简单了解一下pinia的结构
随着 Vue3 的正式转正,Pinia 也渐渐火了起来。所以要更新一下自己的知识树了。这里主要是看看新的状态是什么“形态”。
状态的容器还是“reactive”
- 按照官网教程,做一个简单的例子:
import { defineStore } from 'pinia'
export const usePersonStore = defineStore('objectTest', {
state: () => {
return {
name: 'jyk',
age: 18,
info: {
a1: '11',
a2: '22'
}
}
},
// 也可以这样定义状态
// state: () => ({ count: 0 })
actions: {
nameAction() {
this.name += '11'
}
},
getters: {
ageTest(state) {
// 会有代码自动补全!
return state.age += 100
}
}
})
- 组件里引用:
import { usePersonStore } from './object.js'
const xiaoming = usePersonStore()
console.log('\n xiaoming:')
console.dir(xiaoming)
console.log('counter - keys :')
console.log(Object.keys(xiaoming))
console.log('counter - for in :')
for (const key in xiaoming){
console.log(key)
}
{{xiaoming}}<br>
{{xiaoming.age}}<br>
<div v-for="(item, key, index) in xiaoming">
{{index}} -- {{key}}: {{item}}
</div>
- 然后看看效果
状态果然采用了 reactive,只是内部结构有点茫然,为啥是这样?
数据部分变成了 ref,错,是 toRef
一开始看,是把数据部分变成了 ref,但是仔细一看,原理是toRef。好吧,大概是为了保证响应性,自动结构了。只是还是挺无语的。
有图为证:
getter 变成了 computed
这个在意料之中,只是为啥和数据在一个“层级”上?
action 和数据是一级的。
action 还是函数的形式,只是,应该挂在“原型”上面吧,为啥又和数据挤在一起了?
状态是否需要遍历?
为啥这么在意 getter、action是不是和数据在一个“层级”上呢?因为我经常使用遍历的方式。
试了一下,果然都出来了。
如果在使用状态的时候,不需要用到遍历的话,可以跳过。
template 模板
整体使用
{{xiaoming}}
- 结果:
{ "$id": "objectTest", "name": "jyk", "age": 118, "info": { "a1": "11", "a2": "22" }, "ageTest": 118 }
- 讨论
出现了$id和数据成员,虽然没有出现 getter,但是被执行了一次。
所以age变成了“118”。
好吧,可能是我的用法不对。
分开使用
{{xiaoming.age}}<br><br>
不会触发getter,age还是 18
{{xiaoming.age}}<br><br>
{{xiaoming.ageTest}}<br><br>
两个都显示为 “118”
v-for
<div v-for="(item, key, index) in xiaoming">
{{index}} -- {{key}}: {{item}}
</div>
- 结果
0 -- $id: objectTest
1 -- $onAction: function () { [native code] }
2 -- $patch: function $patch(partialStateOrMutator) { let subscriptionMutation; isListening = false; if (true) { debuggerEvents = []; } if (typeof partialStateOrMutator === "function") { partialStateOrMutator(pinia.state.value[$id]); subscriptionMutation = { type: MutationType.patchFunction, storeId: $id, events: debuggerEvents }; } else { innerPatch(pinia.state.value[$id], partialStateOrMutator); subscriptionMutation = { type: MutationType.patchObject, payload: partialStateOrMutator, storeId: $id, events: debuggerEvents }; } isListening = true; triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); }
3 -- $reset: function $reset() { const newState = state ? state() : {}; this.$patch(($state) => { assign($state, newState); }); }
4 -- $subscribe: $subscribe(callback, options2 = {}) { if (typeof options2 === "boolean") { console.warn(`[\u{1F34D}]: store.$subscribe() no longer accepts a boolean as the 2nd parameter: Replace "store.$subscribe(fn, ${String(options2)})" with "store.$subscribe(fn, { detached: ${String(options2)} })". This will fail in production.`); options2 = { detached: options2 }; } const _removeSubscription = addSubscription(subscriptions, callback, options2.detached); const stopWatcher = scope.run(() => watch(() => pinia.state.value[$id], (state, oldState) => { if (isListening) { callback({ storeId: $id, type: MutationType.direct, events: debuggerEvents }, state); } }, assign({}, $subscribeOptions, options2))); const removeSubscription = () => { stopWatcher(); _removeSubscription(); }; return removeSubscription; }
5 -- $dispose: function $dispose() { scope.stop(); subscriptions = []; actionSubscriptions = []; pinia._s.delete($id); }
6 -- name: jyk
7 -- age: 118
8 -- info: { "a1": "11", "a2": "22" }
9 -- nameAction: function() { const _actionId = runningActionId; const trackedStore = new Proxy(store, { get(...args) { activeAction = _actionId; return Reflect.get(...args); }, set(...args) { activeAction = _actionId; return Reflect.set(...args); } }); return actions[actionName].apply(trackedStore, arguments); }
10 -- ageTest: 118
11 -- _hotUpdate: function(newStore) { originalHotUpdate.apply(this, arguments); patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions)); }
好吧,大概是我的使用方式不对。
for in
console.log('counter - for in :')
for (const key in xiaoming){
console.log(key)
}
- 结果
counter - for in :
pinia.vue:42 $id
pinia.vue:42 $onAction
pinia.vue:42 $patch
pinia.vue:42 $reset
pinia.vue:42 $subscribe
pinia.vue:42 $dispose
pinia.vue:42 name
pinia.vue:42 age
pinia.vue:42 info
pinia.vue:42 nameAction
pinia.vue:42 ageTest
pinia.vue:42 _hotUpdate
- 讨论
没有出现 action。出现了内部设置的成员,以及数据、getter。总之和我想的不一样。
Object.keys
console.log('counter - keys :')
console.log(Object.keys(xiaoming))
- 结果
counter - keys :
pinia.vue:38 (12) ["$id", "$onAction", "$patch", "$reset", "$subscribe", "$dispose", "name", "age", "info", "nameAction", "ageTest", "_hotUpdate"]
我想的到底是啥样的呢?
可以使用 class + reactive 实现一个充血实体类,比如这样:
import { computed, reactive } from 'vue'
// 充血实体类
class TestClass {
constructor (_info) {
// 设置属性,数组或者对象
this.name = 'jyk'
this.age = 18
this.info = {
a1: 'a1',
a2: 'a2'
}
}
// 通用赋值
$set(model, clear = false) {
if (clear) {
Object.keys(this).forEach(key => {
delete this[key]
})
}
Object.assign(this, model)
}
actionTest() {
this.age += 1
}
get getterTest() {
const tmp = computed(() => { return this.age + 100})
return tmp
}
}
export default function() {
const tmp = new TestClass()
return reactive(tmp)
}
在组件里使用:
const test2 = testClass()
console.log(test2)
console.log(test2.getterTest)
console.log('\n 遍历 Object.keys -----')
console.log(Object.keys(test2))
console.log('\n 遍历 for in -----')
for (const key in test2) {
console.log(key, ':', test2[key])
}
console.log('\n 遍历 for in 结束 -----')
获取实例后,套上 reactive 就可以获得响应性。
这样数据部分在第一层,其他各种方法都在“原型”里面,那么在 v-for、 Object.keys 和for...in的时候,只会出现数据部分,没有各种函数了。
整体结构也很简洁。
- 看看打印效果
遍历的情况也是挺好的。
简单了解一下pinia的结构的更多相关文章
- 简单的if多分支结构练习:用户录入 1-10的数字 , 1-7没奖品 , 8,9,10分别获得 3 2 1 等奖
package com.summer.cn; import java.util.Scanner; /** * @author Summer *简单的if多分支结构练习 *用户录入 1-10的数字 , ...
- 简单的Verilog测试模板结构
这里记录一下曾经用到的简单的测试模板,如下所示: //timescale `timescale 1ns/1ns module tb_module(); //the Internal motivatio ...
- C++编程练习(3)----“实现简单的栈的顺序存储结构“
栈(stack)是限定仅在表尾进行插入和删除操作的线性表. 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom). 栈又称为后进先出(Last In First Out)的线性表,简 ...
- 第5章 简单的C程序设计——循环结构程序设计
5.1 为什么需要循环控制 前面介绍了程序中常用到的顺序结构和选择结构,但是只有这两种结构是不够的,还需要用到循环结构(或称重复结构).因为在程序所处理的问题中常常遇到需要重复处理的问题. 循环结构和 ...
- celery 分布式异步任务框架(celery简单使用、celery多任务结构、celery定时任务、celery计划任务、celery在Django项目中使用Python脚本调用Django环境)
一.celery简介: Celery 是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务(async tas ...
- Entity Framework 6 Code First的简单使用和更新数据库结构
一.安装Entity Framework 6 在项目中右击选择“管理NuGet程序包",联机搜索Entity Framework,点击安装 二.配置数据库连接 在App.config中加入数 ...
- 第4章 简单的C程序设计——选择结构程序设计
在顺序结构中,各语句是按自上而下的顺序执行的,执行完上一个语句就自动执行下一个语句,是无条件的,不必作任何判断.实际上,很多情况下,需要根据某个条件是否满足来决定是否执行指定的操作任务,或者从给定的两 ...
- 简单介绍Collection框架的结构
Collection:List列表,Set集 Map:Hashtable,HashMap,TreeMap Collection 是单列集合 List 元素是有序的.可重复 有序的 collect ...
- 简单list转化为tree结构
1 @Override public List<Module> getTree() { List<Module> list = moduleMapper.queryList() ...
随机推荐
- 期中架构&防火墙¥四表五链
今日内容 架构图 包过滤防火墙 Iptables 新建虚拟机 内容详细 一.架构图 用户通过域名访问一个网站类比开车去饭店用餐 访问网站的流程 1.浏览器输入网站的域名(www.baidu.com), ...
- Solution -「多校联训」最小点覆盖
\(\mathcal{Description}\) Link. 求含有 \(n\) 个结点的所有有标号简单无向图中,最小点覆盖为 \(m\) 的图的数量的奇偶性.\(T\) 组数据. \( ...
- 暑假撸系统7- 熊孩子的捣乱!javascript保存前台状态!
系统大体框架已经搭的差不多了, 往下就是技术性的美化以及修补了,但这也是最最耗费时间的.在这个过程就发现了一个有意思的需求,这里把思路以及解决方案总结下. 因为做的是考试系统,不管是大或者小的考试,本 ...
- 【曹工杂谈】Mysql-Connector-Java时区问题的一点理解--写入数据库的时间总是晚13小时问题
背景 去年写了一篇"[曹工杂谈]Mysql客户端上,时间为啥和本地差了整整13个小时,就离谱",结果最近还真就用上了. 不是我用上,是组内一位同事,他也是这样:有个服务往数据库in ...
- [LeetCode]1342. 将数字变成 0 的操作次数
给你一个非负整数 num ,请你返回将它变成 0 所需要的步数. 如果当前数字是偶数,你需要把它除以 2 :否则,减去 1 . 示例 1: 输入:num = 14 输出:6 解释: 步骤 1) 14 ...
- PostgreSQL VACUUM 之深入浅出 (二)
AUTOVACUUM AUTOVACUUM 简介 PostgreSQL 提供了 AUTOVACUUM 的机制. autovacuum 不仅会自动进行 VACUUM,也会自动进行 ANALYZE,以分析 ...
- 渗透利器burp suite新版本v2020.9.1及v2020.8汉化版下载
Burp suite是一款抓包渗透必备软件.burp Suite是响当当的web应用程序渗透测试集成平台.从应用程序攻击表面的最初映射和分析,到寻找和利用安全漏洞等过程,所有工具为支持整体测试程序而无 ...
- MySQL日常笔记第二讲
今日内容概要 存储引擎 MySQL的数据类型 约束条件 今日内容详细 存储引擎 """ 针对不同的数据可以有不同的存储方式 存储引擎就相当于针对数据采用不同的存储方式 & ...
- git--撤销添加&放弃修改&代码冲突
git add . 后,撤销指定文件的add(还未提交): git reset HEAD 文件名 不保存本地改动,用远程代码覆盖: git reset --hard origin/dev 放弃工作区的 ...
- mysql全量备份与增量备份
mysql全量备份与增量备份 1.全量备份 全量备份就是把数据库中所有的数据进行备份. 备份所有库: mysqldump -uroot -p456 -S /data/3306/mysql.sock ...