Vue组件间的数据通信

props配置项

  • 功能:让组件接受外部传来的数据

    • 传递数据:
      <Demo name="xxx"></Demo>
      
    • 接受数据:
      • 只接受
        props: ["name"],
        
      • 限制类型接受
        props: {
          name: String,
        },
        
      • 限制类型,必要性限制,指定默认值接受
        props: {
          name: {
            type: String,
            required: true,
            default: "胡先森"
          },
        },
        
  • 备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确定需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据

组件的自定义事件

  • 一种组件间通信的方式,适用于:子组件===>父组件

  • 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)

  • 绑定自定义事件

    • 在父组件中

      <Student @myClick="test"></Student>或者<Student v-on:myClick="test"></Student>
      
    • 在父组件中

      <Student ref="student"></Student>
      ...
      
      mounted() {
        this.$refs.student.$on("myClick", this.test);
      }
      
    • 若想让自定义事件只能触发一次,可以使用once修饰符,或者$once方法

  • 触发自定义事件:this.$emit("myClick", params)

  • 解绑自定义事件:this.$off("myClick")

  • 组件上也可以绑定原生DOM事件,需要使用native修饰符,特别是在使用了element-ui组件时,定义的事件一般都是用native修饰。

  • 注意:通过this.$refs.student.$on("myClick", this.test)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

全局事件总线(GlobalEventBus)

  • 一种组件间通信的方式,适用于任意组件间的通信

  • 安装全局事件总线(main.js):

    new Vue({
      ...
      beforeCreate() {
        // 安装全局事件总线,$bus就是当前应用的VM
        Vue.prototype.$bus = this;
      },
      ...
    })
    
  • 使用全局事件总线:

    • 接受数据:A组件想接受数据,则在A组件中给$bus绑定自定义事件,事件的回调函数留在A组件中
      methods: {
        demo(data) {...},
      },
      mounted() {
        this.$bus.$on("xxx", this.demo)
      }
      
    • 提供数据
      this.$bus.$emit("xxx", params)
      
  • 最好在beforeDestroy钩子中用$off去解绑当前组件所用到的事件

消息订阅与发布(pubsub)

  • 一种组件间通信的方式,适用于任意组件间的通信。

  • 使用步骤:

    • 安装pubsub
      npm install --save pubsub-js
      
    • 引入
      import pubsub from "pubsub-js"
      
    • 接受数据:A组件想接受数据,则在A组件中订阅消息,订阅的回调函数留在A组件中
      methods: {
        demo(data) {...},
      },
      mounted() {
        this.pubId = pubsub.subscribe("xxx", this.demo);
      }
      
    • 提供数据
      pubsub.publish("xxx", params);
      
  • 最好在beforeDestroy钩子中用

    pubsub.unsubscribe(this.pubId);
    

    去解绑当前组件所用到的事件

插槽

  • 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于父组件===>子组件
  • 分类:默认插槽、具名插槽、作用域插槽
    -使用方式:
    • 默认插槽:
      • 父组件:
        <Category>
          <div>html结构</div>
        </Category>
        
      • 子组件:
        <template>
          <div>
            <!-- 定义插槽 -->
            <slot>一些描述内容</slot>
          </div>
        </template>
        
    • 具名插槽:
      • 父组件:
        <Category>
          <template slot="center">
            <div>html结构</div>
          </template>
          <template slot="footer">
            <div>html结构</div>
          </template>
        </Category>
        
      • 子组件:
        <template>
          <div>
            <!-- 定义插槽 -->
            <slot name="center">一些描述内容</slot>
            <slot name="footer">一些描述内容</slot>
          </div>
        </template>
        
    • 作用域插槽:
      • 理解:数据在组件自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)

      • 具体实现:

        • 父组件:
          <Category>
            <template scope="dataset">
              <ul>
                <li v-for="(game, index) in dataset.games" :key="index">{{game}}</li>
              </ul>
            </template>
            <template scope="dataset">
              <ol>
                <li v-for="(game, index) in dataset.games" :key="index">{{game}}</li>
              </ol>
            </template>
          </Category>
          
        • 子组件:
          <template>
            <div>
              <!-- 定义插槽 -->
              <slot :games="games">一些描述内容</slot>
            </div>
          </template>
          
          <script>
            export default {
              name: "Category",
              props: ["title"],
              data() {
                return {
                  games: ['红色警戒', '穿越火线', '劲舞团', '超级玛丽'],
                }
              },
            }
          </script>
          

Vuex(可参考博主的Vuex的使用及map方法)

  • 概念:在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间的通信

  • 使用场景:多个组件需要共享数据

  • 搭建Vuex环境

    • 创建文件:src/store/index.js
      // 该文件用于创建Vuex中最为核心的store
      // 引入Vuex
      import Vue from 'vue'
      // 引入Vuex插件
      import Vuex from "vuex"
      Vue.use(Vuex)
      // 准备actions--用于响应组件的动作
      const actions = {}
      // 准备mutations--用于操作数据(state)
      const mutations = {}
      // 准备state--用于存储数据
      const state = {}
      
      const store = new Vuex.Store({
        actions,
        mutations,
        state,
      })
      
      export default store;
      
    • 在main.js中创建vm时传入store配置项
      // 引入创建的store
      import store from "./store"
      
      new Vue({
        el: '#app',
        render: h=>h(App),
        // 使用store
        store,
        ...
      })
      
  • 具体使用

    • 组件使用
      methods: {
        add() {
          this.$store.dispatch("add", params);
        },
        ...
      }
      
    • src/store/index.js配置
      // 准备actions--用于响应组件的动作
      const actions = {
        add(context, value) {
          context.commiit("ADD", value);
        },
        ...
      }
      // 准备mutations--用于操作数据(state)
      const mutations = {
        ADD(state, value) {
          state.sum += value;
        },
        ...
      }
      // 准备state--用于存储数据
      const state = {
        sum: 0,
        ...
      }
      
posted @ 2022-02-24 08:49  xsha_h  阅读(133)  评论(0编辑  收藏  举报