vue组件之间的数据传递方法

1.props属性:

在父组件中,能够经过子组件标签属性的形式将数据或者函数传给子组件,子组件经过props去读取父组件传过来的数据vue

  • 用法vuex

    • 父组件传数据给子组件:bash

      • 通常的属性值都是用来给子组件展现的app

    • 子组件传数据给父组件异步

      • 属性值为函数类型的,通常是用来子组件向父组件传递数据,子组件经过调用父组件传过来的函数,能够修改父组件的状态数据函数

  • 缺点:工具

    • 隔层组件间传递: 必须逐层传递(麻烦)优化

    • 兄弟组件间: 必须借助父组件(麻烦)ui

  • 注意:this

//子组件获取父组件传过来的值
props: {
    obj: {//obj为{id:'2'}
       type: Object
     }
}复制代码

引用类型的props,咱们能够在子组件中直接修改引用类型属性的值(如:this.obj.id='3',会生效),可是不能直接改变引用类型存储的地址值(如:this.obj = {id: '3'}),会发出警告。

虽然子组件能够直接修改父组件的状态值,但咱们不建议这样作,咱们但愿全部的 prop 都使得其父子 prop 之间造成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,可是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而致使你的应用的数据流向难以理解。

脏数据问题:如v-model是实现了双向绑定,经过v-model更改数据,会更改父组件的数据,致使脏数据

解决方法:

利用计算属性的set和get,在set中需实现子组件调用父组件的方法,确保数据流向是单向的

computed:{
    msg: {
        get(){
            return this.data
        },
        set(){
            this.$emit('EventName', this.data)
        }    
}}复制代码

2.vue自定义事件:

  • 方式1: 给子组件标签绑定事件监听

    • 子组件向父组件的通讯方式

      • 功能相似于function props

      • 经过在父组件中给子组件标签绑定自定义事件的监听,再由子组件触发事件,实现子组件向父组件传递数据的方法,事件名必须一致,且不能有大写字母,v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (由于 HTML 是大小写不敏感的)

        // 方式一: 经过v-on绑定
        <component @delete_todo="deleteTodo"/>
        // 方式二: 经过$on()绑定
        this.$refs.xxx.$on('delete_todo', function (todo) {
        this.deleteTodo(todo)})​
        经过this.$emit('delete_todo', todo)触发事件复制代码
    • 不适合隔层组件和兄弟组件间的通讯

    • 注意:

      • 在组件标签上绑定事件,会被解析为vue自定义事件

      • 在普通的标签上绑定事件,会被解析为DOM事件

        <--!     
        表示在组件component绑定了一个名为click的vue自定义事件,
        至关于作了vm.$on('click',fn)    
        注意:不是常规理解的点击事件,这里与点击无关,只是名字恰好是click,
        固然实际操做中不建议取这类特殊的名字 
        -->
        <component @click="fn"/>
        <--! 表示在div上绑定一个click的点击事件,是DOM事件 -->​
        ​<div @click="fn"/>复制代码

  • 方式2: 经过单独的vm对象绑定监听/分发事件

    • 任意组件间通讯(相似于pubsub)

      • 建立一个公用的vm对象

      import Vue from 'vue'export default new Vue()复制代码
      • 在接收消息的组件,绑定监听

      import vm from './vm.js'mounted(){
          vm.$on('delete_todo', function (todo) {
              this.deleteTodo(todo)
          })}复制代码
      • 在发送消息的组件,触发事件

      vm.$emit('delete_todo', todo)复制代码
    • 事件总线(EventBus),其实跟上面的用法同样,这里是把vm实例绑在了Vue的显示原型上

      //点击任意一个组件,其余组件的值跟着变化,利用总线去实现兄弟之间的通讯
      Vue.prototype.bus = new Vue()
      var vm = new Vue({
          el:"#app"
          })    
      //v-a组件
      Vue.component('v-a', {
          template:'<div @click="handle">{{msg}}</div>',
          data(){
              return {
                  msg: 'v-a'
              }
          },
          mounted () {
              //绑定事件监听
              this.bus.$on('bus',(msg)=>{
                  this.msg = msg
              })
          },
          methods: {
              handle () {
                  //触发事件
                  this.bus.$emit('bus', this.msg)
              }
          }})
      //v-b组件
      Vue.component('v-b', {
          template:'<div @click="handle">{{msg}}</div>',
          data(){
              return {
                  msg: 'v-b' 
             }
          },
          mounted () {
              //绑定事件监听
              this.bus.$on('bus',(msg)=>{
                  this.msg = msg
              })
          }, 
         methods: {
              handle () {
                  //触发事件 
                 this.bus.$emit('bus', this.msg)
              }
          }})复制代码

3.消息的订阅和发布(pubsub)

  • 适用于任何关系的组件间的通讯

  • 缺点:相对于vuex,管理不够集中

  • 用法:

    • 引入pubsub-js库

    • 在接收消息的组件订阅消息(subscribe)

      PubSub.subscribe('name',(name,data)=>{})复制代码
    • 在发送消息的组件发布消息 ( publish)

      PubSub.publish('name',data)复制代码
  • 其余用法能够参考官方API文档,这里不细说

4.vuex

vuex是专门为vue.js应用程序定义的状态管理模式,当多个组件须要共享数据时,咱们通常用vuex去管理状态数据,实现多个组件间的相互通讯


vuex的核心

  • state:存放数据

  • mutations:修改数据

  • actions:提交mutation,修改数据

  • getters:存放数据,相似于vue的计算属性

知道了这几个核心概念后,咱们还须要知道怎么合理使用他们

  • 如何从仓库store读取数据

    • state

      从store的实例中咱们能够经过store.state去得到状态数据,为了使得store能够全局使用,咱们须要经过Vue.use(Vuex),将vuex注给全部vue子的组件,Vue.use回去调用插件的install方法,将stroe绑到Vue.prototype,这样Vue的实例对象都能经过vm.store获取或操做仓库的数据组件内经过this.$store.state能够得到

      state:{    
       data: 0
      }复制代码

    • getters

      有些状态熟悉须要根据其余状态属性计算而动态得到,通常都是存在getters中,组件经过调用this.$store.getters

      Getter 接受 state 做为其第一个参数

      getters:{
          data2(state){
              return state.data+1
          }
      }复制代码

  • 如何修改仓库store的数据

    • mutations(同步修改)

      更改 Vuex 的 store 中的状态的惟一方法是提交 mutation,接受 state 做为第一个参数 ,mutation接收提交载荷,第二个参数为载荷,在大多数状况下,载荷应该是一个对象 ,这样能够接收多个数据

      mutations:{
          mutationType:(state,data)=>{
              state.data = data
          }
      }复制代码
    • actions(异步修改)

      在action中提交mutation,组件经过store.dispatch触发action

      由于vue的调试工具没法检测到mutations的异步变化,因此咱们若是须要异步修改状态数据,通常是放在action去异步获取到数据后再提交mutation,确保vue的调试工具能够检测到,mutation的变化

  • 注意点

    当组件须要给vue中的状态数据添加属性时,经过obj.的形式没法实现

    由于Vuex 的 store 中的状态是响应式的,那么当咱们变动状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也须要与使用 Vue 同样遵照一些注意事项:

    1. 咱们最好提早在 store 中初始化好全部所需属性。

    2. 当须要在对象上添加新属性时,咱们应该

    • 使用 Vue.set(obj, 'newProp', 123), 或者

    • 以新对象替换老对象。例如,利用 stage-3 的对象展开运算符,咱们能够这样写:

    state.obj = { ...state.obj, newProp: 123 }复制代码
  • 优化

    • import {mapState,mapGetters,mapMutations,mapActions} from "vuex";使得在使用vuex时,组件能够写的更加的简洁

    • 数据比较多的时候,使用module

    • 使用常量存放mutation_type

优势:

  • 多组件共享状态(数据的管理)

  • 组件间的关系也没有限制

  • 功能比pubsub强大, 更适用于vue项目

5.slot插槽

  • 父向子通讯

  • 通讯是带数据的标签

  • 注意: 标签是在父组件中解析

相关文章
相关标签/搜索