vue3: 3.如何利用 effectScope 自己实现一个青铜版pinia 一 actions篇

编程入门 行业动态 更新时间:2024-10-28 20:31:05

vue3: 3.如何利用 effectScope 自己实现一个<a href=https://www.elefans.com/category/jswz/34/1760777.html style=青铜版pinia 一 actions篇"/>

vue3: 3.如何利用 effectScope 自己实现一个青铜版pinia 一 actions篇

vue3: 如何利用 effectScope 自己实现一个青铜版pinia - actions篇

上一篇我们实现了状态管理仓库的 getters, 但是实际应用中并不推荐我们直接更改store.state的值,所以我们需要实现一个actions来更新我们的状态

actions 的实现原理非常简单,只需要把action暴露出去给组件使用就行,并且actions支持同步和异步

接着上代码:

依然是创建一个store对象,store新增一个actions对象
该对象只需要在useStore的时候暴露给组件使用的store.state上就行
我们在执行useStore的时候将getters、store.actions 合并到store.state 就能实现
然后我们可以直接通过store.state[actionsName] 访问对应的actions

const store = {state: {val: 0},getters: {},actions: {add (value) {this.val += value},remove (value) {this.val -= value}},useStore () {const setUp = () => {if (!Vue.isReactive(this.state)) {// 以下的操作只需要执行一次// 因为执行setup做响应式依赖收集的时候会在每个组件执行,访问的是同一个state,该state 对象的代理实现只需要第一次就够了this.state = Vue.reactive(this.state)const _this = this// 将this.getters里面的函数取出,存到 getters 这个对象里面的值变为具有computed 计算属性的一个对象const getters = Object.keys(_this.getters || {}).reduce(function (conmputedGetters, name) {// 利用computed 计算this.getters里面的值, 并记录下来conmputedGetters[name] = Vueputed(() => {return _this.getters[name].call(_this.state, _this.state)})return conmputedGetters}, {})// 直接将 this.actions 合并到 this.state 上就好了, action 函数里面可以直接通过 this 访问 state 对象Object.assign(this.state, getters, this.actions)}}const scope = Vue.effectScope()scope.run(setUp)return this.state}
}

然后我们创建两个子组件
不通过直接更改store.state的值去更新组件
而是通过store的 actions 去更新组件

<body><script src=".2.37/vue.global.min.js"integrity="sha512-rCO3ZZnxh9j/Y725Iq2Cqr2lc9fi83zVeN3PFTUosktylZsCFjD13PDbKrzKjKO/idjM4KlMQC52AsoGFTAe6A=="crossorigin="anonymous"referrerpolicy="no-referrer"></script><div id="app"></div><script>const store = {state: {val: 0},getters: {},actions: {add (value) {this.val += value},remove (value) {this.val -= value}},useStore () {const setUp = () => {if (!Vue.isReactive(this.state)) {// 以下的操作只需要执行一次// 因为执行setup做响应式依赖收集的时候会在每个组件执行,访问的是同一个state,该state 对象的代理实现只需要第一次就够了this.state = Vue.reactive(this.state)const _this = this// 将this.getters里面的函数取出,存到 getters 这个对象里面的值变为具有computed 计算属性的一个对象const getters = Object.keys(_this.getters || {}).reduce(function (conmputedGetters, name) {// 利用computed 计算this.getters里面的值, 并记录下来conmputedGetters[name] = Vueputed(() => {return _this.getters[name].call(_this.state, _this.state)})return conmputedGetters}, {})// 直接将 this.actions 合并到 this.state 上就好了, action 函数里面可以直接通过 this 访问 state 对象Object.assign(this.state, getters, this.actions)}}const scope = Vue.effectScope()scope.run(() => {// 执行setup函数,收集响应式依赖return setUp()})return this.state}}// 子组件1const childrenOne = Vue.defineComponent({name: 'children-one',setup () {// 为什么要执行useStore,因为要通过 useStore 内的setup 函数为该组件提供响应式的依赖搜集// storeA 已经是一个包含getters的最基本的状态管理对象了// 不过我们一般不建议直接修改store的值,后续会提供actions去帮助大家更改state的值const storeA = store.useStore()const add = () => {storeA.add(1)}return {add,storeA}},template: `<div><h3>children-one</h3><button @click="add">children-one add</button><br/><span>val : {{storeA.val}}</span></div>`})// 子组件2const childrenTwo = Vue.defineComponent({name: 'children-two',setup () {const storeB = store.useStore()const remove = () => {storeB.remove(2)}return {remove,storeB}},template: `<div><h3>children-two</h3><button @click="remove">children-two remove</button><br/><span>val : {{storeB.val}}</span><br/></div>`})const app = Vue.createApp({name: 'app',components: {'children-one': childrenOne,'children-two': childrenTwo,},template: `<div class='ass' ><children-one /><children-two /></div>`})app.mount('#app')</script>
</body>

我们来看下效果:

这样一个我们就实现了 actions

到这里一个基础的青铜版pinia基本就差不多实现了,基本实现原理就是这么多
要想达到和pinia一样的效果,比如多模块等其他优秀特性
我们还需要调整store的生成方式和数据组成等比较繁杂的内容,我们只是简单了解pinia实现原理
其他的就不深入研究了,有兴趣的小伙伴可以自己研究改造一下

更多推荐

vue3: 3.如何利用 effectScope 自己实现一个青铜版pinia 一 actions篇

本文发布于:2024-02-11 15:16:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1681678.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:青铜   effectScope   actions   pinia

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!