Skip to content

feat: 优化全局状态管理机制 #1305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/canvas/render/src/page-block-function/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export function useSchema(
bridge,
stores,
state,
// 追加一个 globalState,指向 stores,用于全局状态管理
globalState: stores,
props,
dataSourceMap: {},
emit: () => {} // 兼容访问器中getter和setter中this.emit写法
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const { EXPRESSION_TYPE } = constants
const CONSTANTS = {
THIS: 'this.',
STATE: 'this.state.',
STORE: 'this.stores.',
STORE: 'this.globalState.',
PROPS: 'this.props.',
COLLECTION: 'Collection',
ITEM: 'item',
Expand Down
4 changes: 2 additions & 2 deletions packages/vue-generator/src/generator/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ const generateVueCode = ({ schema, name, type, componentsMap }) => {
? `const [${componentNames.join(',')}] = [${exportNames.map((name) => `${name}()`).join(',')}]`
: ''

const contextArr = ['stores', 'state', ...methodsName]
const contextArr = ['stores', 'state', 'globalState', ...methodsName]

const result = `
<template>
Expand All @@ -420,7 +420,7 @@ ${imports.join('\n')}
const props = defineProps({${propsArr.join(',\n')}})
const emit = defineEmits(${JSON.stringify(emitsArr)})

const { t, lowcodeWrap, stores } = vue.inject(I18nInjectionKey).lowcode()
const { t, lowcodeWrap, stores, globalState } = vue.inject(I18nInjectionKey).lowcode()
const wrap = lowcodeWrap(props, { emit })

${iconStatement}
Expand Down
93 changes: 49 additions & 44 deletions packages/vue-generator/src/plugins/genGlobalState.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,63 +31,68 @@ function genDependenciesPlugin(options = {}) {
run(schema) {
const globalState = parseSchema(schema)

let importStatement = "import { defineStore } from 'pinia'"
const state = {}
const getters = {}
const actions = {}

const res = []
const ids = []

for (const stateItem of globalState) {
let importStatement = "import { defineStore } from 'pinia'"
const { id, state, getters, actions } = stateItem

ids.push(id)
const { id, state: stateValue, getters: gettersValue = [], actions: actionsValue = [] } = stateItem

const stateExpression = `() => ({ ${Object.entries(state)
.map((item) => {
let [key, value] = item

if (typeof value === 'string') {
value = `'${value}'`
state[id] = stateValue
Object.keys(gettersValue).forEach((key) => {
if (typeof gettersValue[key] === 'object' && gettersValue[key].type === 'JSFunction') {
if (gettersValue[key].value.includes('this')) {
gettersValue[key].value = gettersValue[key].value.replace(/this\./g, `this.${id}.`)
}

if (value && typeof value === 'object') {
value = JSON.stringify(value)
getters[key] = gettersValue[key].value
}
})
Object.keys(actionsValue).forEach((key) => {
if (typeof actionsValue[key] === 'object' && actionsValue[key].type === 'JSFunction') {
if (actionsValue[key].value.includes('this')) {
actionsValue[key].value = actionsValue[key].value.replace(/this\./g, `this.${id}.`)
}

return [key, value].join(':')
})
.join(',')} })`

const getterExpression = Object.entries(getters)
.filter((item) => item[1]?.type === 'JSFunction')
.map(([key, value]) => `${key}: ${value.value}`)
.join(',')

const actionExpressions = Object.entries(actions)
.filter((item) => item[1]?.type === 'JSFunction')
.map(([key, value]) => `${key}: ${value.value}`)
.join(',')

const storeFiles = `
${importStatement}
export const ${id} = defineStore({
id: '${id}',
state: ${stateExpression},
getters: { ${getterExpression} },
actions: { ${actionExpressions} }
})
`
res.push({
fileType: 'js',
fileName: `${id}.js`,
path,
fileContent: storeFiles
actions[key] = actionsValue[key].value
}
})
}

const globalStateFiles = `
${importStatement}
export const globalState = defineStore('globalState', {
state: () => (${JSON.stringify(state, null, 2)}),
getters: {${Object.entries(getters)
.map(([key, value]) => `${key}: ${value}`)
.join(',')}},
actions: {${Object.entries(actions)
.map(([key, value]) => `${key}: ${value}`)
.join(',')}}
})

export const useGlobalState = () => {
// 获取 globalState 实例
const globalStateInstance = globalState();

return globalStateInstance;
};

`

res.push({
fileType: 'js',
fileName: 'globalState.js',
path: './src/stores',
fileContent: globalStateFiles
})

res.push({
fileType: 'js',
fileName: 'index.js',
path,
fileContent: ids.map((item) => `export { ${item} } from './${item}'`).join('\n')
fileContent: `export { globalState } from './globalState'`
})

return res
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import dataSourceMap from './dataSource'
import * as utils from '../utils'
import * as bridge from './bridge'
import { useStores } from './store'
import { useGlobalState } from '@/stores/globalState'

export const lowcodeWrap = (props, context) => {
const global = {}
Expand Down Expand Up @@ -81,6 +82,7 @@ export default () => {
provide(I18nInjectionKey, i18n)

const stores = useStores()
const globalState = useGlobalState()

return { t: i18n.global.t, lowcodeWrap, stores }
return { t: i18n.global.t, lowcodeWrap, stores, globalState }
}