Vue 组件间有5种常见的数据共享方式:
1:props & $emit
2:依赖注入(provide inject )
3:处理边界
4:eventbus
5:vuex
下面详细介绍vuex方式的数据传递:
Vuex是什么
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
白话解释
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
使用Vuex之前应该下载Vuex 引用
store
创建一个Store
//创建store之前确保已经引入Vuex.js或在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
//state相当于自定义组件中的data
state: {
count: 0
},
//getters相当于自定义组件中的computed
getters: {
getName() {
return this.$store.state.count--;
}
},
//mutations相当于自定义组件中的methods,只能做同步的操作
//使用commit 触发 mutations
mutations: {
increment(state) {
state.count++
}
}
,
//actions异步操作,例如ajax请求
//使用dispatch触发 actions
actions: {
//todo
}
})
核心概念
State
Vuex 使用单一状态树,这就意味着,每个应用将仅仅包含一个 store 实例。
Vuex中的state相当于组件中的 data 。
通过使用store.state / this.$store.state
<div id="app"></div>
<script>
const store = new Vuex.Store({
state: {
count:3
}
});
const counter = {
//模板中用$store.state.count 或者 直接count 都可
template: `<div>{{ $store.state.count }}--{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
//vue对象要放在最底层
const vm = new Vue({
el: '#app',
template: `<div class="app"><counter></counter></div>`,
//把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
//data数据失效
data:{
count:10,
age:22
},
components: { counter },
})
</script>
结果:
虽然root中有data数据,但是不会从date中取数据
Getter
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 接受 state 作为其第一个参数:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '唐', done: true },
{ id: 2, text: '宋', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
});
const counter = {
template: `<div>{{ count[0].id }}---{{count[0].text}}---{{count[0].done}}</div>`,
computed: {
count() {
return store.getters.doneTodos;
}
}
}
const vm = new Vue({
el: '#app',
template: `<div class="app"><counter></counter></div>`,
store,
components: { counter },
})
结果:
Mutation
- mutation 相当于自定义组件中的methods。
- 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)
- 回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
- 不能直接调用一个 mutation handler,需要以相应的 type 调用 store.commit 方法:store.commit(‘increment’)
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
//事件类型:increment
increment (state) {
// 变更状态
state.count++
}
}
})
//store.commit('事件类型','事件参数');
//store.commit('increment')
const vm = new Vue({
el: '#app',
store,
mounted() {
store.commit("increment");
}
})
控制台打印结果:
Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。——action 不能直接对State 中的数据进行操作,只能通过commit(type,data) 方法调用 mutation。
- Action 可以包含任意异步操作。
- 通过 store.dispatch(type)方法触发action,type为事件类型
const store = new Vuex.Store({
state: {
dataList:[]
},
mutations: {
render(state,data){
state.dataList=data;
},
},
actions: {
//对state进行解构,将commit解构出来
getData({commit}){
fetch("./data.json").then((res)=>res.json()).then((result)=>{
//不能直接对State 中的数据进行操作,能通过commit(type,data) 方法
commit("render",result.data);
})
}
}
})
const vm = new Vue(){
created(){
//触发action
store.dispatch("getData");
}
}
异步过程简单来说就是,通过(dispatch)调用actions中的函数,函数中做异步请求数据,
请求结果作为同步函数的参数,(commit)调用actions中的同步函数,在同步函数中实现对state里的变量赋值
参考文档:Vuex