vue中新的状态管理器-pinia
背景
对于pinia的使用,可参考官方文档在这不做过多赘述。这边主要来讲讲pinia中 少用且好用的方法,为什么我们选择pinia而不用vuex
ps: 以下写法全部基于组合式API
使用方式:
先下载依赖
npm i pinia -s
在vue3中,main.js这么写
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
ps:就别考虑v2了吧,v2老老实实用vuex。
State
1、如何修改State
在传统的vuex中我们是不建议直接修改state的,而是要求我们通过mutation来修改state,但是在pinia中我们可以直接修改state。例如:
const store = useStore()
store.count++
如果我们需要在同一时间变更多个属性,可以通过$patch方法,例如:
store.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
2、如何订阅State
用来监听state是否发生变化,与watch相比,使用 $subscribe() 的好处是 subscriptions 在 patch 后只触发一次 。例如
cartStore.$subscribe((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// 和 cartStore.$id 一样
mutation.storeId // 'cart'
// 只有 mutation.type === 'patch object'的情况下才可用
mutation.payload // 传递给 cartStore.$patch() 的补丁对象。
// 每当状态发生变化时,将整个 state 持久化到本地存储。
localStorage.setItem('cart', JSON.stringify(state))
})
在组合式API中可以这么使用:
<script setup>
const someStore = useSomeStore()
// this subscription will be kept even after the component is unmounted
someStore.$subscribe(callback, { detached: true })
</script>
Getter
1、如何访问其他store 的 getter
想要使用另一个 store 的 getter 的话,那就直接在 getter 内使用就好,例如:
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data //otherStore.data 就是其他getter中的getter
},
},
})
2、如何像getter中传递参数
Getter 只是幕后的计算属性,所以不可以向它们传递任何参数。不过,你可以从 getter 返回一个函数,该函数可以接受任意参数,例如
export const useStore = defineStore('main', {
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})
组件中使用:
<script setup>
import { useUserListStore } from './store'
const userList = useUserListStore()
const { getUserById } = storeToRefs(userList)
// note you will have to use `getUserById.value` to access
// the function within the <script setup>
</script>
<template>
<p>User 2: {{ getUserById(2) }}</p>
</template>
ps: getter 将不再被缓存,它们只是一个被你调用的函数。不过,你可以在 getter 本身中缓存一些结果,虽然这种做法并不常见,但有证明表明它的性能会更好
Action
1、如何访问其他 store 的 action
举个:
import { useAuthStore } from './auth-store'
export const useSettingsStore = defineStore('settings', {
state: () => ({
preferences: null,
// ...
}),
actions: {
async fetchUserPreferences() {
const auth = useAuthStore()
if (auth.isAuthenticated) {
this.preferences = await fetchPreferences() //这行用了别的store的action
} else {
throw new Error('User must be authenticated')
}
},
},
})
2、订阅 action
你可以通过 store.$onAction() 来监听 action 和它们的结果。传递给它的回调函数会在 action 本身之前执行。after 表示在 promise 解决之后,允许你在 action 解决后执行一个一个回调函数。同样地,onError 允许你在 action 抛出错误或 reject 时执行一个回调函数。这些函数对于追踪运行时错误非常有用,类似于Vue docs 中的这个提示。
这里有一个例子,在运行 action 之前以及 action resolve/reject 之后打印日志记录。
const unsubscribe = someStore.$onAction(
({
name, // action 名称
store, // store 实例,类似 `someStore`
args, // 传递给 action 的参数数组
after, // 在 action 返回或解决后的钩子
onError, // action 抛出或拒绝的钩子
}) => {
// 为这个特定的 action 调用提供一个共享变量
const startTime = Date.now()
// 这将在执行 "store "的 action 之前触发。
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// 这将在 action 成功并完全运行后触发。
// 它等待着任何返回的 promise
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// 如果 action 抛出或返回一个拒绝的 promise,这将触发
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// 手动删除监听器
unsubscribe()
默认情况下,action 订阅器会被绑定到添加它们的组件上(如果 store 在组件的 setup() 内)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,请将 true 作为第二个参数传递给 action 订阅器,以便将其从当前组件中分离:
<script setup>
const someStore = useSomeStore()
// this subscription will be kept even after the component is unmounted
someStore.$onAction(callback, true)
</script>
ps:这部分没有亲自写过demo,直接照搬官方文档了
插件
1、介绍
由于有了底层 API 的支持,Pinia store 现在完全支持扩展。以下是你可以扩展的内容:
- 为 store 添加新的属性
- 定义 store 时增加新的选项
- 为 store 增加新的方法
- 包装现有的方法
- 改变甚至取消 action
- 实现副作用,如本地存储
- 仅应用插件于特定 store
插件是通过 pinia.use() 添加到 pinia 实例的。最简单的例子是通过返回一个对象将一个静态属性添加到所有 store。例如:
import { createPinia } from 'pinia'
// 创建的每个 store 中都会添加一个名为 `secret` 的属性。
// 在安装此插件后,插件可以保存在不同的文件中
function SecretPiniaPlugin() {
return { secret: 'the cake is a lie' }
}
const pinia = createPinia()
// 将该插件交给 Pinia
pinia.use(SecretPiniaPlugin)
// 在另一个文件中
const store = useStore()
store.secret // 'the cake is a lie'
这对添加全局对象很有用,如路由器、modal 或 toast 管理器。
2、如何拓展Store
为了能让devtools 自动追踪到,推荐使用下列方法:
pinia.use(({ store }) => {
store.hello = 'world'
})
3、添加的属性在store中是共享还是独享,可以如下配置:
const sharedRef = ref('shared')
pinia.use(({ store }) => {
// 每个 store 都有单独的 `hello` 属性
store.hello = ref('secret')
// 它会被自动解包
store.hello // 'secret'
// 所有的 store 都在共享 `shared` 属性的值
store.shared = sharedRef
store.shared // 'shared'
})
4、添加新的选项
在定义 store 时,可以创建新的选项,以便在插件中使用它们。例如,你可以创建一个 debounce 选项,允许你让任何 action 实现防抖。
defineStore('search', {
actions: {
searchContacts() {
// ...
},
},
// 这将在后面被一个插件读取
debounce: {
// 让 action searchContacts 防抖 300ms
searchContacts: 300,
},
})
然后,该插件可以读取该选项来包装 action,并替换原始 action:
// 使用任意防抖库
import debounce from 'lodash/debounce'
pinia.use(({ options, store }) => {
if (options.debounce) {
// 我们正在用新的 action 来覆盖这些 action
return Object.keys(options.debounce).reduce((debouncedActions, action) => {
debouncedActions[action] = debounce(
store[action],
options.debounce[action]
)
return debouncedActions
}, {})
}
})
注意,在使用 setup 语法时,自定义选项作为第 3 个参数传递:(前面举的例子都是 Option Store)
defineStore(
'search',
() => {
// ...
},
{
// 这将在后面被一个插件读取
debounce: {
// 让 action searchContacts 防抖 300ms
searchContacts: 300,
},
}
)
以下均为亲自写过demo,以后再补充吧
5、如何添加新的state
6、如何添加新的外部属性
7、在插件中调用 $subscribe
vue中新的状态管理器-pinia的更多相关文章
- vue状态管理器(用户登录简单应用)
技术点:通过vue状态管理器,对已经登录的用户显示不同的页面: 一 vue之状态管理器应用 主要用来存储cookie信息 与vue-cookies一起使用 安装:npm install vue-co ...
- 对于React各种状态管理器的解读
首先我们要先知道什么是状态管理器,这玩意是干啥的? 当我们在多个页面中使用到了相同的属性时就可以用到状态管理器,将这些状态存到外部的一个单独的文件中,不管在什么时候想使用都可以很方便的获取. reac ...
- VueX状态管理器 的应用
VueX状态管理器 cnpm i vuex axios -S 1 创建Vuex 仓库 import Vue from 'vue' import Vuex from 'vuex' vue.use(Vue ...
- vue中怎样实现 路由拦截器
vue中怎样实现 路由拦截器(当用户没有登录的时候,跳转到登录页面,已经登录的时候,不能跳转到登录页,除非后台token失效) 在 我们需要实现这样 一个功能,登录拦截 其实就是 路由拦截,首先在定义 ...
- VS2013中Nuget程序包管理器控制台使用入门(三)-项目实战(原创)
VS2013中Nuget程序包管理器控制台使用入门(三)-项目实战 1.给指定项目安装Newtonsoft.Json ,Version 4.5.11 PM> Install-Package Ne ...
- PHP V5.2 中的新增功能,第 1 部分: 使用新的内存管理器
PHP V5.2:开始 2006 年 11 月发布了 PHP V5.2,它包括许多新增功能和错误修正.它废止了 5.1 版并被推荐给所有 PHP V5 用户进行升级.我最喜欢的实验室环境 —— Win ...
- vue - 状态管理器 Vuex
状态管理 vuex是一个专门为vue.js设计的集中式状态管理架构.状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态.简单的说就是data中需要共用的属性.
- vue项目--vuex状态管理器
本文取之官网和其他文章结合自己的理解用简单化的语言表达.用于自己的笔记记录,也希望能帮到其他小伙伴理解,学习更多的前端知识. Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态 ...
- 轻量级状态管理库Pinia试吃
最近连续看了几个GitHub上的开源项目,里面都用到了 Pinia 这个状态管理库,于是研究了一下,发现确实是个好东西!那么,Pinia 的特点: 轻量化 -- Pinia 体积约1KB,十分轻巧 ...
- TensorFlow中的显存管理器——BFC Allocator
背景 作者:DeepLearningStack,阿里巴巴算法工程师,开源TensorFlow Contributor] 使用GPU训练时,一次训练任务无论是模型参数还是中间结果都需要占用大量显存.为了 ...
随机推荐
- app内打开外部第三方瞎下载链接
Q:我用cordova开发项目,想在app内跳转外部链接,安装了cordova-plugin-inappbrowser后确实可以跳转,但是跳转的页面有个按钮,原本点击会下载app,现在点击后毫无反应, ...
- 【APT】Hades APT组织针对乌克兰发起网络攻击事件分析
背景 Hades一个充满神秘色彩的APT组织,该组织因为2017年12月22日针对韩国平昌冬奥会的攻击活动被首次发现,后来卡巴斯基将该次事件的攻击组织命名为Hades.但是该攻击组织的归属问题却一直未 ...
- 关于ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x87\xA8\xF0\x9F...'报错的解决心得
昨天发现MySQL数据库执行发生了报错 ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x87\xA8\xF0\x9F...' 马上意识到应 ...
- macOS开发应用Sign(签名)和Notarizaiton(公证)
签名 可执行文件签名: codesign -f -s ${证书ID} --timestamp ${签名文件} .Pkg安装文件签名: productsign --timestamp --sign ${ ...
- uniapp中使用echarts点击图例与tooltips无反应
只需要在项目main.js文件中加上 window.wx = {} // echarts中tooltips点击无反应与点击图例无反应解决方法 即可
- curl 查看响应时间
curl -o /dev/null -s -w "time_namelookup:%{time_namelookup}\ntime_connect: %{time_connect}\ntim ...
- centos7.2 64位安装php7.2.12
1 安装php所需要的扩展 yum -y install libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel curl curl ...
- linux which及软硬链接使用
which查看系统命令位置,which vi /bin #放置系统一般命令 /sbin#放置系统管理相关命令 /user/bin /user/sbin 软链接 ln -s 源文件 链接文件 #1.如果 ...
- java mysql删除表中多余的重复记录(多个字段),只留有id最小的记录
mysql 删除表中多余的重复记录(多个字段),只留有id最小的记录 DELETE FROM 表1 f WHERE (f.字段1,f.字段2) IN ( SELECT 字段1,字段2 FROM 表1 ...
- 3-1 熟悉Hadoop及其操作
Hadoop最早起源于Nutch.Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取.索引.查询等功能,但随着抓取网页数量的增加,遇到了严重的可扩展性问题--如何解决数十亿网页的存储和索引 ...