这种场景,如何设计 vue 主页面分发消息给子组件?

vue 项目, 有多个主页面,这里用 Home.vueAbout.vue 模拟

每个主页面内部有一个 websocket
且有多个不同层级的子组件,这里用 HellowWorld.vue模拟

每当主页面收到 websocket 消息的时候,通过某种方式通知到子组件

我目前的方案

  • Home.vue

    <template>

    <div class="home">

    <HelloWorld msg="Welcome to Your Vue.js App"/>

    <el-button @click="send('home')">home</el-button>

    </div>

    </template>

    <script>

    import HelloWorld from '@/components/HelloWorld.vue'

    export default {

    name: 'Home',

    components: {

    HelloWorld

    },

    data () {

    return {

    wsChildren: []

    }

    },

    provide () {

    return {

    ipcRoot: this

    }

    },

    methods: {

    send (data) {

    this.wsChildren.forEach(vm => vm.onWsMessage(data))

    }

    }

    }

    </script>

  • About.vue

    <template>

    <div class="about">

    <img alt="Vue logo" src="../assets/logo.jpg">

    <HelloWorld msg="Welcome to Your Vue.js App"/>

    <el-button @click="send('about')">about</el-button>

    </div>

    </template>

    <script>

    // @ is an alias to /src

    import HelloWorld from '@/components/HelloWorld.vue'

    export default {

    name: 'About',

    components: {

    HelloWorld

    },

    data () {

    return {

    wsChildren: []

    }

    },

    methods: {

    send (data) {

    this.wsChildren.forEach(vm => vm.onWsMessage(data))

    }

    }

    }

    </script>

  • HelloWorld.vue

    <template>

    <div class="hello">

    child

    </div>

    </template>

    <script>

    export default {

    name: 'HelloWorld',

    inject: {

    ipcRoot: {

    default: null // 提供默认值为 null,当没有找到 ipcRoot 时使用

    }

    },

    mounted () {

    if (this.ipcRoot && this.ipcRoot.wsChildren) {

    this.ipcRoot.wsChildren.push(this)

    }

    },

    methods: {

    onWsMessage (data) {

    console.log('__SY__? ~ HelloWorld onWsMessage ~ data:', data)

    }

    }

    }

    </script>

也就是当子组件挂载完成后,主页面主动收集,然后通过遍历去分发消息,这种模式以后的维护性如何?

请问各位到老有没有更好的方式,虚心求教!!!


回答:

可以使用 vuex 或者 EventBus

EventBus为例,创建一个新的 vue 实例,通过全局注册,让所有 vue 都能访问到同一个实例,然后通过 $emit$on 做到跨页面、跨层级的事件监听。

只需要在要分发数据的文件中调用 this.$bus.$emit('onMsg', msg),需要监听的文件在 mounted 周期中注册监听事件 this.$bus.$on('onMsg', function(msg))即可。

记得在页面卸载时调用 this.$bus.$off('onMsg', function(msg))关闭监听,不然可能会有重复监听的问题。

bus.js

import vue from 'vue'

export default new vue()

main.js

import Bus from './bus'

vue.prototype.$bus = Bus

主页面

this.$bus.$emit('事件名', '数据')

子组件

this.$bus.$on('事件名', function() => {})

以上是 这种场景,如何设计 vue 主页面分发消息给子组件? 的全部内容, 来源链接: utcz.com/p/935371.html

回到顶部