vuex官网:https://vuex.vuejs.org/zh/
vuex介绍:vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(集中式存储管理)
使用场景:多个组件共用一个属性数据,并且组件传值诸多繁琐,直接用全局共享属性比较方便,数据统一管理好维护
存储哪些东西:存储全局共享属性,存储全局共享方法
vuex优势: 相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。
vuex劣势: 在F5刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。(即刷新浏览器,vuex数据丢失)
vuex安装:
npm install vuex@next --save
创建方式:新建src/store/index.js文件
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0,
},
getters: {
count: (state) => state.count,
},
mutations: {
add(state,value) {
state.count+=value;
},
},
//注意直接传递state不会执行,需要传递commit,state,actons是用来提交mutations里的方法
actions: {
increment({commit,state,value}) {
commit('add', value)
},
},
modules: {
},
});
vuex中的属性
state =》有点像组件里的data,用来定义数据
调用方法:
方式一:this.$store.state.数据名
//标签
<h1>首页{{ $store.state.settings.theme }}</h1>
//js
this.$store.state.settings.theme
方式二:使用辅助函数mapState,然后在computed解构…mapState([‘storeName’])就可以在标签上直接使用或this.storeName使用
<template>
<div>
<h1>首页{{ storeName }}</h1>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default defineComponent({
computed: {
...mapState(['storeName'])
}
})
以上两种方式有什么区别?
方式一:this.
s
t
o
r
e
.
s
t
a
t
e
.
x
x
x
是使用
store.state.xxx 是使用
store.state.xxx是使用store本身的属性值
方式二:mapState辅助函数是拷贝了state里的某个属性到vue的当前组件的对象
区别:this.$store.state.xxx 是可以直接修改属性,mapState辅助函数的属性不可以修改
gerters =〉有点像组件里的computed,用来写计算属性的方法
调用方法:
方式一:this.$store.getters.fangfaname
//标签
<h1>首页{{ $store.getters.fangfaname }}</h1>
//js
this.$store.getters.fangfaname
方式二:辅助函数mapGetters用的较多
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['sidebar', 'device', 'user', 'baseApi'])
}
注意:vuex是单向数据流,所以v-model绑定getters会报错,而且没有get和set的写法(组件中可以用get和set方法,vuex中没有)
mutations =》有点像组件里的methods,用来写具体方法
调用方法:
方式一:辅助函数mapMutations
<template>
<div>
<h1>首页{{ storeName }}</h1>
<button @click="add">+</button>
</div>
</template>
import { mapState ,mapMutations} from 'vuex'
export default defineComponent({
computed: {
...mapState(['storeName'])
},
methods: {
...mapMutations(['add']),
}
})
方式二:通过commit方式提交mutations
this.$store.commit('fangfaname','canshu')
actions=>和mutations有点类似,action也是存储方法的
调用方法:
方式一:辅助函数mapActions
<template>
<div>
<h1>首页{{ storeName }}</h1>
<button @click="increment">+</button>
</div>
</template>
import { mapState ,mapActions} from 'vuex'
export default defineComponent({
computed: {
...mapState(['storeName'])
},
methods: {
...mapAations(['increment'])
}
})
方式二:使用dispatch方式
methods: {
...mapAations(['increment']),
but(){
this.$store.dispatch('increment',20)//用dispatch调用方法名,参数
}
}
mutations和actions的区别?
使用方式:mutations是通过commit来提交;actions是用dispatch来提交
actions是用来提交mutations的,而不是直接更改状态(actions可以改变state状态值,但不建议这样写)
同步/异步:mutations是同步函数,actions是包含异步方法(setTimeout,promise.all,promise.then)
mutations里写异步,页面变了但state里的数据不会改变,只能写同步
module=》把整个状态管理再次细分为模块,更好管理,主要是state
import { mapState } from 'vuex'
computed: {
...mapState({
// 组件自定义名:state=> state.模块.属性名
sidebar: state => state.app.sidebar,
device: state => state.app.device,
showSettings: state => state.settings.showSettings,
needTagsView: state => state.settings.tagsView,
fixedHeader: state => state.settings.fixedHeader
})
}
vuex的持久化存储
Vuex是在中大型项目中必不可少的状态管理组件,刷新会重新更新状态,但是有时候我们并不希望如此。例如全局相关的,如登录状态、token、以及一些不常更新的状态等,我们更希望能够固化到本地,减少无用的接口访问,以及更佳的用户体验。
页面刷新后,想保存页面未保存的数据。我们总是习惯于放在浏览器的sessionStorage、localStorage、cookie中。但是用了vue后,vuex便可以被应用了。
方式一:自己写localStorage.setItem存储,项目中大量数据手动写比较麻烦
localStorage.setItem("count",state.count);
方式二:第三方插件 vuex-persistedstate
安装: npm install vuex-persistedstate --save
配置使用:
#在store下的index.js中
import createPersistedState from 'vuex-persistedstate'
export default new Vuex.Store({
// ...
plugins: [createPersistedState ()]
})
#vuex-persistedstate默认使用localStorage来固化数据(默认存储于localStorage)
存储到sessionStorage
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [
createPersistedState({
storage: window.sessionStorage
})
]
})
存储到cookie
import persistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
export default new Vuex.Store({
// ...
plugins: [
persistedState({
storage: {
getItem: key => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, {
expires: 7
}),
removeItem: key => Cookies.remove(key)
}
})
]
})
默认持久化全部state,配置制定的state的属性值
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [
createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的assessmentData
assessmentData: val.assessmentData
}
}
})
]
})
自定义多种存储方式配置
import Vue from 'vue'
import { Vuex } from 'vuex';
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
const createPersistedStatetedState1 = () => createPersistedState({
key: 'vuexStorage',
storage: window.localStorage,
reducer: (state) => {
return {
//localStorage只存储device
count: state.device
}
}
})
const createPersistedStatetedState2 = () => createPersistedState({
storage: window.sessionStorage,
reducer: (state) => {
let sessionState = Object.assign({}, state)
//sessionStorage存储device以外的其他参数
for(let key in sessionState){
if(key !== 'device'){
delete sessionState[key]
}
}
return {
sessionState:sessionState,
}
}
})
const store = new Vuex.Store({
state: {
count: 0,
device: 'pc'
},
getters: {
getCount: state => {
return state.count
},
getDevice: state => {
return state.device
}
},
mutations: {
device
},
// 两种方式都需要配置
Plugins: [
createPersistedStatetedState1,
createPersistedStatetedState2
]
})
API
createPersistedState([options])使用给定的选项创建插件的新实例。可以提供以下选项来配置您的特定需求的插件:
API | 说明 |
---|---|
key | 存储持久状态的键 (默认值:vuex) |
paths | 部分持续状态的任何路径的数组。如果没有路径给出,完整的状态是持久的 默认值:[]) |
reducer | 一个函数,将被调用来基于给定的路径持久化的状态 (默认值:都包含这些值) |
subscriber | 一个被调用来设置突变订阅的函数(默认值:store => handler => store.subscribe(handler)) |
storage | 而不是(或与) (默认值:getState和setState localStorage) |
getState | 将被调用以重新水化先前持久状态的函数 (默认值:storage) |
setState | 将被调用来保持给定状态的函数 storage(默认值: storage) |
filter | 将被调用来过滤将setState最终触发存储的任何突变的函数 (默认值:() => true) |
面试题1:在项目开发中使用vuex,一个组件调用vuex的数据,要把1修改成2,刷新页面数据又变成1了,怎么解决
【考点vuex的持久化存储】
面试题2:在某个组件中可以直接修改vuex中的状态吗?
可以的方式:在mutations里修改状态属性值,或在组件中直接修改vuex源头属性值this.
s
t
o
r
e
.
s
t
a
t
e
.
n
a
m
e
=
修改新数据不可以的方式:辅助函数是不可以修改的,是拷贝的
t
h
i
s
.
store.state.name =修改新数据 不可以的方式:辅助函数是不可以修改的,是拷贝的this.
store.state.name=修改新数据不可以的方式:辅助函数是不可以修改的,是拷贝的this.store.state.属性名给了vue对象可以直接this.name调用
面试题3:项目中vuex的getters属性在组件中被绑定到v-model会发生什么?
绑定v-model后,修改会报错,vuex是单向数据流
面试题4:vuex是单向数据流还是双向数据流?
vuex是单向数据流