一、数组的变异(数组更新)
Vue.js 内部对被观察数组的变异方法 (mutating methods,包括 push() , pop() , shift() , unshift() , splic
e() , sort() 和 reverse() ) 进行了拦截,因此调用这些方法也将自动触发视图更新。
// 以下操作会触发 DOM 更新
demo.items.unshift({ childMsg: 'Baz' })
demo.items.pop()
// vue 2.6 // src/core/observer/array.js const arrayProto = Array.prototype; // 获取数组原型对象 const arrayMethods = Object.create(arrayProto); // 生成一个新对象,且__proto__ 指向 数组原型对象 const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']; /** * Intercept mutating methods and emit events */ methods.forEach(method => { const original = arrayProto[method]; let val = function mutator (...args) { const result = original.apply(this, args); //缓存原始方法 let inserted = null; switch (method) { case 'push': inserted = args; break; case 'unshift': inserted = args; break; case 'splice': inserted = args.slice(2); // array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) [item]) break; } if (inserted) observeArray(inserted); // 获取插入的值,并设置响应式监听 notify(); // 通知依赖像更新 return result; } Object.defineProperty(arrayMethods, method, { value: val, writable: true, configurable: true, enumerable: true }) }) const observeArray = function observeArray (inserted) { // 简写,[具体实现](https://github.com/vuejs/vue/blob/2.6/src/core/observer/index.js) console.log(inserted); //新增的元素形成的数组 console.log('响应式监听数组'); } const notify = function notify () { console.log('视图更新了'); }
在Vue现有阶段中,对响应式处理利用的是Object.defineProperty对数据进行拦截,而这个方法并不能监听到数组内部变化,数组长度变化,数组的截取变化等,所以我们需要对这些操作进行hack,让vue能监听到其中的变化。
因此,在改变数组的值时不可直接用索引。这些改动是无法被 Vue.js 侦测到的。你应该使用扩展的 $set() 方法
// 不要用 `demo.items[0] = ...`
demo.items.$set(0, { childMsg: 'Changed!'})
$remove() 只是 splice() 方法的语法糖。它将移除给定索引处的元素。当参数不是数值时, $remove() 将在数组中搜索该值并删除第一个发现的对应元素 :
// 删除索引为 0 的元素。
demo.items.$remove(0)
二、自定义指令:
具体这个用的不多,感兴趣的可以了解下别人写的文章。。。
https://www.cnblogs.com/LO-ME/p/7767797.html
http://gitblogs.com/blogs/details?id=53f012d0-02d0-4a98-a64e-2c7f881b8b0a
三、关于对下面这句话的理解(ref/this.$refs)
当 ref
和 v-for
一起使用的时候,你得到的引用将会是一个包含了对应数据源的这些子组件的数组
参考这位大佬的:https://www.jianshu.com/p/6c8c39a7bf14
四、关于v-model
v-model 是语法糖,一般用在表单中数据的双向绑定,也可以用在自定义组件中,比如我们自定义一个select/option 组件。。
参考这位老哥写的文章:https://www.jianshu.com/p/296421704b25 https://www.jianshu.com/p/b3649529bff0
五、为什么要在data中初始化数据:
因为 Vue 是通过递归遍历初始数据中的所有属性,并用 Object.defineProperty 把它们转
化为 getter 和 setter 来实现数据观察的。如果一个属性在实例创建时不存在于初始数据中,那么 Vue 就没有
办法观察这个属性了。
六、关于nextTick ,DOM异步更新机制、宏任务微任务 任务队列、事件循环机制、MutationObserver
HTML5 新增属性。。。
参考:https://www.leevii.com/2019/07/vue-nexttick-implementation.html
https://segmentfault.com/a/1190000012861862?utm_source=tag-newest
https://www.cnblogs.com/fozero/p/10863667.html
https://www.jianshu.com/p/5d84815c2555
七、计算属性和watch的区别
计算属性其实和method一样,只不过计算属性是基于缓存机制的 必须有返回值,目的是计算一些复杂的表达式运算。。。watch是侦听器,监听data里的属性值的变化。。。
computed
是计算一个新的属性,并将该属性挂载到 vm(Vue 实例)上,而watch
是监听已经存在且已挂载到vm
上的数据,所以用watch
同样可以监听computed
计算属性的变化(其它还有data
、props
)computed
本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问computed
属性,才会计算新的值,而watch
则是当数据发生变化便会调用执行函数- 从使用场景上说,
computed
适用一个数据被多个数据影响,而watch
适用一个数据影响多个数据;
参考:https://juejin.im/entry/5b07824651882538a34c1694