vue中 创建组件时 data只能使用函数式定义,而不能使用对象式定义
对象式:
let data ={
a:1,
b:2
}
const x1 = data;
const x2 = data;
此时 x1和x2 都指向同一个data 控制台输出x1 和 x2 均为 { a:1,b:2 }
x1.a = 99 => x1={ a:99,b:2 }
x2 = { a:99,b:2 }
函数式:
function data() {
return{
a:1,
b:2
}
}
const x1 = data();
const x2 = data();
此时 x1和x2 都不指向同一个data 而是将data() 中的返回值重新复制了两次 控制台输出x1 和 x2 均为 { a:1,b:2 }
x1.a = 99 => x1={ a:99,b:2 }
x2 = { a:1,b:2 }
x1 和 x2 是两个毫不关联的值
computed 和 watch 的区别
- computed 中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调
- computed 默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性设置为true
- 使用场景:computed--当一个属性受多个属性影响的时候,使用computed。watch--当一条数据影响多条数据的时候,使用wacth。
computed 的 get 和 set
get方法是取值,在get中给这个计算属性中的变量赋值
set方法是改变时触发,这里的改变指的是当我们在computed中定义的变量的值发生改变是会触发set方法,这样我们就可以在set方法中进行一些我们想要做的事。数据的全选和取消全选。
nextTick
- 原理
vue是异步执行dom更新的,一旦观察到数据变化,vue就会开启一个队列,然后把在同一事件循环当中观察到数据变化的watcher推送进这个队列,如果这个watcher被触发多次,只会被推送到队列一次,这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和dom操作,这样可以提高渲染效率。
如果要获取更新后的dom元素,可以使用vue内置的$nextTick方法,参数是一个函数。它的作用类似setTimeout,进行执行异步的操作。
<div id = 'app'> {{a}} </div>
...
//a=0
function add(){
this.a = this.a+1
this.a = this.a+1
this.a = this.a+1
this.a = this.a+1
this.a = this.a+1
document.getElementById('#app').innerHTML //这个时候a的值还是0 因为在这个时候数据变化了 但dom还未更新
}
- 应用
vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick可以获取数据更新后最新dom的变化。
- 场景
1)第三方插件,在vue生成的某些dom动态发生变化时重新应用该插件。
2)视图更新之后,基于新的视图进行操作。
vue中 DOM 更新是异步的 并不是数据改变之后立即更新DOM,而是在当前的回调调用完成之后 再通知视图去更新DOM 在上述例子中: this.a = this.a+1 时,数据改变了 但是不会更新DOM (因为如果更新DOM 的话,在第一个this.a = this.a+1执行完成之后 就更新一次DOM,第二次this.a = this.a+1执行完成之后还会更新一次DOM 直到最后一次this.a = this.a+1执行完成,这个期间会更新N次DOM 会造成更大的渲染成本,所以在vue中 让所有的代码执行完成之后再去更新DOM只会更新一次)当最后一次this.a =this.a+1执行完成 此时a的值为5,但是DOM上的a的值仍为0,由于要将当前回调执行完 所以此时已经调用document.getElementById('#app').innerHTML 值为0,想要获取到最新DOM的值 需要加上以下代码
<div id = 'app'> {{a}} </div>
...
//a=0
function add(){
this.a = this.a+1
this.a = this.a+1
this.a = this.a+1
this.a = this.a+1
this.a = this.a+1
//1、js方法
setTimeout(()=>{
document.getElementById('#app').innerHTML//此时利用setTimeout 将document.getElementById('#app').innerHTML放到任务队列中 也就相当于异步调用
})
//2.vue中 nextTick
this.$nextTick(()=>{
document.getElementById('#app').innerHTML //利用nextTick 将document.getElementById('#app').innerHTML放入下一次轮询中调用 相当于setTimeout
})
}