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 实例可以在整个应用程序中共享和使用。

  1. 根路径下创建vuex实例,在根路径创建store文件夹(非必要) 创建index.js
import { createStore } from 'vuex'

export default createStore({
  state: {
    log_user:""
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})
  1. 在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的导航守卫来完成。

posted @ 2023-06-10 19:50  零哭谷  阅读(282)  评论(0编辑  收藏  举报