vue中的组件通信

组件是vue.js中最重要的一个功能,在vue中组件的实例都是相互独立的,但开发过程中组件雨组件之间的数据相互引用是必不可少,下面来阐述vue的几种通信方式

1:父组件->子组件:通过props接受父传递数据

步骤1:子通过props键来接受父传递过来的数据 props:[‘变量名1’,…,‘变量名n’]
步骤2:父传递给子 父必须在调用子的组件上通过语法 v-bind:子props中的变量名=“父data中的键”

// 声明fathertag组件
Vue.component("fathertag", {
    // 声明模型数据
    data() {
        return {
            // 调用的时候注意大小写
            sonName: "赵冠希"  
        }
    },
    // 声明组件内容
    template: `
        <fieldset>
            <legend>父组件</legend>

            <div>
                <p>我是父组件,我儿子叫:{{sonName}}</p> 
                
                <!-- 调用子组件 -->
                <sontag v-bind:myName="sonName"></sontag>
            </div>

        </fieldset>
    `,
    // 声明子组件
    components: {
        // 键就是组件标识
        sontag: {
            // 通过props键来获取父传递的数据
            props: ['myName'],
            // 这里的下props相当于下面data 
            // data() {
            //     return {
            //         // myName: 数据
            //         myName: 6666,
            //     }
            // },
            // 声明子组件内容
            template: `
                <fieldset>
                    <legend>子组件</legend>
                    <p>我是子组件,我爸爸给我取名:{{myName}}</p>
                </fieldset>
            `
        }
    }
})

2:子组件->父组件:通过$emit创建自定义事件发送数据

步骤1:子创建自定义事件 通过语法this.$emit(事件名称, 数据1, …, 数据n)
步骤2:父调用自定义事件 父在调用子组件上通过 @自定义事件名称=“函数名” 你在父定义函数接受数据即可

// 声明fathertag组件
Vue.component("fathertag", {
    // 声明模型数据
    data() {
        return {
            // 调用的时候注意大小写
            sonName: "赵冠希",
            mySonData: ""
        }
    },
    // 声明组件内容
    template: `
        <fieldset>
            <legend>父组件</legend>

            <div>
                <p>我是父组件,我儿子叫:{{sonName}}</p> 
                
                <!-- 调用子组件 -->
                <sontag @getSonData="showSonDataFn" v-bind:myName="sonName"></sontag>
                <p>
                    子的数据: {{ mySonData }}
                </p>
            </div>

        </fieldset>
    `,
    // 声明父普通函数
    methods: {
        showSonDataFn(data) {
            // console.log(data)
            this.mySonData = data
        }
    },
    // 声明子组件
    components: {
        // 键就是组件标识
        sontag: {
            // 简单理解:页面加载完毕 -> 组件渲染完毕会触发下面这个键
            mounted() {
                // 在这里面创建自定义事件
                this.$emit("getSonData", this.myName2)
            },
            // 通过props键来获取父传递的数据
            props: ['myName'],
            // 脚下留心:下props相当于下面data 
            data() {
                return {
                    // myName: 数据
                    // myName: 6666,
                    myName2: "xxxxxx"
                }
            },
            // 声明子组件内容
            template: `
                <fieldset>
                    <legend>子组件</legend>
                    <p>我是子组件,我爸爸给我取名:{{myName}}</p>
                </fieldset>
            `
        }
    }
})

3:兄弟组件:通过EventBus(事件总线)

步骤1:创建所有组件共享数据中心 const eventBus = new Vue()
步骤2:传递数据 eventBus. e m i t ( 1 , . . . , n ) 3 e v e n t B u s . emit(自定义事件名称, 数据1,...,数据n) 步骤3:接受数据 eventBus. on(自定义事件名称,处理函数)

// 创建一个组件数据共享中心
const eventBus = new Vue()

Vue.component("mytag1", {
    // 声明组件模型数据
    data() {
        return {
            msg: "webopenfather",
            other: 66666
        }
    },
    // 声明组件内容
    template: `
        <fieldset>
            <legend>兄弟1</legend>
            <button @click="sendDataFn">点击传递数据</button>
        </fieldset>
    `,
    // 声明普通方法
    methods:{
        sendDataFn() {
            // 发送数据
            eventBus.$emit("mytag1MsgData", this.msg, this.other)
        }
    }
})
Vue.component("mytag2", {
    // 声明组件内容
    template: `
    <fieldset>
        <legend>兄弟2</legend>
        <p>{{data}}</p>
        <p>{{data2}}</p>
    </fieldset>
    `,
    // 声明自己的模型数据
    data() {
        return {
            data: "",
            data2: ""
        }
    },
    // 组件渲染完毕触发函数 
    mounted() {
        eventBus.$on("mytag1MsgData", (data, data2, data3) => {// 推荐写箭头函数
            console.log(data)
            console.log(data2)
            console.log(data3)
            // 将数据保存到自己的模型里面 -> 展示
            this.data = data
            this.data2 = data2
        })
    }
})

4:状态管理vuex

在实战中组件之间通信麻烦(两三个兄弟无所谓,但是n个兄弟 比较复杂),所以Vuex实现组件数据统一管理


const store = new Vuex.Store({
  // 声明仓库数据
  state: {
      // 跟其他组件定义data一样:,//
      ...
  },
  // 仓库数据过滤
  getters: {
      方法名(state) {
           +return
      },
      ...
  },
  // 更新仓库数据(这里面不允许写异步请求)
  mutations: {
  // 无参数
      get/set方法名(state) {
           
      },
  // 有参数(思考:有几个形参,根据actions调用传递的实参定)
      get/set方法名(state, data1, ..., datan) {
          state.= 异步请求数据(data1)
      }
  },
  // 更新仓库数据(这里面专门写异步请求,但是不能直接操作state 操作mutations)
  actions: {
  get/set方法名(context) {
  //不传递参数:context.commit(mutations里面的方法名)
  //传递参数: context.commit(mutations里面的方法名, 数据1,..,数据n)
 
   }
  }
})
//
//在组件中触发仓库里面数据语法
//如果在组件中调用state&getter:
computed: {
  方法名() { // 推荐方法名就是vuex.state中的键名
      return this.$store.state/getters.}

}
// 如何调用mutations
// 如何调用actions
methods: {
  方法名() {
      this.$store.commit(mutations里面方法名)
      this.$store.dispatch(actions里面的方法名)
  }
}

辅助函数

辅助函数(state):在组件computed里面写 …Vuex.mapState([键1,…,键n])
辅助函数(getters):在组件computed里面写 …Vuex.mapGetters([方法名1,…,方法名n])
辅助函数(mutations)在组件methods等其他 …Vuex.mapMutations([]或者{})
辅助函数(actions) 在组件methods等其他 …Vuex.mapActions([]或{}})
[‘mutations/action方法名里面方法名’] 注:这时候普通方法名 同 数组里面的值

{ 键就是普通方法名,值mutations/action方法名里面方法名 键:值 }

const store = new Vuex.Store({
    // 声明仓库数据
    state: { // 计算属性 this.$store.state.键
        age: 19,
        name: 'jack'
    },
    // 声明过滤的仓库数据
    getters: { // 计算属性 this.$store.getters.方法名
        username(state) {
            return 'hello2' + state.name
        }
    },
    // 声明更新仓库数据键
    mutations: { // commit
        setAge(state) {
            state.age++
        }
    },
    // 声明更新仓库数据(异步请求 -> mutations)
    actions: { // dispatch
        setAge(context) {
            context.commit('setAge')
        }
    }
})

// this.$store/$el/$data
let vm = new Vue({
    // 激活
    store,  
    el: '#app',
    data: {
    },
    computed: {
        // 推荐方法名就是vuex.state中的键
        // age() {
        //     return this.$store.state.age
        // },
        // name() {
        //     return this.$store.state.name
        // },
        // username() {
        //     return this.$store.getters.username
        // }
        ...Vuex.mapState(['age', 'name']),
        ...Vuex.mapGetters(['username'])
    },
    methods: {
        // testMutation() {
        //     this.$store.commit('setAge')
        // },
        // 下述数组里面的值 就是 vuex.mutations里面的方法名
        // 默认普通方法名就是 vuex.mutations里面的方法名
        // ...Vuex.mapMutations(['setAge']),
        ...Vuex.mapMutations({
            //前面普通方法名,后面是vuex.mutations里面的方法名
            testMutation: 'setAge'
        }),
        // testAction() {
        //     this.$store.dispatch('setAge')
        // }
        ...Vuex.mapActions({
            testAction: 'setAge'
        })
    }
})

模块化思想

store 在new vue中激活

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  // 公共的
  state
  getters
  mutations
  actions

  // 单个模块的
  modules: {
    a: moduleA,
    b: moduleB
  }
})

//调用组件中获取数据
// 它们都是在computed
...mapState({
    方法名: state => state.状态,
    方法名: state => state.moduleA.状态,
    方法名: state => state.moduleB.状态
}),
...mapGetters({
    方法名: '方法名',
    方法名: 'moduleA/方法名',
    方法名: 'moduleB/方法名'
})

// 它们都是在methods
...mapMutations({
    方法名: 'moduleA/方法名',
    方法名: 'moduleB/方法名'
}),
...mapActions({
    方法名: 'moduleA/方法名',
    方法名: 'moduleB/方法名',
})
发布了4 篇原创文章 · 获赞 1 · 访问量 317

猜你喜欢

转载自blog.csdn.net/monthover/article/details/104503445