vue2中的一些实战技巧之如何创建小型仓库store类似于vuex

小项目还用Vuex?vue2使用Vue.observable手写一个状态管理吧,vue3直接使用reactive手写store

为什么用这个,首先想要手写仓库,那么你使用的数据就必须是响应式数据,不然你改变了,页面却没有改。

Vue.observable和reactive都是把数据变成响应式的方法

故vue2的做法是

import Vue from 'vue'

export const store=Vue.observable({
    userInfo:null,
})
// 定义 mutations, 修改属性
export const mutation={
    setUserInfo(user){
        store.userInfo=user
    }
}
//actions处理异步
export const actions={
    async login(loginInfo){
        //登录处理...
    }
}

但是这样做有缺陷,如果外部直接改变store对象里面的数据而不通过mutations的方法改变,那写这个mutations又有什么意义呢

所以我们得思考怎么把返回的store对象是个只读属性不让外部进行修改,要修改值只能通过mutations里面的方法进行修改;

于是想到了es6的proxy代理对象来进行操作,返回的是一个代理对象,mutations修改的是这个js内部的对象,而不是直接修改store对象

修改后代码如下

    import Vue from 'vue'
    //初始化数据只能内部修改,外部只能通过mutations中的方法才能访问
    let _state = Vue.observable({
        userInfo: {
            name:{
                name1: '12323'
            },
        },
        testVal: {a: 1, b: 2}
    });
    
    /**
    * 使用proxy代理对象更好的监听数据变化
    * 设置只读对象
    * @type {{name: string}}
    */
    export const state = readonlyPoxy(_state);

    /**
    * 在mutations设置值的时候设置的是
    * @type {{setUserInfo(*): void}}
    */
    export const mutations = {
      setUserInfo(user) {
        _state.userInfo = user;
      },
      setTest(val){
        _state.testVal= val;
      }
    }
    
    /**
    * 创建只读的代理对象
    * @param needProxyObj 需要代理的对象
    * @param needProxyObj
    * @returns {boolean|any}
    */
    function readonlyPoxy(needProxyObj) {
      return  new Proxy(needProxyObj, {
          set(target, propertyKey, value) {
            console.error(`${propertyKey} is readonly `)
            return true
          },
          get(target, propertyKey) {
            if(target[propertyKey] instanceof Object){
                return  readonlyPoxy(target[propertyKey])
            }
            return Reflect.get(target, propertyKey);
          }
      })
    }

以上做法就相当于vue3中的readonly方法一样外部无法更改该值

vue3中的做法

import {reactive, readonly} from "vue";
import {getAbout} from "../api/about/index";
//数据初始化
const state = reactive({
    isLoading: false,
    userInfo: ""
})
//readonly保证该数据导出是只读数据
export const aboutInfo = readonly(state);
//做一些异步处理
export async function getAboutInfo() {
    //...
}

在组件中直接导出使用就行

<template>
   <div>
     {{ userInfo.name }}
   </div>
</template>
<script>
  import { state, mutations } from '../store'
  export default {
    computed: {
      userInfo() {
        return state.userInfo 
      }
   },
   created() {
     mutations.setUserInfo({
       name: '子君'
     })
   }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值