Vue3 的轻量级的状态管理。
简称:nf-state
基于 reactive 完全发挥 composition API 的特点,简单快捷,好用。
- 全局状态,用法和 Vuex 类似。
- 只读状态,只有指定位置才可以改变,其他组件只能读取,更安全。
- 跟踪状态,可以跟踪变更情况,记录状态变化的时间、函数、组件、代码位置、属性名、原值、新值,支持嵌套属性。
- 初始化,可以对全局状态进行初始化赋值。
只包含状态 state,不包含 mutations、action 这类操作方法,可以使用 Vue3 的 Composition API 的方式来操作状态。
- vite2
- Vue3 (composition API)
- lib 状态管理的源码
- src 状态管理的使用demo
- distp 在线演示的代码
https://gitee.com/naturefw/nf-rollup-state
https://naturefw.gitee.io/nf-rollup-state/
https://gitee.com/naturefw/nf-rollup-state
npm i nf-state
或者
yarn add nf-state
- createStore 创建实例,定义全局状态和初始化函数。
// store-nf/index.js
// 加载状态的类库
import { createStore } from 'nf-state'
// 加载 controller,非必要。
import userController from '../views/state/controller/userController.js'
export default createStore({
// 读写状态,直接使用 reactive
state: {
// 用户是否登录以及登录状态
user: {
isLogin: false,
name: 'jyk', //
age: 19
}
},
// 全局常量,使用 readonly
readonly:{
// 访问indexedDB 和 webSQL 的标识,用于区分不同的库
dbFlag: {
project_db_meta: 'plat-meta-db' // 平台 运行时需要的 meta。
},
// 用户是否登录以及登录状态
user1: {
isLogin: false,
info:{
name: '测试第二层属性'
},
name: 'jyk', //
age: 19
}
},
// 跟踪状态,用 proxy 给 reactive 套娃
track: {
trackTest: {
name: '跟踪测试',
age: 18,
children1: {
name1: '子属性测试',
children2: {
name2: '再嵌一套'
}
}
},
test2: {
name: ''
}
},
// 可以给全局状态设置初始状态,同步数据可以直接在上面设置,如果是异步数据,可以在这里设置。
init (state, read) {
userController().setWriteUse(read.user1)
setTimeout(() => {
read.dbFlag.project_db_meta = '加载后修改'
}, 2000)
}
})
-
state:固定名称不能更改。里面的属性可以随意设置,只是属性必须是对象(包含数组),不能是基础类型。
-
readonly:固定名称不能更改。里面的函数可以随意设置,函数名称就是注册和获取的函数名称。
必须是对象(数组),不能是基础类型。 -
track:可以跟踪的状态。
-
init:初始化函数,固定名称不能更改。
可以写异步代码。
- main.js 挂载到 app
//main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store-nf' // 轻量级状态
createApp(App)
.use(store) // 加载状态,调用 init 执行初始化函数。
.mount('#app')
- 模板里可以用 $state 访问全局状态。
<template>
全局状态-user:{{$state.user1}}<br>
</template>
目前只支持全局状态,局部状态需要先在代码里面获取,然后返回给模板。
- 在组件里获取状态。
import { state, watchState } from 'nf-state'
// 可以直接操作状态
console.log(state)
const testTract2 = () => {
state.trackTest.children1.name1 = new Date().valueOf()
}
const testTract3 = () => {
state.trackTest.children1.children2.name2 = new Date().valueOf()
state.test2.name = new Date().valueOf()
}
- 设置监听和钩子函数
import { state, watchState } from 'nf-state'
// 设置监听和钩子
watchState.trackTest(({keyPath, key, value, oldValue}) => {
if (keyPath === '') {
console.log(`\nstateKey.${key}=`)
} else {
console.log(`\nstateKey.${keyPath.replace(',','.')}.${key}=` )
}
console.log('oldValue:', oldValue)
console.log('value:', value )
// return null
})
- 局部状态,使用跟踪的方法。
import { reactive, provide, inject } from 'vue'
import { trackReactive } from 'nf-state'
const flag = 'test2'
/**
* 注入局部状态
*/
const reg = () => {
// 需要在函数内部定义,否则就变成“全局”的了。
const _test = reactive({
name: '局部状态的对象形式的controller'
})
// 注入
provide(flag, _test)
// 其他操作,比如设置 watch
return _test
}
/**
* 获取注入的状态
*/
const get = () => {
// 获取
const re = inject(flag)
return re
}
const regTrack = () => {
const ret = reactive({
name: '局部状态的可跟踪状态'
})
// 定义记录跟踪日志的容器
const logTrack = reactive([])
// 设置监听和钩子
const watchSet = (res) => {
console.log(res)
console.log(res.stack)
console.log(logTrack)
}
const loaclTrack = trackReactive(ret, 'loaclTrack', logTrack, watchSet)
return {
loaclTrack,
logTrack,
watchSet
}
}
// 其他操作
export {
regTrack,
reg,
get,
}
基本用法就是这些了,其他的就是各种灵活应用。