九种简洁的Vue数据通讯

在编写一个vue项目的时候,组件之间的数据通信是必不可少的。也是非常的重要的一步。今天写几种vue中组件的数据通信方式以及应用场景。

props&@

  1. props

    父组件把数据通过v-bind这个指令绑定在子组件参数上传下去.子组件在props这个属性获取.
    props可以以数组和对象的形式接收.如下

    • 数组形式

      // 父组件
      <Children v-bind:msg="msg"></Children>
      // 在子组件上定义
      props: ["msg"] //字符串对应的是父组件绑定的v-bind值.
      
    • 对象形式

      // 父组件
      <Children v-bind:msg="msg"></Children>
      // 在子组件上定义 -- 对象可以设置其他条件
      props: {
          msg: {
              type: String, //判断传入的类型
              default: "默认数据", //默认值
              require: true, // 是否必须传入项
          },
      },
      

    子组件只能使用不能直接修改props的属性.直接修改的话修改成功并且vue会抛出警告,所以不推荐你这么做.

  2. @

    父组件传入一个方法给子组件.子组件可以调用这个方法修改父组件的值(解决了子组件不能修改父组件的值)。

    // 在父组件把定义好的fn传下去,供子组件调用.
    <Children @fn="fn"></Children>
    
    //子组件通过$emit调用fn.
    this.$emit("fn", 1, 2, 3);
    

ref

在父组件注册的子组件中添加ref属性.父组件能通过this.$refs.属性名拿到这个子组件的实例.就可以直接做操作啦.

//父组件
<Children ref="subInst" /> 

this.$refs.subInst // 父组件可以通过这个方法直接拿到子组件的data和methods.

provide&inject

在父组件提供数据(provide),子组件注入数据(inject).
provide 选项应该是:一个对象或返回一个对象的函数
inject 选项应该是:一个字符串数组,或 一个对象,对象的 key 是本地的绑定名

//父组件上添加这个方法
provide() {
    return {
		msg: this.msg, // 这里需要注意传基本的值,没有响应式.需要传一个响应式的对象.
    };
},

// 子(孙)组件
inject: ["msg"],

官方着重说明provide 和 inject 主要为高阶插件/组件库提供用例,并不推荐直接用于应用程序代码中。

KaTeX parse error: Expected 'EOF', got '&' at position 6: attrs&̲listeners

这两个属性是一个对象.分别保存父组件中传下来的数据和方法.

  • $attrs

    //父组件
    <Children :msg="msg"></Children> 
    
    //子组件
    //传下来的数据保存在$attrs这个属性中
    <template>
      <div class="hello">
        我是attrs子组件 --- {{ $attrs.msg }} //$attrs上的值是只读的,并不会响应式的。强制$set设置vue会抛出警告.这是一个只读属性.
      </div>
    </template> 
    
  • $listeners

    //父组件
    <Children :fn="fn"></Children> 
    
    //子组件
    //传下来的方法保存在$listeners这个属性中,可直接调用.
    <template>
      <div class="hello">
        我是attrs子组件 --- {{ $attrs.msg }}
      </div>
    </template> 
    

sync&model

这是vue组件中自带的语法糖。方便调用。

  1. sync

    //父组件
    <Children :msg.sync="msg"></Children> // 在父组件注册的子组件挂载修饰符.sync
    
    // 子组件
    this.$emit("update:msg", "789"); //子组件上直接调用这个方法,传值改值.
    

    .sync修饰符相当于vue在内部定义方法可以修改值,相当于父组件上使用@把函数传下来这种.
    在子组件打印实例,会发现在listen上出现update:msg方法。

  2. model

    //父组件
    <Children v-model="msg"></Children> // 在父组件注册的子组件v-model
    
    //子组件上使用需要props接收value和调用事件event的this.$emit("input", value);
    //这里默认使用input的v-model
    <input type="text" v-model="value" /> //子组件直接修改前提的接收props的value.
    

    v-model用于表单数据的双向绑定,这个背后就做了两个操作:

    1. v-bind绑定一个value属性
     2. v-on指令给当前元素绑定input事件

    在子组件可以通过model修改默认的value和event.例

    model: {
        prop: "check",
        event: "change",
    },
    

    注意咋组件上调用v-model还是需要你去绑定值和修改 值得操作.

eventBus

通过创建一个新的vue实例,当做事件车然后挂在vue的原型上。通过发布订阅的方式就行通讯。这个方法可任意组件之间使用,前面的但是父组件传下来的。

//任意组件创建订阅callback这个方法,
this.$eventBus.$on("callback", (data) => {
console.log("接收到data----", data);
});

//任意组件上传入数据通讯,(发布)
this.$eventBus.$emit("callback", "传入数据");

使用这个方法可以在任意两个组件上进行通讯。方便至极。缺点是项目复杂的是时候难以维护,追踪。

parent&children

通过挂载在Vue的原型上,递归执行$emit方法.在需要通讯的组件上订阅发布.

  • parent

    Vue.prototype.$dispatch = function (eventName, params) {
      var parent = this.$parent;
      while (parent) {
        parent.$emit(eventName, params);
        parent = parent.$parent;
      }
    } //在原型上定义个方法,内部就是一直往上级执行$emit这个方法.
    
    // 在需要使用组件数据的父组件中,订阅.
    this.$on("Up", function (params) {
    	this.msg = params;
    });
    
    // 调用方法的子组件或孙组件.
    this.$dispatch("Up", "我是通过parent方式改变的数据");
    
  • children

    // 通知子组件的监听事件
    Vue.prototype.$notice = function (eventName, params) {
      var children = this.$children;
      function deep(children) {
        children.forEach(item => {
          item.$emit(eventName, params);
          if (item.children) {
            deep(children);
          }
        });
      }
      deep(children);
    } //在原型上定义个方法,内部就是递归调用下级的$emit这个方法.
    
    // 在需要使用组件数据的子组件中,订阅.
    this.$on("down", function (params) {
    	this.msg = params;
    });
    
    // 调用方法的组件
    this.$notice("down", "我是通过children方式改变的数据");
    

这两种写法一般在封装组件中用的比较多.好处就是能一直往上级查找或者往下查找.缺点就是污染Vue原型.

solt

这种写法是在父组件中使用子组件的数据.也称之为作用域插槽.
(solt的其它用法就不说了需要的去官网直接瞄一瞄).

// 父组件
<children>
  <template v-slot:header="scope">
    <h1>{{scope.header}}</h1> //这里展示的就是123.
  </template>
</children>

//子组件
<slot name="header" :header="123"></slot>

比如element的表格可编辑内容就是这个作用域插槽实现的.有兴趣的可以去看看源码.

vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

vuex可以说是这几种中数据管理最好的了. 最主要的是响应式(基于vue),组件之间数据共享.

这里就略过一下api吧.毕竟这个东西用vue的基本使用到这个东西.大家都很熟.

  • state

    存储数据的属性, 不可直接修改state的属性值.(不方便追踪)

  • mutations

    同步修改state的方法,通过commit触发

    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
        increment (state,a) { //后面是传进来的参数.
          // 变更状态
          state.count++
        }
      }
    })
    
    // 触发
    store.commit("increment",2)
    
  • actions

    • Action 提交的是 mutation,而不是直接变更状态。

    • Action 可以包含任意异步操作。

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })
    
    //触发
    store.dispatch("increment"); // 这里需要异步操作返回promise.
    
  • getters

    相当于vue中计算属性computed.

    const store = new Vuex.Store({
      state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
      },
      getters: {
        doneTodos: state => {
          return state.todos.filter(todo => todo.done)
        }
      }
    })
    
    //访问
    store.getters.doneTodos
    
  • modules(略)

  • 辅助函数

    • mapState
    • mapActions
    • mapMutations
    • mapGetters

    返回的是函数,参数是在vuex定义对应的属性名的数组. 返回一个对象.

总结

以上就是自己对vue数据通讯的总结. 如果觉得文章对你有用,欢迎给个“赞”,也欢迎技术讨论,感谢大家 !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值