5、条件渲染指令
(1)v-show
根据表达式的真假值,切换元素的 display 的 CSS
属性。即控制显示隐藏
例子:
<template> <!-- 绑定v-show指令,控制div的显示隐藏--> <div v-show="show">v-show指令</div> </template> <script> export default { data() { return { show: true //tue显示;false隐藏 }; } }; </script>
(2)v-if
v-if根据表达式的值的是否为真,来有条件地渲染元素。本质是通过操作dom
元素来切换显示状态。
v-for优先级比v-if高,不建议两者一起使用。
例子:
<template> <!-- 绑定v-if指令,控制div的显示隐藏--> <div v-if="show">v-if指令</div> </template> <script> export default { data() { return { show: true //tue显示;false隐藏 }; } }; </script>
(3)v-show与v-if的区别
v-if
是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销
毁和重建。v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做—直到条件第一次变为真时,才会
开始渲染条件块。- 相比之下,
v-show
就简单得多—不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS
进行切换。 - 一般来说,
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频
繁地切换,则使用v-show
较好;如果在运行时条件很少改变,或控制的是一个组件,需要重新编译,则使用v-if
较好。
(4)v-else-if
为 v-if 或者 v-else-if 添加“else 块”。
v-else和v-else-if的前一兄弟元素必须有 v-if 或 v-else-if
<div v-if="type === 'a'"> a </div> <div v-else-if="type === 'b'"> b </div> <div v-else-if="type === 'c'"> c </div> <div v-else> not a/b/c </div>
6.列表渲染指令v-for
v-for
基于源数据多次渲染元素或模板块,v-for
指令中可以使用数组、对象。
数组语法: (item, index) in items
其中items
为源数据数组,item
为数组元素别名,index
为索引具有唯一性
例子:
<div> <!-- 遍历对象 --> <div v-for="(val, key, index) in object" :key="index">{{ val }}{{ key }}{{ index }}</div> </div> </template> <script> export default { data() { return { object: { name: '张三', age: '20' } }; } }; </script>
遍历对象渲染结果为:
张三name0 20age1
key 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需
要为每项提供一个唯一 key ,这个key 值必需要有且具有唯一性,通常建议使用id来作为key值,
不建议使用索引。
四、计算属性(computed)
计算属性可用于快速计算视图中显示的属性。这些计算将被缓存,并且只在需要时更新。所以,对于任 何复杂计算,都可以使用计算属性。
- 定义在computed节点中,定义的时按照方法来定义,使用的时当做一个属性来使用。
- 可以提高代码复用性。
- 它计算的数据会被缓存,只有它所依赖的数据发生了变化才会重新计算,提升性能。
例计算数量的总数:
<template> <div> <!-- 使用计算属性:当做一个属性来使用 --> <div>总数值:{{ count }}</div> </div> </template> <script> export default { data() { return { list: [ { name: '数量01', count: 10 }, { name: '数量02', count: 20 }, { name: '数量03', count: 30 } ] }; }, //在computed节点中定义方法count computed: { // 计算数量的总数 count() { let countNum = 0; this.list.forEach(item => { countNum += item.count; }); return countNum; } }, mounted() { console.log(this.count); } }; </script>
五、监听器(watch)
watch用于监听data里面的数据是否被修改,一旦修改就可以执行一些其他的操作。
- 监听data中的某个对象时,如果要实现对象中属性的改变能被监听到,需要使用 deep:true 属 性。
- 也可以直接监听data中对象的子属性的变化,则不需要加 deep:true ,可以使用’对象.属性’的方 式,注意一定要包裹一层引号,推荐使用单引号包裹。
- 如果需要首次进入页面就监听到数据,而不是等到数据改变才监听到,则需要添加
immediate:true
属性。
<template> <div> <!-- 输入框num值改变,执行watch监听。改变numDouble变量--> <el-input v-model="num" placeholder="请输入内容"></el-input> <h2>监听num并*2:{{ numDouble }}</h2> </div> </template> <script> export default { data() { return { num: 0, numDouble: 0, obj: { a: 1, b: 2 } }; }, watch: { //监听num,函数第一个参数是变化后的新值,第二个参数是旧值 num: function(newVal, oldVal) { this.numDouble = newVal*2; }, //对象 obj: { handler: function(newVal, oldVal) { //... }, deep: true //深度监听 }, //对象属性,使用单引号包裹 'obj.a': { handler: function(newVal, oldVal) { //... }, immediate: true//控制侦听器是否自动触发,即首次进入页面就监听 } }, methods: {} }; </script>
六、过滤器(filter)
- 过滤器是
vue
中的一个特性,用于对文本进行格式化。在不改变原数据的前提下,对数据进行一定 程度的处理。 - 过滤器分为全局过滤器和局部过滤器,可以用在两个地方:{{ }}插值语法或 v-bind指令,用管道符 | 隔开。
<!-- 在{{ }}插值语法中, 格式:{{值 | 过滤器的名称}} --> {{ message | capitalize }} <!-- 在v-bind中, 格式:v-bind:id="值 | 过滤器的名称" --> <div v-bind:id="rawId | formatId"></div> <!-- 过滤器可以串联,管道符 | 隔开。 将filterA 的结果传递到 filterB 中--> {{ message | filterA | filterB }} <!-- 过滤器是 JavaScript 函数,因此可以接收参数 格式:{{ 值 | filter1(参数) | fliter2(参数) }}--> {{ message | filterA('arg1', arg2) }}
在开发中,需要用到过滤器的地方有很多,比如单位转换、数字打点、文本格式化、时间格式化之类的 等
例转换时间戳、个位补零:
<template> <div> <!-- 局部过滤器 --> <!-- 要过滤的数据,永远是第一个参数;通过filter函数,传递的参数,依次排在后面 --> <div>日期转换:{{ startDate | dateFilter }}</div> <div>日期转换:{{ startDate | dateFilter('YYYY-MM-DD') }}</div> <!-- 全局过滤器 --> <p>个位补零</p> <p v-for="(num, index) in dateList" :key="index">{{ num | fillZero }}</p> </div> </template> <script> import moment from 'moment'; export default { data() { return { startDate: new Date(), dateList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] }; }, filters: { //处理日期格式 dateFilter: function(time, pattern) { if (!pattern) { pattern = 'YYYY-MM-DD HH:mm:ss';//默认格式 } return moment(time).format(pattern); } } }; </script>
全局过滤器经常用在数据修饰上,通常我们把处理函数给抽离出去,统一放在一个 .js 文件中。
- 新建
filter.js
文件
//个位补零 function fillZero(num) { return num < 10 ? `0${num}` : num; } //导出过滤器方法 export default {fillZero};
- 在
main.js
中 引入注册filter.js
文件
//引入过滤器 import filters from './utils/filter.js' //注册过滤器,导入的是一个对象,所以使用Object.keys()方法,得到一个由key组成的数组,遍历数据 让key作为全局过滤器的名字 Object.keys(filters).forEach(key => { Vue.filter(key, filters[key]); });
七、组件
Vue
在实际开发过程中会存在重复使用的 UI 结构,我们可以将类似的 UI 结构提取出来封装成组件。
1、组件的使用
新建一个 vue 文件做为子组件。
1)import 导入
<script> import ChildPage from './child-page'; </script>
2)components中注册
<script> import ChildPage from './child-page'; export default { components: { ChildPage } } </script>
3)template中以标签形式使用
<template> <div> <!-- 把组件名转换为中划线分割的方式使用,与前端开发规范保持一致 --> <child-page></child-page> </div> </template> <script> import ChildPage from './child-page'; export default { components: { ChildPage } </script>
2 . 组件通信
1)父组件传值给子组件
1.通过 props传递
props
可以是数组或对象,用于接收来自父组件的数据。对象允许配置高级选项,如类型检测、自定义 验证和设置默认值。
实际工作开发中,我们都要求统一使用对象的形式。在传递的数值类型不正确时, vue 会报错方便我们 定位错误。 以对象形式接收参数的配置选项:
例父组件传递年龄age变量到子组件,其中age为子组件接收的名称:
<template> <div> <!-- 我是父组件 --> <child-page :age="10"></child-page> </div> </template> <script> import ChildPage from './child-page'; export default { components: { ChildPage } } </script>
子组件通过props接收age并渲染:
<template> <div> <!-- 我是子组件 --> <div>{{ age }}</div> </div> </template> <script> export default { props: { // 检测类型 + 验证 age: { type: [String, Number],//支持多种type类型 default: 0,//默认值和类型保持一致 required: true,//必填项 validator: function(value) {//自定义验证函数 return value >= 0; } }, propA: { type: Number,//单个type类型 default: 0 }, propB: { type: String, default: '' }, propC: { type: Array, default() { return []; } }, propD: { type: Object, default() { return {}; } }, propE: { type: Boolean, default: false } } }; </script>
传递静态Prop,可以像这样给 prop
传入一个静态的值:
<blog-post title="My journey with Vue"></blog-post>