组件通信的原理在 Vue 两种组件通信方法 中已经讲解过了,本篇文章中主要介绍vuex的原理和用法。
1. 什么是vuex
vuex是专为vue.js项目开发的集中式存储管理所有组件的状态,并以一种可预测的状态发生变化,简单来说就是这个vuex状态机里面写好了vue项目可能发生的所有信息,任何组件都可以访问它,它会按规则发生通知,使得相应的组件发生预定状态的变化。
-
吐槽一下Vue 两种组件通信方法 ,这两种方法的原理就是单向数据流的思路,对于多个组件来说问题在于:
- 多个视图依赖于同一状态
- 来自不同视图的行为需要变更同一状态
- 对于props方法:对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力
-
我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码
单向数据流
如图所示:
-
state,驱动应用的数据源;
-
view,以声明方式将 state 映射到视图;
-
actions,响应在 view 上的用户输入导致的状态变化。
图中可知是一个单向数据流 -
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
image.png
这就是 Vuex 背后的基本思想
2.使用vuex的好处
- Vue 两种组件通信方法的两种方法都是父子组件之间的通信方式,那么问题来了,如果有一个组件下面有多级子组件,如果需要跨过父子关系在爷孙组织之间或夸更大的辈分,或者同一辈分中相邻组件之间通信,显然这种方法不适合,这时候vuex状态机的作用体现出来了。
- vuex其实就是一个管家的作用,它实现了所有组件都能无障碍地访问它,它也能监听到管辖之内的所有组件发出的通信信息,并能做出回应。
3. vuex 用法
- 核心概念之state/getter/mutation 的用法
Vue.use(Vuex) //使用vuex
//创建一个store实例
const store = new Vuex.Store({
state: { //声明state状态树
count: 0,
firstName: "qing",
lastName: "lin"
},
mutations: { //mutation中提交需要改变的方法
increment(state) { //mutation中触发一个increment的mutation时调用此函数(state作为第一个参数),*注意,不同于action,mutation必须是同步函数
state.count++
}
},
getters:{
fulleName(state){
return state.firstName + " " + state.lastName
}
}
})
const Counter = {
//页面中渲染出state状态树中的内容
template: '
<div>
<div>{{count}}</div>
<p>{{firstName}}{{lastName}}</p>
<button @click="add">+</button>
</div>', //这里的state,firstName,lastName都是从computed计算属性中获取的
computed: {
count() {
return this.$store.state.count //computed计算属性中的state是从store实例中获取的,这个的是响应式的,只要有一个变化,页面中的state也会跟着变化
},
//fullName(){
// return this.$store.getters.fullName
//},
//这两种写法作用一样,建议使用下面的写法
...Vuex.mapGetters(["fullName"]),
...Vuex.mapState(['firstName', 'lastName']) , //展开运算符,推荐使用这种写法,以新对象替换老对象
},
methods:{
add(){ //调用方法
this.$store.commit('increment')
}
}
}
const app = new Vue({
el: "#app",
store, //把store的实例注入到所有子组件中
components: {
Counter
},
template: '<div class="app"><counter></counter></div>'
})
store.commit('increment') //在根节点中注入store
- 核心概念之action的用法
action和mutation都可以进行更改状态,action相比于mutation的不同之处有两个:- action不会直接更改状态,而是提交mutation.
- action可以进行任意异步操作.
- action 基础用法
const store = new Vuex.Store({
state:{
count:0;
} ,
mutations:{
increment(state){
state.count ++
}
},
//action不会直接修改store实例,而是通过提交mutation的方法间接地修改store
action:{
commit(context){ //这里的context可以看做是store,但不完全是,所以这个参数也可以是store实例中的方法
context.commit("increment")
}
}
})
网友评论