一般在项目中,状态管理都是使用Vue官方提供的Vuex

当在多组件之间共享状态变得复杂时,使用Vuex,此外也可以使用Bus来进行简单的状态管理

1.1 父组件与子组件之间的通信

vue.config.js文件内容

const path = require('path')
const resolve = dir => path.join(__dirname,dir)
const BASE_URL = process.env.NODE_ENV === 'production' ? '/iview-admin':'/' module.exports = {
lintOnSave: false,
baseUrl: BASE_URL,
chainWebpack:config =>{
config.resolve.alias
.set('@',resolve('src')) // 用 @ 符号来替代 src 这个路径
.set('_c',resolve('src/components')) // 用 _c 来替代 src/components这个目录
},
productionSourceMap:false, // 打包时不生成 .map文件,减少打包的体积同时加快打包速度
devServer:{ // 跨域配置,告诉开发服务器将任何没有匹配到静态文件的请求都代理到proxy指定的URL
proxy:'http://localhost:8000'
}
}

src/components/AInput.vue文件内容

<template>
<input @input="handleInput" :value="value">
</template>
<script>
export default {
name:"AInput",
props:{
value:{
type:[String,Number],
default:''
}
},
methods:{
handleInput (event){
const value = event.target.value
this.$emit('input',value)
}
}
}
</script>

src/views/store.vue文件内容

<template>
<div>
<a-input v-model="inputValue"></a-input>
<p>{{inputValue}}</p>
</div>
</template> <script>
import AInput from '_c/AInput.vue' // 引入 AInput组件 export default {
name:'store',
data () {
return {
inputValue:''
}
},
components:{
AInput // 注册AInput组件,然后就可以使用 AInput组件了
}
}
</script>

src/router/router.vue文件内容

import Home from '@/views/Home.vue'

export default [
... // 此处省略
{
path:'/store',
component:() => import('@/views/store.vue')
}
]

浏览器打开URL:http://localhost:8080/#/store,显示效果如下

首先在AInput.vue文件中,为input标签绑定handleInput事件当input框中的数据改变时就会触发handleInput事件,input标签中显示的数据就是value的值

store.vue文件中,a-input标签使用v-model进行双向绑定,v-model是一个语法糖

v-model的效果等同于如下

src/views/store.vue文件内容

<template>
<div>
<a-input :value="inputValue" @input="handleInput"></a-input>
<p>{{inputValue}}</p>
</div>
</template> <script>
import AInput from '_c/AInput.vue' export default {
name:'store',
data () {
return {
inputValue:''
}
},
components:{
AInput
},
methods:{
handleInput(val){
this.inputValue = val
}
}
}
</script>

相比于上面的代码方式,v-model方便很多

vue中,单向数据流通信:

父组件向子组件传值一定是通过属性,子组件想修改父组件传递的值时,一定要通过事件,把要修改的值以参数的形式通过事件提交给父组件,然后在父组件中绑定事件接收消息知道子组件要修改父组件中的数据,最后就可以在子组件中修改数据了,这就是父子组件之间的通信

1.2 单页面中多组件(兄弟组件)中的通信

src/components目录下新建AShow.vue文件

src/components/AShow.vue文件内容

<template>
<div>
<p>AShow: {{ content }}</p>
</div>
</template>
<script>
export default {
props: {
content: {
type: [String, Number],
default: '' // content的值默认为空
}
}
}
</script>

修改src/components/store.vue文件内容

<template>
<div>
<a-input @input="handleInput"></a-input>
<a-show :content="inputValue"></a-show>
</div>
</template>
<script>
import AInput from '_c/AInput.vue' // 引入 AInput组件
import AShow from '_c/AShow.vue' // 引入 AShow组件 export default {
name:'store',
data () {
return {
inputValue:''
}
},
components:{
AInput, // 注册AInput组件,然后就可以使用 AInput组件了
AShow // 注册AShow组件
},
methods: {
handleInput(val){
this.inputValue = val
}
}
}
</script>

浏览器打开URL: http://localhost:8080/#/store,显示效果如下

可以看到,在父组件store中给子组件AInput绑定事件handleInput,handleInput触发之后,把AInput组件中输入的数据赋值给this.inputValue

最后再把this.inputValue的值传递给AShow组件的content属性,以达到单页面下多组件传值的目的。

1.3 使用Bus进行多组件的通信

src/lib目录下新建'bus.js'文件

src/lib/bus.js文件内容

import Vue from 'vue'
const Bus = new Vue()
export default Bus

src/main.js文件中引入bus.js文件

src/main.js文件内容

import Vue from 'vue'
import App from './App.vue'
import router from './router/index'
import store from './store/index'
import Bus from '@/lib/bus' // 引入Bus组件 Vue.config.productionTip = false
Vue.prototype.$bus = Bus // 注册到vue的根实例里,给vue原生对象上添加bus属性 new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

src/views/view1.vue文件内容

<template>
<div class="div2">
<button @click="handleClick" name="button">按钮一</button>
</div>
</template>
<script>
export default {
methods: {
handleClick() {
this.$bus.$emit('changeValue', 'hello') // 把on-click事件提交给 bus
}
},
mounted () {
console.log(this.$bus) // 打印出 this.$bus对象
}
}
</script>
<style>
.div2 {
border: 1px solid green;
}
</style>

src/views/view2.vue文件内容

<template>
<div class="div1">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
},
mounted() {
this.$bus.$on('changeValue', msg => {
this.message = msg
}) // 监听bus的 on-click 事件
}
}
</script>
<style>
.div1 {
border:1px solid red;
}
</style>

src/router/router.js文件内容

import Home from '@/views/Home.vue'

export default [
{
path:'/named_view',
components:{
default: () => import('@/views/child.vue'),
view1: () => import('@/views/view1.vue'),
view2: () => import('@/views/view2.vue'),
}
}
...
]

浏览器打开URL: http://localhost:8080/#/named_view,在浏览器的调试工具中可以看到打印的this.$bus对象

页面渲染结果为

点击页面上的'按钮一',效果如下

在上面的例子里,按钮一所有的绿色框所在就是view1组件,红色框所在就是view2组件

view1.vue组件中,$emit方法会在当前组件view1上把changeValue事件changeValue是绑定在this.$bus这个vue实例上,然后获取changeValue事件的返回值'hello'

然后在view2组件中,在this.$bus这个实例上监听changeValue事件,得到changeValue事件的返回值'hello',然后把返回值赋值给 message,并在p标签上显示出来,这样就实现了不同组件之间的通信。

Vue状态管理之Bus的更多相关文章

  1. Vue状态管理vuex

    前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue提供了vuex.本文将详细介绍Vue状态管理vuex 引入 当访问数据对象时,一个 V ...

  2. vue状态管理器(用户登录简单应用)

    技术点:通过vue状态管理器,对已经登录的用户显示不同的页面: 一  vue之状态管理器应用 主要用来存储cookie信息 与vue-cookies一起使用 安装:npm install vue-co ...

  3. vuex(vue状态管理)

    vuex(vue状态管理) 1.先安装vuex npm install vuex --save   2.在项目的src目录下创建store目录,并且新建index.js文件,然后创建vuex实例,引入 ...

  4. Vue状态管理-Bus

    1.父子组件之间进行通讯: 父组件通过属性和子组件通讯,子组件通过事件和父组件通讯.vue2.x只允许单向数据传递. 先定义一个子组件AInput.vue: <template> < ...

  5. Vue状态管理之Vuex

    Vuex是专为Vue.js设计的状态管理模式.采用集中存储组件状态它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 1.首先让我们从一个vue的计数应用开始 ...

  6. Vue状态管理

    1.导出Vuex import Vuex from 'vuex' 2.定义store /*状态管理*/ const store = new Vuex.Store({ state: { headerSh ...

  7. vue - 状态管理器 Vuex

    状态管理 vuex是一个专门为vue.js设计的集中式状态管理架构.状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态.简单的说就是data中需要共用的属性.

  8. 五、vue状态管理模式vuex

    一.vuex介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 即data中属性同时有一 ...

  9. Vue 状态管理

    类flux状态管理的官方实现 由于多个状态分散的跨越在许多组件和交互间的各个角落,大型应用复杂度也经常逐渐增长. 为了解决这个问题,vue提供了vuex:我们有收到elm启发的状态管理库,vuex甚至 ...

随机推荐

  1. Win8 Metro(C#)数字图像处理--2.67图像最大值滤波器

    原文:Win8 Metro(C#)数字图像处理--2.67图像最大值滤波器  [函数名称]   最大值滤波器WriteableBitmap MaxFilterProcess(WriteableBi ...

  2. WPF Textblock Run 空白问题

    消除Run之前的空白是将Run标签布局时头尾相连 如: <TextBlock > <Run Text="A"></Run> <Run Te ...

  3. 微信小程序把玩(二十八)image组件

    原文:微信小程序把玩(二十八)image组件 image组件也是一个程序不可缺少的,可以这样说一个app中image组件随处可以看到,一般 image有两种加载方式第一种是网络图片第二种是本地图片资源 ...

  4. 零元学Expression Blend 4 - Chapter 9 用实例了解布局容器系列-「Canvas」

    原文:零元学Expression Blend 4 - Chapter 9 用实例了解布局容器系列-「Canvas」 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Blen ...

  5. Visual Studio一直弹出“未将对象引用设置到对象的实例”对话框的处理

    试了一下,VS2017更新到最新版本的时候,会有这个错误.相当于是相当编辑XAML界面的时候会弹出,程序真正执行的时候反而不会弹出. 应该是最新的VS2017在显示XAML编辑界面的时候,会执行一部分 ...

  6. 为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)

    在做更新,在测试异常的时候,在下载过程中,发现如果直接系统禁用了网络,会报错误,可以捕获.但是如果是第三方软件限制程序联网,问题来了. 程序会一直在那里等待,没有异常,也不发送QNetworkAcce ...

  7. 大数据基础之Kafka(1)简介、安装及使用

    kafka2.0 http://kafka.apache.org 一 简介 Kafka® is used for building real-time data pipelines and strea ...

  8. SYN2101型 NTP网络时间服务器

    SYN2101型  NTP网络时间服务器   时钟校准服务器时间 ntp服务器ntp时间校准服务器使用说明视频链接: http://www.syn029.com/h-pd-56-0_310_1_-1. ...

  9. Java动态规划

    1. 介绍 动态规划典型的被用于优化递归算法,因为它们倾向于以指数的方式进行扩展.动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题,然后将它们保存到内存中,这样我们就不必在每次使用它 ...

  10. 【vue系列】Virtual DOM 真的比操作原生 DOM 快吗?

    一.前言 网上都说操作真实dom怎么怎么慢,这儿有个例子:http://chrisharrington.github.io/demos/performance/,例子循环2000个随机数组,点击按钮重 ...