博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue 中非父子组件间的传值
阅读量:6407 次
发布时间:2019-06-23

本文共 2586 字,大约阅读时间需要 8 分钟。

总线机制

非父子之间传值,可以采用发布订阅模式,这种模式在 Vue 中被称为总线机制,或者叫做Bus / 发布订阅模式 / 观察者模式

Vue.prototype.bus = new Vue() //挂载 bus 属性Vue.component('child', { data(){ return { selfContent: this.content } }, props: { content:String }, template: '
{
{selfContent}}
', methods: { handleChildClick() { this.bus.$emit('change',this.selfContent) // 发布 } }, mounted(){ this.bus.$on('change',(msg)=>{ //订阅,这里会被执行两次 this.selfContent = msg }) }})let vm = new Vue({ el: '#root'})

Vue.prototype.bus = new Vue()这句话的意思是,在 Vue 的prototype挂载了一个bus属性,这个属性指向 Vue 的实例,只要我们之后调用 Vue 或者new Vue时,每个组件都会有一个bus属性,因为以后不管是 Vue 的属性还是 Vue 的实例,都是通过 Vue 来创建的,而我在 Vue 的prototype上挂载了一个bus的属性。

组件被挂载之前会执行mounted钩子函数,所以可以在mounted中对change事件进行监听。

this.bus.$on()那边会被执行两次,原因是什么呢?因为在一个child组件里面,触发事件的时候,外面两个child的组件都进行了同一个事件的监听,所以两个child的组件都会执行一遍this.bus.$on()

Vuex

两个兄弟组件之间公共的父组件,那么它们就没法通过一个公用的父组件来进行数据的中转,要实现这两个页面组件的数据通信应该怎么办呢?

vuex是 Vue 官方推荐的数据框架,在 Vue 的大型项目开发之中,Vue 只能承担视图层的内容,而当我们涉及到大量数据传递的时候,往往都需要一个数据框架进行辅助,Vue 之中这个数据框架就是vuex

看上图vuex指的是整个图中虚线部分的内容。

vuex是什么呢?当我们的一个项目之中,比如说多个组件之间进行复杂的数据传递很困难的时候,如果能把这些公用的数据,放在一个公共的存储空间去存储,然后某一个组件改变了这个公共的数据,其他的组件就能感知到,不就可以了吗。vuex的设计理念就是这样的。

回到上图,右侧虚线那块的图就是公用数据存储区域,我们可以把这个区域理解成store仓库,这个仓库是由几部分组成的:

  • State:它是干嘛用的呢?我们所有的公用数据都存放在State当中,那组件想要用公用的数据,直接去调用State就可以了
  • Actions:有些时候想要改变State中的数据,但是不能让组件直接改变State中的数据,必须走一个流程。这里有一些异步操作,将这些异步操作放在Actions,或者一些复杂的同步操作(批量),也可以放在Actions
  • Mutations:组件想要改变数据先去调用Actions,通过Actions去调用MutationsMutations中放的是一个个同步的修改State的方法

结论:只有通过Mutations才能改变State中公用数据的值,这一步也不是绝对的,有时候可以略过Actions这一步,让组件直接调用Mutations修改State中的数据。这里需要注意的是组件调用Actions是通过Dispatch方法,而组件直接调用Actions或者Actions调用Mutations是通过Commit方法。

其实它就是一个单向数据的改变流程。

具体看下代码是怎么实现的:

export default new Vuex.store({    state: {        name: '天天'    },    actions: {        changeName (ctx, name) {            //ctx 是上下文            ctx.commit('changeName', name)      //通过 commit 调用 mutations 去改变 state,这个 changeName 可以自己随便起名字保证和 mutations 中一样即可        }    },    mutations: {        changeName (state, name) {            state.name = name        }    }})

组件需要使用就可以直接这样使用this.$store.state.name

当其他地方需要修改name时,可以这样写

handleNameClick (name) {    this.$store.dispatch('changeName', name)        //派发一个名字叫 changeName 的 Actions,并把 name 传过去}

这边我在改变state时没有任何异步操作,而且这个操作也非常简单,这个时候组件其实没有必要去调用Actions做这个转发,组件可以直接去调用mutations

handleNameClick (name) {    this.$store.commit('changeName', name)        //派发一个名字叫 changeName 的 mutation,并把 name 传递过去。所以上面的 store 里可以把 Actions 给删除了。}

转载地址:http://qkhea.baihongyu.com/

你可能感兴趣的文章
Delphi TServerSocket,TClientSocket实现传送文件代码
查看>>
JS无聊之作
查看>>
Mac上搭建ELK
查看>>
443 Chapter7.Planning for High Availability in the Enterprise
查看>>
HttpHandler初探 - 页面上输出图像
查看>>
框架和语言的作用
查看>>
unidac连接ORACLE免装客户端驱动
查看>>
Cygwin + OpenSSH FOR Windows的安装配置
查看>>
咏南中间件支持手机客户端
查看>>
fastscript增加三方控件之二
查看>>
Windows Vista RTM 你准备好了么?
查看>>
Tensorflow Serving 模型部署和服务
查看>>
Java Web开发详解——XML+DTD+XML Schema+XSLT+Servlet 3.0+JSP 2.2深入剖析与实例应用
查看>>
topcoder srm 680 div1 -3
查看>>
具体数学第二版第四章习题(1)
查看>>
高效前端优化工具--Fiddler入门教程
查看>>
【翻译】我钟爱的HTML5和CSS3在线工具
查看>>
Java多线程学习(吐血超详细总结)
查看>>
css3 变形
查看>>
Win7 64bit 安装Mysql5 出错 无法启动服务。
查看>>