likes
comments
collection
share

❤ pinia的使用(Vue3系统篇八Pinia大菠萝)❤ pinia的使用(Vue3系统篇八Pinia大菠萝) 1、P

作者站长头像
站长
· 阅读数 25

❤ pinia的使用(Vue3系统篇八Pinia大菠萝)

❤ pinia的使用(Vue3系统篇八Pinia大菠萝)❤ pinia的使用(Vue3系统篇八Pinia大菠萝) 1、P

1、Pinia简介

简介

Pinia是什么

Pinia 是一个为 Vue 3 设计的状态管理库,vue3建议使用pinia代替vuex进行状态管理。

Pinia旨在提供简洁、强大且易于使用的 API,用于在 Vue 应用程序中管理状态。它提供了一种基于 Vue 3 的响应式系统的方式来管理全局和局部的状态,同时也与 TypeScript 很好地集成在一起。

vue2的都知道vuex状态管理,所谓状态管理,简单来说就是一个存储数据的地方,存放在Vuex中的数据在各个组件中都能访问到,它是Vue生态中重要的组成部分。

而pinia同理也是起到状态管理的作用,但是它又不完全同于vuex,相比有如下优点:

  • Vue2和Vue3都支持,这让我们能很快上手

  • pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受待见,pinia直接抛弃。

  • pinia中action支持同步和异步

  • 良好的Typescript支持,Vue3推荐使用TS来编写

  • 无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,而pinia中每个store都是独立的,互相不影响。

  • 体积非常小,只有1KB左右。

  • pinia支持插件来扩展自身功能。

  • 支持服务端渲染。

Pinia 关键特点

  • 基于 Vue 3 的响应式系统:Pinia 利用了 Vue 3 的响应式系统,使得在应用中管理状态变得非常直观和高效。

  • 使用 Vue Composition API:Pinia 鼓励开发者使用 Vue 3 的 Composition API 来定义状态和逻辑,这使得代码更清晰和可维护。

  • 零依赖:Pinia 是一个轻量级的库,不依赖于其他状态管理库或类似的工具,使得它具有很高的灵活性。

  • 支持 TypeScript:Pinia 提供了对 TypeScript 的内置支持,包括类型推导、接口定义和类型安全等功能,这使得使用 TypeScript 进行开发变得更加顺畅。

  • 插件系统:Pinia 提供了插件系统,使得开发者可以根据项目的需要进行功能扩展和定制,例如增加中间件、开发工具等。

2、安装使用pinia

(1)安装和使用示范

yarn add pinia

3、基于Vue3如何使用pinia

(1)创建store

创建一个 store,例如 counterStore

// src/stores/counterStore.js
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
  },
});

在需要使用 store 的组件中导入并使用它

<template>
  <div>
    <p>Count: {{ counterStore.count }}</p>
    <button @click="counterStore.increment()">Increment</button>
    <button @click="counterStore.decrement()">Decrement</button>
  </div>
</template>

<script>
import { useCounterStore } from '@/stores/counterStore';

export default {
  setup() {
    const counterStore = useCounterStore();

    return { counterStore };
  },
};
</script>

(2)我的开源项目中详细使用

接下来我们就在开源项目Nexus之中把这部分的pinia使用尝试一下,并且利用pinia实现我们的登录部分

首先我们获取一下用户的权限,这部分我们需要用到一个东西,这个东西就是js-cookie,拿来存储我们的cookie信息

👉 在utils=>auth.js ,然后我们使用这个部分把token都放入Cookies部分

import Cookies from 'js-cookie'

const TokenKey = 'Admin-Token'

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}

👉 在store之中我们简单封装一下user的信息,用来存储关于用户的token信息

在store=> modules=> user.js 之中简单的封装一下我们的用户登录信息

这里我们主要是对于用户的账号密码进行传递,然后传递我们的token,默认带一张我们默认的头像部分

import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/assets/images/defaulte_avatar.png'

const useUserStore = defineStore(
  'user',
  {
    state: () => ({
      token: getToken(),
      name: '',
      avatar: '',
      roles: [],
      permissions: []
    }),
    actions: {
      // 登录
      login(userInfo) {
        const username = userInfo.username.trim()
        const password = userInfo.password
        const code = userInfo.code
        const uuid = userInfo.uuid
        return new Promise((resolve, reject) => {
          login(username, password, code, uuid).then(res => {
            setToken(res.token)
            this.token = res.token
            resolve()
          }).catch(error => {
            reject(error)
          })
        })
      },
      // 获取用户信息
      getInfo() {
        return new Promise((resolve, reject) => {
          getInfo().then(res => {
            const user = res.user
            const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;

            if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
              this.roles = res.roles
              this.permissions = res.permissions
            } else {
              this.roles = ['ROLE_DEFAULT']
            }
            this.name = user.userName
            this.avatar = avatar;
            resolve(res)
          }).catch(error => {
            reject(error)
          })
        })
      },
      // 退出系统
      logOut() {
        return new Promise((resolve, reject) => {
          logout(this.token).then(() => {
            this.token = ''
            this.roles = []
            this.permissions = []
            removeToken()
            resolve()
          }).catch(error => {
            reject(error)
          })
        })
      }
    }
  })

export default useUserStore

接下来完善我们的登录部分

import useUserStore from '@/store/modules/user'
const userStore = useUserStore()

// 处理表单提交的函数
const handleSubmit = async (event) => {
        event.preventDefault();
        // 在实际应用中,这里可以发送注册请求到服务器进行用户注册
        // 这里简单地假设密码和确认密码相同才能注册成功

        if (form.value.username === '' || form.value.password === '') {
            ElMessage.error('用户名和密码不能为空');
            return;
        }else{
            console.log(form.value, 'form.value');
            try {
                const res:any = await login(form.value);
                if(res.code==200){
                    ElMessage.success(res.message);

                     // 调用action的登录方法
                      userStore.login(loginForm.value).then(() => {
                        const query = route.query;
                        const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
                          if (cur !== "redirect") {
                            acc[cur] = query[cur];
                          }
                          return acc;
                        }, {});
                        router.push({ path: redirect.value || "/", query: otherQueryParams });
                      }).catch(() => {
                        loading.value = false;
                      });
                }else{
                   ElMessage.error(res.message);
                }
            } catch (error) {
                // console.log('获取数据详情失败,请重试!',error);
            } finally {
                // console.log('完!');
            }
        }
        return;
};

这里看看我们的登录接口部分

import request from '@/utils/request.js'
// 登录方法
export function login(username, password, code, uuid) {
  const data = {
    username,
    password,
    code,
    uuid
  }
  return request({
    url: '/api/login',
    headers: {
      isToken: false,
      repeatSubmit: false
    },
    method: 'post',
    data: data
  })
}

尝试调用一下看看

❤ pinia的使用(Vue3系统篇八Pinia大菠萝)❤ pinia的使用(Vue3系统篇八Pinia大菠萝) 1、P

这里记得完善一下我们token部分

import { getToken } from '@/utils/auth'

权限部分记得更改一下
if (whiteList.indexOf(to.path) !== -1||getToken()) {
    console.log('白名单或者token账号进入1!');
    next();
}

点击登录ok!

转载自:https://juejin.cn/post/7401824176229531682
评论
请登录