文章目录
介绍
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
好处:
能够在vuex中集中管理共享的数据,易于开发和后期维护
存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步
能够高效地实现组件之间的数据共享,提高开发效率
应用层级的状态应该集中到单个 store 对象中。
提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
异步逻辑都应该封装到 action 里面。
在 Vue 组件中获得 Vuex 状态
Vuex 的状态存储是响应式的
计算属性返回状态
// 创建一个 Counter 组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM
Vuex 通过 Vue 的插件系统将 store 实例从根组件中“注入”到所有的子组件里。且子组件能通过 this.$store 访问到。让我们更新下 Counter 的实现:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
mapState 辅助函数
一个组件需要获取多个状态的时候,可以使用 mapState 辅助函数帮助我们生成计算属性
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
State
State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行储存。
//创建store数据源,提供唯一公共数据
export default new Vuex.Store({
// 公共数据存放
state: {
//储存数据
//变量
counter:0,
//数组
normaluser:{
normal:false,
id:'',
username:'',
password:'',
telephone:'',
email:'',
qqNumber:'',
level:'',
},
},
mutations: {
},
actions: {
},
modules: {
}
})
组件访问State中数据的一种方式
this.$store.state.couter
组件访问State中数据得第二种方式
import {mapState} from 'vuex'
//从vuex中按需导入mapState函数
export default {
name: "Header",
//通过刚才导入得mapState函数,将当前组件需要的全局属性,映射为当前组件的computed属性
computed:{
...mapState(['couter'])
}
}
Getter
Getter用于Store的数据进行加工处理形成新的数据
Getter可以对Store中已有的数据加工处理之后形成新的数据,类似于Vue的计算属性
Store中数据发生变化,Getter的数据也会跟着变化
export default new Vuex.Store({
// 公共数据存放
state: {
couter:0
},
getters:{
shownNum(){
return '当前的数据是['+state.couter+']'
}
}
})
在其他组件使用getters
第一种方式:
this.$store.getters.名称,后面没有括号
this.$store.getters.showNum
第二种方式
import {mapGetters} from 'vuex'
computed:{
...mapGetters(['showNum'])
}
Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
Mutation用于变更Store数据,不可以直接操作Store中的数据
这种方式虽然操作繁琐,但是可以集中监控所有数据的变化
mutations: {
addN(state.step){
//变更状态
state.count+=step
}
},
你不能直接调用一个 mutation 处理函数。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation 处理函数,你需要以相应的 type 调用 store.commit 方法
第一种方式
this.$store.commit('addN',3)
第二种方式
import { mapMutations } from 'vuex'
//从vuex中按需导入mapState函数
export default {
name: "Header",
//通过刚才导入得mapState函数,将当前组件需要的全局属性,映射为当前组件的computed属性
methods:{
...mapMutations(['sub','subN'])
btn1(){
this.sub()
},
btn2(){
this.subN()
}
}
}
提交载荷(Payload)
Action
Action用于处理异步任务
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是需要通过触发Mutation的方式间接变更数据。
actions: {
addAsync(context){
sertTimeout(()=>{
//只能间接触发Mutation
context.commit('add')
},1000)
}
},
组件中触发Action
第一种方式
methods:{
handle(){
//触发actions
this.$store.dispatch('addAsync')
}
}
第二种方式
组件内导入mapActions函数
import {mapActions} from 'vuex'
methods:{
...mapMutations(['addAsync'])
btn3(){
this.addAsync()
}
}
关于传参数,第一个永远是context,第二个才是传进来的参数
actions: {
addAsync(context,step){
},1000)
}
},
页面刷新造成数据丢失解决
这里我分别说明一下这2中方法的使用方式:
第一种:利用js存储技术(localStorage、sessionStorage、cookie)来进行处理
在App.vue中的create函数中写上这几行代码,
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store") ) {
this.$store.replaceState(Object.assign({},this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload",()=>{
sessionStorage.setItem("store",JSON.stringify(this.$store.state))
})
这样就能在页面刷新时把store的数据存到sessionStorage中,并且在页面加载时及时获取到数据。
这里之所以使用sessionStorage,是因为sessionStorage的存在时间是当页面打开时存在,页面一关闭就会自动清除,能保证下次一进来页面使用的仍是新数据,不是上次存储的数据。
第二种:使用一些vue的插件,例如 vuex-persistedstate ,实际上其根本原理就是将vuex中的state存在 localStorage或者sessionStorage中,在页面刷新之后vuex在从 localStorage中把数据拿回来
一、首先安装插件,
npm install vuex-persistedstate --save
二、然后在store的index.js中写上下面这些代码
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
})
此时可以使用sessionStorage 把数据存储起来,
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
这样我们就把vuex中的数据存储起来了,同样我们在页面加载时再次把sessionStorage中的数据存到vuex中,就可以了。
Vuex模块式开发
新建home.js 和search.js 两个小仓库
const state = {}
const mutations = {}
const actions = {}
const getter = {}
export default {
state,
mutations,
actions,
getter
}
主index.js
import Home from './Home'
import Search from './Search'
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
Home, //
Search
}
})
就会出现