仓库vuex
Vuex简介
1.为了方便实现组件之间的数据共享,Vuex是他们团队借鉴了redux,用来实现vue组件全局状态(数据)管理的一种机制.
2.特点(面试)
能够在vuex中集中管理共享的数据,易于开发和后期维护
能够高效地实现组件之间的数据共享, 提高开发效率
存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;
对于组件中的私有数据,依旧存储在组件自身的data中即可.
3.使用场景
如果你实在不知道开发中什么数据才应该保存到Vuex中,那你就先不用Vuex,需要的时候自然就会想到它
Vuex的官网:
引入方式
1.自己下载引入
2.cli脚手架引入
安装:
npm i vuex --save
导入:
import Vuex from "vuex"
Vue.use(Vuex)
创建仓库:
const store=new Vuex.Store({
state:{msg:"我就是所有共享的数据"}
})
把仓库挂载到vm对象:
new Vue({
render(h){return h(app)},
router,
store//挂载以后 所有的组件就可以直接从store中获取全局数据
}).$mount( "#app")
vue create app
选择配置vuex
State
1.创建state状态,状态就是那个存数据的对象
const store=new Vuex.store({
state:{msg:"我就是所有共享的数据"}
})
2.组件中访问数据
this.$store.state.msg
Getter
getter就就像是store的计算属性,它会传入state对象供我们操作 //1.设计
const store = new Vuex.Store({
state: {
arr: [
{ id: 1, text: '...', birth: "1997-02-03" },
{ id: 2, text: '...', birth: "2019-10-03" }
]
},
getters: {
bigMans(state) {
return state.arr.filter((man)=>{
let manY=new Date(man.birth).getFullYear()
let nowY=new Date().getFullYear()
return (nowY-manY)>=18
})
}
}
})
//2.使用
this.$store.getters.bigMans
Mutation
组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation 不要用赋值表达式直接在组件中给store设置新数据 这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI
//1.设计
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
//默认传第一个参数传state
increment (state,obj) {
// 变更状态
state.count=obj.n
}
}
})
//2.组件中使用 //2.1 直接触发并传值(提交载荷)
this.$store.commit('increment',{n:100})
//2.2 可以以一个对象的形式传入 //传入对象时,当相于把整个对象作为了第二个参数传入mutations
this.$store.commit({
type: 'increment',
n:100
})
注意:一条重要的原则就是要记住 mutation 必须是同步处理 下面是错误的方式:
mutations: {
increment (state,obj) {
//如果fnAsync函数是一个异步业务函数,就会导致更新失败
fnAsync(() => {
state.count=obj.n
})
}
}
Action
Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作。
//设计
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state,obj) {
state.count=obj.n
}
},
actions: {
//默认第一个参数传一个跟store一样的对象
increment (context,obj) {
//假设fnAsync是一个异步业务函数
fnAsync(() => {
context.commit('increment',obj)
})
}
}
})
//使用也是两种: //1.直接分发
this.$store.dispatch('increment',{n:100})
//2.以对象形式分发
this.$store.dispatch({
type: 'increment',
n:100
})
Module
可用于业务分块开发: 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter
//分块设计:
const moduleA = {
namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)
state: { msg:1 },
mutations: { change(state,n){state.msg=n} },
actions: { change(context,n){context.commit("change",n)} },
getters: { x(state){return state.msg} }
}
const moduleB = {
namespaced: true,//局部命名空间
state: { msg:1 },
mutations: { change(state,n){state.msg=n} },
actions: { change(context,n){context.commit("change",n)} },
getters: { x(state){return state.msg} }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
//组件中的使用:
this.$store.state.a.msg // -> moduleA 的状态
this.$store.state.b.msg // -> moduleB 的状态
this.$store.commit("a/change",100)-> moduleA 的mutations
this.$store.commit("b/change",200)-> moduleB 的mutations
this.$store.getters["a/x"]-> moduleA 的getters
this.$store.getters["b/x"]-> moduleB 的getters
this.$store.dispatch("a/change",100)-> moduleA 的actions
this.$store.dispatch("b/change",200)-> moduleB 的actions
技术厉害的同学拓展:mapState,mapGetters,mapMutation,mapAction和使用常量替代 Mutation 事件类型,
使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然
用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。