Vue中用的比较多的几个API

  • A+
所属分类:Web前端
摘要

在Vue2.x中,当一个Vue实例创建好了以后,如果想要后续给该实例的某一个data添加属性,该属性是不会触发视图更新的,解决方法是使用Vue.set或者vm.$set方法添加指定属性。


1. 数据:Vue.set 和 Vue.delete

在Vue2.x中,当一个Vue实例创建好了以后,如果想要后续给该实例的某一个data添加属性,该属性是不会触发视图更新的,解决方法是使用Vue.set或者vm.$set方法添加指定属性。

例如

<template>   <div>       <p>foo.a is {{foo.a}}</p>       <p>foo.b is {{foo.b}}</p>       <button @click="foo.a = 111">change a to 111</button>       <button @click="foo.b = 111">change b to 111</button>   </div> </template>  <script> export default {   data() {     return {       foo: { a: 123 }     }   },   created() {     //在Vue实例创建成功,但是还未挂载到dom树之前给foo增加b属性。     this.foo.b = 456;   } } </script>  

以上代码在Vue实例创建成功,但是还未挂载到dom树之前给foo增加b属性,此时再页面上可以正常看到foo.a,但是点击修改foo.b页面并不会发生变化。

正确的写法

created() {   this.$set(this.foo, 'b', 456);   //或者   Vue.set(this.foo, 'b', 123);      //对于数组,第二个参数是下表 } 

同样的,想要删除一个属性并触发视图更新,并不能直接使用delete,而要用Vue.delete(target, propertyName/index) 或者vm.$delete(target, propertyName/index)

但是,目前在Vue3中,直接使用this.foo.b = 456也一样可以触发视图更新,也可以直接使用delete删除属性。

2. 事件:vm.$on $emit $once $off

vm.$emitvm.$on是基于发布订阅模式的,常用在子组件向父组件派发事件的时候使用,在子组件上使用@xxx="callback"指令即可,但是除了这种方法,也可以直接在子组件中使用vm.$on也可以触发vm.$emit派发的事件,需要注意的是在哪个组件派发就应该在哪个组件订阅,即事件的派发者既是事件的订阅者。

vm.$emit('test', 'hello'); //派发事件 vm.$on('test', (msg) => {  //订阅事件   console.log(msg); })  

基于这两个api,可以实现一个简单的跨组件通信的方法:事件总线,原理是在Vue的原型上添加一个Vue实例,之后所有组件都可以通过这个Vue实例进行发布消息和订阅消息。

Vue.prototype.$bus = new Vue();  const vm1 = new Vue({...}); const vm2 = new Vue({...});  vm1.$bus.$emit('test', 'hello'); //vm1派发事件 vm2.$bus.$on('test', (msg) => {  //vm2订阅事件   console.log(msg); }) 

vm.$oncevm.$on差不多,区别在于前者在监听到一次事件后就会将该事件移除。

vm.$off用于移除事件监听器

  • 如果没有提供参数,则移除所有监听器。

  • 如果提供了事件的名称,则移除该事件所有的监听器。

  • 如果提供了事件名称与回调引用,则移除这个回调的监听器。

vm.$off(); //移除所有的事件监听器 vm.$off('test'); //移除该事件所有的监听器 vm.$off('test', callback); //只移除这个回调的监听器