Vue监视数据的原理
- vue会监视data中所有层次的数据
- 如何监测对象中的数据
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1)对象中后追加的数据,Vue默认不做响应式处理。
(2)如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value)或
vm.$set(target,propertyName/index,value) - 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事
(1)调用原生对应的方法对数据进行更新
(2)重新解析模板,进而更新页面 - 在Vue修改数组中的某个元素一定要使用如下方法:
(1).使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
(2).Vue.set()或vm.$set()
//data中的数据
student: {
name: 'tom',
age: 20,
hobby: ['抽烟', '喝酒', '烫头'],
friends: [
{ name: 'jerry', age: 25 },
{ name: 'tony', age: 36 }
]
}
//methods
//往对象身上添加属性的的两种写法
addSex() {
Vue.set(this.student, 'sex', '男')
this.$set(this.student, 'sex', '男')
},
//修改数组身上某个属性的几种操作
//unshift():方法将新项添加到数组的开头
addFriend() {
this.student.friends.unshift({ name: 'jack', age: 30 })
},
//修改name中的值,不会重新解析模板更新页面。
updatefirstFriendName() {
this.student.friends[0].name = '张三'
},
//push():方法将新项添加到数组的尾部
addHobby() {
this.student.hobby.push("学习")
},
//filter():创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。不会改变原始数组。
filterHobby() {
this.student.hobby = this.student.hobby.filter((h) => {
return h !== '抽烟'
})
}
特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性!!!
内置指令
- v-bind:单向绑定解析表达式,可简写为:xxx
- v-model:双向数据绑定
- v-for:遍历数组/对象/字符串
- v-on:绑定事件监听,可简写为@
- v-if:条件渲染(动态控制节点是否存在)
- v-else:条件渲染(动态控制节点是否存在)
- v-show:条件渲染()动态控制节点是否展示
- v-text指令:用于操作纯文本,它会替代显示对应的数据对象上的值。当绑定的数据对象上的值发生改变,插值处的内容也会随之更新。注意:此处为单向绑定,数据对象上的值改变,插值会发生变化;但是当插值发生变化并不会影响数据对象的值。
- v-cloak指令:
1.本质是一个特殊的属性,vue实例创建完毕并接管容器之后,会删掉v-cloak属性
2.使用css配合v-cloak可以解决网速慢时页面展现出{{xxx}}的问题 - v-once指令:
1.v-once所在节点在初次动态渲染后,就视为静态内容了
2.以后数据的改变不会引起v-once所在结构的更新,,可以用于优化性能 - v-pre指令
1.跳过其所在节点的编译过程
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
<div v-cloak>{{str}}</div>
<div v-cloak>{{str}}</div>
<h2 v-pre>当前的n值是:{{n}}</h2>
//属性绑定,可简写为:value="bind"
<input type="text" v-bind:value="bind"><br>
//双向绑定,可简写为v-model="model"
<input type="text" v-model:value="model"><br>
<p>{{model}}</p>
// 事件绑定,可简写为@click="von"
<button v-on:click="von">我被点了{{on}}次</button>
v-bind、v-model、v-on的区别:
v-bind: 属性绑定(简写:), v-on:事件绑定(简写@), v-model:双向绑定(简写v-model)
自定义指令
自定义指令总结:
定义语法:
(1)局部指令:
new Vue({directives:{指令明:配置对象}}) 或 new Vue({directives{指令名:回调函数}})
(2)全局指令
Vue.directive(指令名,配置对象) 或Vue.directive(指令名,回调函数)
配置对象中常用的3个回调
(1)bind:指令与元素成功绑定时调用
(2)inserted:指令所在元素被插入页面时调用
(3)update:指令所在模板结构被重新解析时调用
// 全局fbind指令的写法
Vue.directive('fbind', {
// 指令与元素成功绑定时(一上来)
bind(element, binding) {
console.log('big', this)//注意此处的this是window
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element, binding) {
console.log('inserted')
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
console.log('update')
}
})
//局部写法,要写在new Vue中
directives: {
// big函数如何被调用:
// 1,指令与元素成功绑定时(一上来)。
// 2.指令所在的模板被重新解析时。
// 注意如果是有多个单词组成的话,需要写成原始写法,即将其加引号引起来,作为一个对象
"big-number"(element, binding) {
element.innerText = binding.value * 10
},
fbind(element, binding) {
element.value = binding.value
}
// 完整写法,这些都是局部指令
//fbind: {
// // 指令与元素成功绑定时(一上来)
// bind(element, binding) {
// console.log('big', this)//注意此处的this是window
// element.value = binding.value
// },
// // 指令所在元素被插入页面时
// inserted(element, binding) {
// console.log('inserted')
// element.focus()
// },
// // 指令所在的模板被重新解析时
// update(element, binding) {
// element.value = binding.value
// console.log('update')
// }
// }
//在vue模板中的写法
<!-- 定义一个v-fbind指令 -->
<input type="text" v-fbind:value="n">
}
备注:
1.指令定义时不加v-,但使用时要加v-
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用kebabcase命名
生命周期函数
生命周期:
- 又名:生命周期回调函数、生命周期函数、生命周期钩子。
- 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数
- 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
常用的生命周期钩子:
- mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息。
- beforeDestory:清除定时器,解绑自定义事件,取消订阅消息。
关于销毁vue实例:
- 销毁后借助Vue开发者工具看不到任何信息。
- 销毁后自定义事件会失效,但原生DOM事件依然有效。
- 一般不会在beforeDestory操作数据,因为即便操作数据,也不会再触发更新流程了
// Vue完成模板的解析并把初始的真实DOM元素放入页面后,调用mounted
mounted() {
//这个是一个定时器
setInterval(() => {
vm.opacity -= 0.01
if (this.opacity <= 0) this.opacity = 1
}, 16)
},