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"},
todos: [
{ id: 1, text: 'Learn Vue', done: true },
{ id: 2, text: 'Learn Vuex', done: false }
]
}
const getters={
getUser(state){
return state.user.name+"x"
},
doneTodos: state => {
return state.todos.filter(todo => todo.done);
}
}
获取值的时候let ret = store.getters.getUser
let ret2 = store.getters.doneTodos
要注意getters里面的都是属性,所以store.getters.getUser()这种调用方式是错误的,正确是使用store.getters.getUser
这里还有个细节要注意:
- 如果函数体内要使用state里面的变量 只需要显示传入,但是在调用的时候是传参是可以省略的,这些工作都是vuex自动会做的
- 我们在这种写法上可以添加闭包的高阶函数写法
export default createStore({
state: {
permission_remark:["漏洞风险编辑","漏洞风险删除"] //和token一起返回 这里返回的是权限的中文备注,用来在每个页面通过判断是否有中文权限而决定是否显示编辑删除按钮
},
getters: {
hasPermission: (state) => (remark) => {
return state.permission_remark.includes(remark);
}
},
})
这种双箭头函数解析如下
let functionname = (name) => (age) => {
console.log('这是一个嵌套的箭头函数');
};
完整的写法如下:
let functionname = (name) => {
return (age) => {
console.log(`Name: ${name}, Age: ${age}`);
console.log('这是一个嵌套的箭头函数');
};
};
这种函数的调用方式就是functionname(name)(age),在vuex的getters中functionname(name)就是可以省略的部分.
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方法,传入函数名进行调用
新版本笔记
- actions底层也是调用mutations,因此它可以使用commit方法调用mutations里的函数
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
- 我们可以用结构的语法来写
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment ({ commit }) {
commit('increment')
}
}
- 额外传参 我们来设定一个场景在action中实现一个注销的函数,里面实现2个功能,1个是路由切到登录页面,第2个就是显示一个自定义的消息提示
//在vuex中的代码
actions: {
logoff(context, payload) {
console.log("logoff");
localStorage.removeItem("token");
// 使用 context就是Vuex 的上下文对象 context,这个对象包含了很多实用的属性和方法,如 commit、dispatch、state 等。如果调用commit 就是context.commit
// 如果调用store.state中的值 则是 context.state
//context.commit('clearAuthInfo');
// 使用 payload 中的数据
payload.router.push({ name: "login" });
ElMessage({
message: payload.message,
type: 'error',
plain: true,
grouping: true,
duration: 4000
});
}
}
//组件调用
<template>
<div>
<!-- 其他组件内容 -->
<el-dropdown-item @click="logoff('成功退出')">注销</el-dropdown-item>
</div>
</template>
<script>
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
const router = useRouter();
const logoff = (message) => {
store.dispatch('logoff', { router, message });
};
return {
logoff
};
}
}
</script>
// 当我们采用结构形式编写
actions: {
logoff({ commit,state }, { router, message }) {
console.log("logoff");
localStorage.removeItem("token");
// commit('clearAuthInfo'); // 清除状态的一些变化
// 路由跳转到登录页面
router.push({ name: "login" });
// 展示退出提示信息
ElMessage({
message: message,
type: 'error',
plain: true,
grouping: true,
duration: 4000
});
},
},
//组件代码
<template>
<div>
<!-- 其他内容 -->
<el-dropdown-item @click="logoff('成功退出')">注销</el-dropdown-item>
</div>
</template>
<script>
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
const router = useRouter();
const logoff = (message) => {
store.dispatch('logoff', { router, message });
};
return {
logoff
};
}
}
</script>
老版本笔记
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的导航守卫来完成。
本文作者:零哭谷
本文链接:https://www.cnblogs.com/Young-shi/p/17471477.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?