Vuex主要用于兄弟组件或者是隔代组件通信,并分享数据的最好方式!并要关注几个问题:
1.vuex是什么?
2.vuex的核心概念;
- vuex的属性;
- vuex的数据传递流程;
3.为什么要用vuex?
答1:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. Vuex 解决了多个视图依赖于同一个状态和来自不同视图的行为需要变更同一状态的问题,将开发者的精力聚焦于数据的更新而不是数据在组件之间的传递上
答2:
vuex五大核心属性:state,getter,mutation,action,module
- state:存储数据,存储状态;在根实例中注册了store 后,用
this.$store.state
来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。 - getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
- mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
- actions:包含任意异步操作,通过提交 mutation 间接更变状态。
- module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块
答3:
由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致代码无法维护。所以我们需要把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!通俗讲就是兄弟组件或者隔代组件之间能传递数据
下面做一个代码实例:用于兄弟之间的通信:
目录结构:本案例采用vue-cli去搭建,只写你要加上的代码
|-src
|- pages
|- vuex
|- father.vue
|- son1.vue
|- son2.vue
|- store
- index.js
|- main.js
|- router.js
|- package.json
package.json
"dependencies": {
"vuex": "^3.2.0"
}
router.js
import father from './pages/vuex/father'
export default new Router({
{
path: '/father',
name: 'father',
component: father
},
)}
main.js
import store from './store'
new Vue({
router,
store,// 加上这个
render: h => h(App),
}).$mount('#app')
vuex/father.vue
<template>
<div id="father">
<son1/>
<son2/>
</div>
</template>
<script>
import Son1 from './son1';
import Son2 from './son2';
export default {
// 父组件
name: 'father',
components: {
Son1,
Son2
}
}
</script>
<style>
</style>
vuex/son1.vue
<template>
<div id="son1">
<h1>组件son1</h1>
<button @click="transform">点击我让son2组件接收到数据</button>
<p>点击son2,所以本组件信息发生变化:<span>{{ Son2Message }}</span></p>
</div>
</template>
<script>
export default {
name: 'son1',
data () {
return {
Son1Message: 'Hello, son2组件,我是son1组件'
}
},
computed: {
Son2Message(){
return this.$store.state.Son2Msg
}
},
methods: {
transform(){
this.$store.dispatch('receiverSon1Msg', this.Son1Message)
}
}
}
</script>
<style>
span{
color: blue;
}
</style>
或另一种写法:采用mapState, mapActions的方法
<template>
<div id="son1">
<h1>组件son1</h1>
<button @click="transform">点击我让son2组件接收到数据</button>
<p>点击son2,所以本组件信息发生变化:<span>{{ Son2Msg }}</span></p>
</div>
</template>
<script>
import { mapState, mapActions} from 'vuex'
export default {
name: 'son1',
data () {
return {
Son1Message: 'Hello, son2组件,我是son1组件'
}
},
computed: {
// Son2Message(){
// return this.$store.state.Son2Msg
// }
...mapState(['Son2Msg'])
},
methods: {
// 映射:this.$store.dispatch('receiverSon1Msg', this.Son1Message) ,this.Son1Message通过函数参数方式传递
...mapActions(['receiverSon1Msg']),
transform(){
this.receiverSon1Msg(this.Son1Message)
// 触发receiverSon1Msg,将son1组件的数据存放到store里去
// this.$store.dispatch('receiverSon1Msg', this.Son1Message)
}
}
}
</script>
<style>
span{
color: blue;
}
</style>
vuex/son2.vue
<template>
<div id="son2">
<h1>我是son2组件</h1>
<button @click="transform">点击我让son1组件接收数据</button>
<p>因为你点了son1,所以本组件的信息发生了变化:<span>{{Son1Message}}</span></p>
</div>
</template>
<script>
export default {
name: 'son2',
data () {
return {
Son2Message: 'Hello, son1组件, 我是son2组件'
}
},
computed: {
Son1Message(){
return this.$store.state.Son1Msg
}
},
methods: {
transform(){
this.$store.dispatch('receiverSon2Msg', this.Son2Message)
}
}
}
</script>
<style>
span{
color: blue;
}
</style>
或另一种写法:采用mapState, mapActions的方法
<template>
<div id="son2">
<h1>我是son2组件</h1>
<button @click="transform">点击我让son1组件接收数据</button>
<p>因为你点了son1,所以本组件的信息发生了变化:<span>{{Son1Msg}}</span></p>
</div>
</template>
<script>
import { mapState, mapActions} from 'vuex'
export default {
name: 'son2',
data () {
return {
Son2Message: 'Hello, son1组件, 我是son2组件'
}
},
computed: {
// Son1Message(){
// return this.$store.state.Son1Msg
// }
...mapState(['Son1Msg'])
},
methods: {
// 映射this.$store.dispatch('receiverSon2Msg', this.Son2Message),this.Son2Message通过函数参数方式传递
...mapActions(['receiverSon2Msg']),
transform(){
this.receiverSon2Msg(this.Son2Message)
// this.$store.dispatch('receiverSon2Msg', this.Son2Message)
}
}
}
</script>
<style>
span{
color: blue;
}
</style>
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
// 初始化 son1和son2 组件的数据,等待获取
Son1Msg: '',
Son2Msg: ''
}
const actions = {
// 接收来自组件派发的来的数据,receiverSon1Msg()就是前面派发来的,所以名字要和前面参数一定义的一样
receiverSon1Msg(context, Son1Msg) {
// 通过context将username传送到mutations
context.commit('receiverson1msg', Son1Msg)
},
receiverSon2Msg(context, Son2Msg){
// actions里面可以进行异步操作,setTimeout是异步函数
setTimeout(function(){
context.commit('receiverson2msg', Son2Msg)
},2000)
}
}
const mutations = {
receiverson1msg(state, Son1Msg){
// 将son1组件的数据放入state中
state.Son1Msg = Son1Msg
},
receiverson2msg(state, Son2Msg) {
// 将son2组件的数据放入state中
state.Son2Msg = Son2Msg
}
}
export default new Vuex.Store({
state,
mutations,
actions
})
手画图:
最好效果图:其中蓝色字为传递的数据。