vue3 + vite + ts + setup , 第十四练 vue3 中使用pinia (一) 修改state的值,使用storeToRefs解构响应性

2023-05-16

Pinia.js 有如下特点:

  1. 完整的 ts 的支持;
  2. 足够轻量,压缩后的体积只有1kb左右;
  3. 去除 mutations,只有 state,getters,actions;
  4. actions 支持同步和异步;
  5. 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
  6. 无需手动添加 store,store 一旦创建便会自动添加;
  7. 支持Vue3 和 Vue2

官方文档:Piniaicon-default.png?t=M666https://pinia.vuejs.org/

1、在vue3项目中安装

yarn add pinia
 
npm install pinia

2、vue3中引入使用

import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
 
const store = createPinia()
let app = createApp(App)
 
 
app.use(store)
 
app.mount('#app')

3、在vue2中使用

import { createPinia, PiniaVuePlugin } from 'pinia'
 
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
 
new Vue({
  el: '#app',
  // other options...
  // ...
  // note the same `pinia` instance can be used across multiple Vue apps on
  // the same page
  pinia,
})

在项目中如何使用

1、在src新建store目录,src/store/user.ts

      创建Names.ts用来定义仓库的name 也是id 唯一

names.ts

export const enum Names {
  User = "USER",
  Test = "TEST"
}

user.ts 

import { defineStore } from 'pinia'
import { Names } from "./Name"

// name 名称 也是id,是必要的 Pania 使用它来将商店连接到 devtools。将返回的函数命名为use...是可组合项之间的约定,以使其使用习惯。
export const useUserStore = defineStore(Names.User, {
  // state 箭头函数 返回一个对象在对象里面定义
  state: () => {
    return {
      userName: '张三三',
      age: 18
    }
  },
  // computed 修饰一些值
  getters: {

  },
  // methods 可以做同步 异步都可以  提交state
  actions: {
    setAge(num: number) {
      this.age = num
    }
  }
})

2、在组件中使用,修改state的5中方法

usePinia.vue

<template>
  <div>
    <h1>我是pinia:{{ userStore.userName }}--{{ userStore.age }}</h1>
    <button @click="changeState">change-state</button>
  </div>
</template>

<script setup lang="ts">
import { useUserStore } from '../../Store/user'
// 使用pinia
const userStore = useUserStore()
// 修改state的5中方法
/* //方式一:userStore.age++

      let changeState = () => {
        userStore.age++
      }
*/


/* //方法二:userStore.$patch({userName: '我是沙雕',age: 58})

    let changeState = () => {
      userStore.$patch({ userName: '我是沙雕', age: 58 })
    }
 */

/* // 方法三:工厂函数方式

let changeState = () => {
  userStore.$patch((state) => {
    // 处理逻辑后修改
    state.age++
    if (userStore.age > 20) {
      state.userName = '你是一个美女'
    }
    state.age = userStore.age
  })
}
 */

/* // 方案四:$state您可以通过将store的属性设置为新对象来替换store的整个状态 缺点就是必须修改整个对象的所有属性
   // 一般使用不多
let changeState = () => {
  userStore.$state = {
    age: 388,
    userName: '修改了张三'
  }
}
 */

// 方案五: 定义Actions 在actions 中直接使用this就可以指到state里面的值
let changeState = () => {
  userStore.setAge(789)
}

</script>

<style scoped>
</style>

3、pinia直接解构会导致失去响应性的

let { userName, age } = userStore


let changeState = () => {
  userStore.age++
}

console.log(userName,age)

修改userStore.age的值,元数据会改变的,但是解构的userName,age不会改变,由于解构失去了响应性

4、可以使用storeToRefs 解决由于解构失去的响应性

// 使用 storeToRefs 可以解决因为解构导致失去的响应性
let { userName, age } = storeToRefs(userStore)
console.log("解构", userName, age)
let changeState = () => {
  userStore.age++
}

其原理跟toRefs 一样的给里面的数据包裹一层toref

源码 通过toRaw使store变回原始数据防止重复代理

循环store 通过 isRef isReactive 判断 如果是响应式对象直接拷贝一份给refs 对象 将其原始对象包裹toRef 使其变为响应式对象 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3 + vite + ts + setup , 第十四练 vue3 中使用pinia (一) 修改state的值,使用storeToRefs解构响应性 的相关文章

随机推荐