通常在项目中,状态管理都是使用Vue官方提供的Vuexjavascript
当在多组件之间共享状态变得复杂时,使用Vuex,此外也能够使用Bus来进行简单的状态管理html
1.1 父组件与子组件之间的通讯
vue.config.js
文件内容vue
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
文件内容java
<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的值
app
store.vue文件中,a-input标签使用v-model进行双向绑定,v-model是一个语法糖iview
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标签上显示出来,这样就实现了不一样组件之间的通讯。
原文出处:https://www.cnblogs.com/renpingsheng/p/11210223.html