Vuex,Vuex-persistedstate和vue3-cookies
Vuex
Vuex是Vue框架生态的一环,用于实现全局数据状态的统一管理。
官方地址:https://next.vuex.vuejs.org/zh/index.html
cd ~/Desktop/luffycity/luffycityweb
# 在客户端项目根目录下执行安装命令
yarn add vuex@next
npm install vuex
开始使用
createStore 和 useStore 都是 Vuex 中用于创建和使用 Vuex Store 的方法,但它们的用法和实现方式略有不同。
createStore 是 Vuex 的工厂函数,用于创建一个新的 Vuex Store 实例。它通常在应用程序的入口处被调用,并且只会被调用一次。使用 createStore 方法创建的 Vuex Store 实例可以在整个应用程序中共享和使用。
- 根路径下创建vuex实例,在根路径创建store文件夹(非必要) 创建index.js
import { createStore } from 'vuex'
export default createStore({
state: {
log_user:""
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
- 在main.js导入并且使用use方法启用
import store from './store'
const app = createApp(App).use(store).use(router)
可以使用命令vue add vuex
实现上述步骤.
import { createApp } from 'vue'
import { createStore } from 'vuex'
// 创建一个新的 store 实例
const store = createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})
--------------vue2写法----------
export default createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})
useStore 是一个 Vue 3 中的 Composition API,用于在组件中访问 Vuex Store 实例。使用 useStore 方法可以直接从组件中访问已经创建的 Vuex Store 实例,而不需要在每个组件中都导入和创建一个新的 Vuex Store 实例。
import { useStore } from "vuex";
export default {
setup() {
const store = useStore();
const increment = () => {
store.commit("increment");
};
return {
increment
};
}
};
----------vue3语法--------
<script setup>
const store = useStore()
store.commit("increment");
</script>
核心的五个属性
state 负责记录全局的静态变量,
getter 就像 Vue 组件中的计算属性,用于从 State 中派生出新的状态,避免在组件中重复编写相同逻辑。
mutations 唯一修改 State 的方式: Mutations 是 Vuex 中唯一允许修改 State 的地方,并且必须是同步函数。
Actions 用于处理异步操作,例如网络请求、定时器等,并将最终结果提交给 Mutations 更新 State。组合多个 Mutations: Actions 可以组合多个 Mutations,实现更复杂的状态变更逻辑。
Mutations 和 Actions 本身的设计目标并不是为了返回值,而是为了修改状态或处理异步操作。所以他们不直接返回值,而是将值存放到state中
state
该属性等同于vue中的data属性,用来存储全局的对象
const state={
user:{name:"alex"}
}
getters
对state中的属性进行二次计算,但是不能修改state中的值,
const state={
user:{name:"alex"}
}
const getters={
getUser(state){
return state.user.name+"x"
}
}
获取值的时候let ret = store.getters.getUser
要注意getters里面的都是属性,所以store.getters.getUser()这种调用方式是错误的
mutations 相当于vue中的methos
唯一的修改state中值的方法,同步阻塞
但是mutations是无法获取返回值的
const state={
user:{name:"alex"}
}
const mutations={
updateUser(state,new_user){
state.user = new_user
//mutations无法返回值,所以updateUser这个方法获取不到111
return 111
}
}
actions
异步阻塞,也可以修改state值,但是底层还是调用mutations,而不是直接变更。
并且调用mutations还要通过commit方法,传入函数名进行调用
const state={
user:{name:"alex"}
}
const mutations={
updateUser(state,new_user){
state.user = new_user
}
const actions={
// 和mutations不同,不用传state,可以通过上下文context,
// 这个context 可以获取整个代码文件中的属性和方法
// 调mutations的方法通过commit调用,而调用actions的要用dispatch调用
asyncUpdateUser(context,new_user){ //这个context参数可以不显示传
context.commit("updateUser",new_user)
}
}
}
// 调用方式 store.dispatch("asyncUpdateUser","newuser")
Module
用来对vuex下面进行模块化切分组合,看下官网例子https://vuex.vuejs.org/zh/guide/modules.html
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
登录小案例
父组件 home.vue
子组件 login.vue
vuex全局的代码 login.js
子组件中输入用户名,如果是aa或者bb则登录成功,成功后的用户显示在父组件的标签中作为全局显示.
未登录成功则显示未登录
main.js代码
import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import store from './components/login.js'
createApp(App).use(store).mount('#app')
home.vue代码
<script setup>
import { ref } from 'vue'
import login from "./login.vue"
import store from "./login.js"
</script>
<template>
<p>用户信息>>{{store.state.user}}</p>
<login></login>
</template>
<style scoped>
</style>
login.vue代码
<script setup>
import { ref,reactive } from 'vue'
import store from "./login.js"
const user =ref("")
// 同步阻塞 执行mutations
const submit =()=>{
if (user.value==="aa"){
store.commit("login_success",user)
}
}
// 异步调用 执行actions
const submit2 =()=>{
if (user.value==="bb"){
store.dispatch("asyncUpdateUser",user)
}
}
</script>
<template>
<label>用户登录</label>
<!-- <input type="" name="" v-model="userinfo.user"> -->
<input type="" name="" v-model="user">
<button @click="submit">commit同步阻塞</button>
<button @click="submit2">action异步阻塞</button>
</template>
login.js代码
import { createStore } from 'vuex'
export default createStore({
// 也可以用函数形式写
// state(){
// // state:{
// return{user:"未登录"}
// // }
// },
state:{user:"未登录"},
mutations:{
login_success(state,newuser){
state.user = newuser
console.log(state.user)
}
},
actions:{
// 和mutations不同,不用传state,可以通过上下文context,
// 这个context 可以获取整个代码文件中的属性和方法
// 调mutations的方法通过commit调用,而调用actions的要用dispatch调用
asyncUpdateUser(context,new_user){ //这个context参数可以不显示传
context.commit("login_success",new_user)
}
}
})
vue3-cookies
cookie的第三方组件,官网地址 https://github.com/KanHarI/vue3-cookies
注意:无法获取httponly=True的值
安装方式
npm install vue3-cookies --save
OR
yarn add vue3-cookies
引入使用的2种方式
方式1:
main.js配置
// 引入VueCookies
import VueCookies from 'vue3-cookies'
const app = createApp(App)
// use一下VueCookies
app.use(VueCookies)
//在各个组件中使用
import {getCurrentInstance} from 'vue'
const {proxy} = getCurrentInstance()
// 设置cookie
proxy.$cookies.set('k1', 'v1', '1h')
方式2:
//main.js中代码不变
import VueCookies from 'vue3-cookies'
const app = createApp(App)
// use一下VueCookies
app.use(VueCookies)
//各个组件使用
// 引入方式2
import { useCookies } from "vue3-cookies";
const { cookies } = useCookies();
// 设置cookie
cookies.set('k2', 'v2', '1h')
几个常用的方法介绍
// 设置cookie
cookies.set('k2', 'v2', '1h')
// 获取
console.log(cookies.get('k2')) // v2
// 删除指定key
cookies.remove("k2")
// 判断某个key是否存在,返回true或者false
console.log(cookies.isKey("k2"))
// 获取所有的key的数组
console.log(cookies.keys()) // ['_ga', 'csrftoken', 'k1', 'k3', 'k4', 'k5']
//就能按照索引取值
console.log(cookies.keys()[0]) // _ga
// 想要获取值,需要自己处理,这里没有提供方法
let obj = {};
for (let key of cookies.keys()){
obj[key] = cookies.get(key)
}
console.log(obj)
vuex-persistedstate
因为vuex默认是保存数据在内存中的,所以基于浏览器开发的网页,如果在F5刷新网页时会存在数据丢失的情况。所以我们可以把store数据永久存储到localStorage中。这里就需要使用插件vuex-persistedstate来实现。
在前端项目的根目录下执行安装命令
cd ~/Desktop/luffycity/luffycityweb
yarn add vuex-persistedstate
npm install vuex-persistedstate --save
在vuex的store/index.js文件中导入此插件。
import {createStore} from "vuex"
import createPersistedState from "vuex-persistedstate"
// 实例化一个vuex存储库
export default createStore({
// 调用永久存储vuex数据的插件,localstorage里会多一个名叫vuex的Key,里面就是vuex的数据
plugins: [createPersistedState()],
state(){ // 相当于组件中的data,用于保存全局状态数据
return {
user: {}
}
},
getters: {
getUserInfo(state){
// 从jwt的载荷中提取用户信息
let now = parseInt( (new Date() - 0) / 1000 );
if(state.user.exp === undefined) {
// 没登录
state.user = {}
localStorage.token = null;
sessionStorage.token = null;
return null
}
if(parseInt(state.user.exp) < now) {
// 过期处理
state.user = {}
localStorage.token = null;
sessionStorage.token = null;
return null
}
return state.user;
}
},
mutations: { // 相当于组件中的methods,用于操作state全局数据
login(state, payload){
state.user = payload; // state.user 就是上面声明的user
}
}
})
完成了登录功能以后,我们要防止用户FQ访问需要认证身份的页面时,可以基于vue-router的导航守卫来完成。