当前位置: 首页 > news >正文

南京网站设计建设网站服务器

南京网站设计建设,网站服务器,域名做违法网站,江苏建设装饰集团有限公司状态管理Pinia使用详解(带你从入门到入神) 序: ​ 如果你之前使用过 vuex 进行状态管理的话,那么 pinia 就是一个类似的插件。它是最新一代的轻量级状态管理插件。你可以通过defineStore来简单创建一个存储管理。 ​ 与 vuex 相比,pinia 提…

状态管理Pinia使用详解(带你从入门到入神)

序:

​ 如果你之前使用过 vuex 进行状态管理的话,那么 pinia 就是一个类似的插件。它是最新一代的轻量级状态管理插件。你可以通过defineStore来简单创建一个存储管理。

​ 与 vuex 相比,pinia 提供了一个更简单的 API,具有更少的操作,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。

特点:

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

pinia官网

1.安装

yarn add pinianpm install pinia

2.引入注册Vue3

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

3.初始化仓库Store

3.1.新建一个文件夹Store

3.2.新建文件[name].ts

3.3.定义仓库Store

3.4.我们需要知道存储是使用定义的defineStore(),并且它需要一个唯一的名称,作为第一个参数传递

新建文件store-namespace/index.ts

export const enum Names {Test = 'TEST'
}

store 引入

import { defineStore } from 'pinia'
import { Names } from './store-namespace'export const useTestStore = defineStore(Names.Test, {})

这个名称,也称为id,是必要的,Pania 使用它来将商店连接到 devtools。将返回的函数命名为*use…*是可组合项之间的约定,以使其使用习惯。

3.5.定义值

State 箭头函数 返回一个对象 在对象里面定义值

import { defineStore } from 'pinia'
import { Names } from './store-namespce'export const useTestStore = defineStore(Names.Test, {state:()=>{return {current:1}},//类似于computed 可以帮我们去修饰我们的值getters:{},//可以操作异步 和 同步提交stateactions:{}
})

4.State

4.1.State 是允许直接修改值的

例如current++

<template><div><button @click="Add">+</button><div>{{Test.current}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.current++
}</script><style></style>

4.2.批量修改State的值

<template><div><button @click="Add">+</button><div>{{Test.current}}</div><div>{{Test.age}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.$patch({current:200,age:300})
}</script><style></style>

4.3.批量修改函数形式

推荐使用函数形式 可以自定义修改逻辑

<template><div><button @click="Add">+</button><div>{{Test.current}}</div><div>{{Test.age}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.$patch((state)=>{state.current++;state.age = 40})
}</script><style></style>

4.4.通过原始对象修改整个实例

$state您可以通过将store的属性设置为新对象来替换store的整个状态

缺点就是必须修改整个对象的所有属性

<template><div><button @click="Add">+</button><div>{{Test.current}}</div><div>{{Test.age}}</div></div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.$state = {current:10,age:30}    
}</script><style></style>

4.5.通过actions修改

定义Actions

在actions 中直接使用this就可以指到state里面的值

import { defineStore } from 'pinia';
import { store } from '@/store';export const useModalStore = defineStore({id: 'modal',  // 唯一的idstate: () => ({modals: []}),actions: {add(modal) {this.modals.push(modal)},remove(id) {let index = this.modals.findIndex(v => v.id == id)if (index > -1) {this.modals.splice(index, 1);}}},
});// 在组件setup函数外使用
export function useModalStoreWithOut() {return useModalStore(store);
}

使用方法直接在实例调用

<script setup lang='ts'>
iimport { useModalStoreWithOut } from '@/store/modules/modal.store';const modalStore = useModalStoreWithOut();modalStore.remove({ id });
modalStore.add({ modal });</script><style></style>

5.解构store

在Pinia里,是不允许直接解构是会失去响应性的

const Test = useTestStore()const { current, name } = Testconsole.log(current, name);

差异对比

修改Test current 解构完之后的数据不会变

而源数据是会变的

<template><div>origin value {{Test.current}}</div><div>pinia:{{ current }}--{{ name }}change :<button @click="change">change</button></div>
</template><script setup lang='ts'>
import { useTestStore } from './store'const Test = useTestStore()const change = () => {Test.current++
}const { current, name } = Testconsole.log(current, name);</script><style>
</style>

解决方案可以使用 storeToRefs

import { storeToRefs } from 'pinia'const Test = useTestStore()const { current, name } = storeToRefs(Test)

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

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

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

6.Actions,getters

6.1.Actions(支持同步异步)

6.1.1.同步可直接调用

import { defineStore } from 'pinia'
import { Names } from './store-naspace'
export const useTestStore = defineStore(Names.TEST, {state: () => ({counter: 0,}),actions: {increment() {this.counter++},randomizeCounter() {this.counter = Math.round(100 * Math.random())},},
})
<template><div><button @click="Add">+</button><div>{{Test.counter}}</div>    </div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.randomizeCounter()
}</script><style></style>

6.1.2.异步 可以结合async await 修饰

import { defineStore } from 'pinia'
import { Names } from './store-naspace'type Result = {name: stringisChu: boolean
}const Login = (): Promise<Result> => {return new Promise((resolve) => {setTimeout(() => {resolve({name: '小满',isChu: true})}, 3000)})
}export const useTestStore = defineStore(Names.TEST, {state: () => ({user: <Result>{},name: "123"}),actions: {async getLoginInfo() {const result = await Login()this.user = result;}},
})
<template><div><button @click="Add">test</button><div>{{Test.user}}</div>    </div>
</template><script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {Test.getLoginInfo()
}</script><style></style>

6.1.3.多个action互相调用getLoginInfo setName

    state: () => ({user: <Result>{},name: "default"}),actions: {async getLoginInfo() {const result = await Login()this.user = result;this.setName(result.name)},setName (name:string) {this.name = name;}},

6.2.getters

6.2.1.使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state

主要作用类似于computed 数据修饰并且有缓存

    getters:{newPrice:(state)=>  `$${state.user.price}`},

6.2.2.普通函数形式可以使用this

    getters:{newCurrent ():number {return ++this.current}},

6.2.3.getters 互相调用

    getters:{newCurrent ():number | string {return ++this.current + this.newName},newName ():string {return `$-${this.name}`}},

pinia插件

pinia和 vuex 都有一个通病 页面刷新状态会丢失

我们可以写一个pinia 插件缓存他的值

const __piniaKey = '__PINIAKEY__'
//定义兜底变量type Options = {key?:string
}
//定义入参类型//将数据存在本地
const setStorage = (key: string, value: any): void => {localStorage.setItem(key, JSON.stringify(value))}//存缓存中读取
const getStorage = (key: string) => {return (localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {})}//利用函数柯丽华接受用户入参
const piniaPlugin = (options: Options) => {//将函数返回给pinia  让pinia  调用 注入 context
return (context: PiniaPluginContext) => {const { store } = context;const data = getStorage(`${options?.key ?? __piniaKey}-${store.$id}`)store.$subscribe(() => {setStorage(`${options?.key ?? __piniaKey}-${store.$id}`, toRaw(store.$state));})//返回值覆盖pinia 原始值
return {...data}}}//初始化pinia
const pinia = createPinia()//注册pinia 插件
pinia.use(piniaPlugin({key: "pinia"}))
http://www.mnyf.cn/news/47883.html

相关文章:

  • 南昌媒体网站建设口碑推荐下载百度app并安装
  • 网站建设兼职在哪找2024年小学生简短小新闻
  • 学校网站集群建设做广告推广哪个平台好
  • 做网站前台和后台是什么seo关键词快速排名前三位
  • 温州大型网站建设百度推广方式有哪些
  • 如何自己做优惠卷网站百度中心
  • 专业做招聘的网站自助建站平台源码
  • 虚拟主机发布网站吗株洲seo
  • 网站备案中查询花西子网络营销策划方案
  • 公司牌子设计图微信小程序排名关键词优化
  • 唐山路南网站建设正规排名网站推广公司
  • 宁波网站制作 收费标准怎么样自己创建网站
  • 这么攻击网站百度收录排名查询
  • 做网站的会什么比百度好用的搜索引擎
  • 微信扫一扫抽红包在哪里做网站分销平台
  • 在线数据分析网站持啊传媒企业推广
  • 潍坊哪个网站建设公司好最新新闻热点事件2023
  • 宝鸡市做网站的公司有哪些网络销售技巧和话术
  • 深圳宝安做网站如何做网站推广的策略
  • 临沂网站建设电话智能识别图片
  • asp网站后台密码破解搜索广告是什么
  • 可以免费做网站吗百度竞价推广课程
  • 怎样做网站平台赚钱全网整合营销公司
  • 北京宏福建设有限公司网站软件定制开发公司
  • 导航栏网站建站关键词分析软件
  • 深圳网站建设公司有哪些内容自己搜20条优化措施
  • 直播网站可以做毕设吗云优化
  • 网站建设属于什么职能推广之家app
  • 用java做网站验证码怎么写免费建站软件
  • 小规模网站开发税率网上哪里接app推广单