feat: add Pinia

This commit is contained in:
Nex Zhu 2021-12-28 18:37:34 +08:00
parent 126d430ef3
commit da0d0a6513
No known key found for this signature in database
GPG Key ID: 15C6254AD19362B4
10 changed files with 133 additions and 18 deletions

View File

@ -17,6 +17,7 @@ Basic:
`master` branch: `master` branch:
- [Element Plus](https://element-plus.org/): component library - [Element Plus](https://element-plus.org/): component library
- [Pinia](https://pinia.vuejs.org/): state management
- [Iconify](https://iconify.design/) icons with [unplugin-icons](https://github.com/antfu/unplugin-icons) - [Iconify](https://iconify.design/) icons with [unplugin-icons](https://github.com/antfu/unplugin-icons)
`antd` branch: `antd` branch:

72
package-lock.json generated
View File

@ -28,6 +28,7 @@
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^3.1.1",
"husky": "^7.0.4", "husky": "^7.0.4",
"lint-staged": "^12.1.4", "lint-staged": "^12.1.4",
"pinia": "^2.0.9",
"postcss-html": "^1.3.0", "postcss-html": "^1.3.0",
"stylelint": "^14.2.0", "stylelint": "^14.2.0",
"stylelint-config-property-sort-order-smacss": "^8.0.0", "stylelint-config-property-sort-order-smacss": "^8.0.0",
@ -9791,6 +9792,58 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/pinia": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.9.tgz",
"integrity": "sha512-iuYdxLJKQ07YPyOHYH05wNG9eKWqkP/4y4GE8+RqEYtz5fwHgPA5kr6zQbg/DoEJGnR2XCm1w1vdt6ppzL9ATg==",
"dev": true,
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.21",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.2.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.1.tgz",
"integrity": "sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==",
"dev": true,
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/pinkie": { "node_modules/pinkie": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
@ -21543,6 +21596,25 @@
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
}, },
"pinia": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.9.tgz",
"integrity": "sha512-iuYdxLJKQ07YPyOHYH05wNG9eKWqkP/4y4GE8+RqEYtz5fwHgPA5kr6zQbg/DoEJGnR2XCm1w1vdt6ppzL9ATg==",
"dev": true,
"requires": {
"@vue/devtools-api": "^6.0.0-beta.21",
"vue-demi": "*"
},
"dependencies": {
"vue-demi": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.1.tgz",
"integrity": "sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==",
"dev": true,
"requires": {}
}
}
},
"pinkie": { "pinkie": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",

View File

@ -48,6 +48,7 @@
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^3.1.1",
"husky": "^7.0.4", "husky": "^7.0.4",
"lint-staged": "^12.1.4", "lint-staged": "^12.1.4",
"pinia": "^2.0.9",
"postcss-html": "^1.3.0", "postcss-html": "^1.3.0",
"stylelint": "^14.2.0", "stylelint": "^14.2.0",
"stylelint-config-property-sort-order-smacss": "^8.0.0", "stylelint-config-property-sort-order-smacss": "^8.0.0",

View File

@ -1,7 +1,15 @@
import { access } from '@fesjs/fes' import { access } from '@fesjs/fes'
import type { App } from 'vue'
import { createPinia } from 'pinia'
import PageLoading from '~/components/PageLoading.vue' import PageLoading from '~/components/PageLoading.vue'
import UserCenter from '~/components/UserCenter.vue' import UserCenter from '~/components/UserCenter.vue'
export function onAppCreated({ app }: { app: App }) {
const pinia = createPinia()
app.use(pinia)
}
export const beforeRender = { export const beforeRender = {
loading: PageLoading, loading: PageLoading,
action() { action() {
@ -9,21 +17,12 @@ export const beforeRender = {
return new Promise((resolve) => { return new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
void setRole('admin') void setRole('admin')
// 初始化应用的全局状态,可以通过 useModel('@@initialState') 获取,具体用法看@/components/UserCenter 文件 resolve({})
resolve(state)
}, 1000) }, 1000)
}) })
}, },
} }
export type State = {
userName: string
}
const state: State = {
userName: 'harrywan',
}
export const layout = { export const layout = {
customHeader: UserCenter, customHeader: UserCenter,
} }

View File

@ -3,15 +3,15 @@
<i-mdi-account-box <i-mdi-account-box
style="color: red; font-size: 2em; vertical-align: middle" style="color: red; font-size: 2em; vertical-align: middle"
/> />
<span>{{ initialState.userName }}</span> <span>{{ name }}</span>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useModel } from '@fesjs/fes' import useUserStore from '~/stores/user'
import type { State } from '~/app'
const initialState = useModel('@@initialState') as State const store = useUserStore()
const name = store.name
</script> </script>
<style scope lang="scss"> <style scope lang="scss">

View File

@ -22,11 +22,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { enums } from '@fesjs/fes' import { enums } from '@fesjs/fes'
import useCounterStore from '~/stores/counter'
const count = ref(0) const store = useCounterStore()
const count = computed(() => store.clicked)
const increment = () => { const increment = () => {
count.value++ store.clicked++
} }
const enumsGet = enums.get const enumsGet = enums.get

21
src/stores/counter.ts Normal file
View File

@ -0,0 +1,21 @@
import { defineStore, acceptHMRUpdate } from 'pinia'
const useCounterStore = defineStore('counter', {
state: () => {
return {
clicked: 4,
}
},
})
// Enable HMR for supported bundlers
// See: https://pinia.vuejs.org/cookbook/hot-module-replacement.html
/* eslint-disable */
// @ts-ignore
if (import.meta.hot) {
// @ts-ignore
import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot))
}
/* eslint-enable */
export default useCounterStore

21
src/stores/user.ts Normal file
View File

@ -0,0 +1,21 @@
import { defineStore, acceptHMRUpdate } from 'pinia'
const useUserStore = defineStore('user', {
state: () => {
return {
name: 'harrywan',
}
},
})
// Enable HMR for supported bundlers
// See: https://pinia.vuejs.org/cookbook/hot-module-replacement.html
/* eslint-disable */
// @ts-ignore
if (import.meta.hot) {
// @ts-ignore
import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot))
}
/* eslint-enable */
export default useUserStore

View File

@ -9,7 +9,6 @@ declare global {
const effectScope: typeof import('vue')['effectScope'] const effectScope: typeof import('vue')['effectScope']
const EffectScope: typeof import('vue')['EffectScope'] const EffectScope: typeof import('vue')['EffectScope']
const ElButton: typeof import('element-plus/es')['ElButton'] const ElButton: typeof import('element-plus/es')['ElButton']
const ElLoadingDirective: typeof import('element-plus/es')['ElLoadingDirective']
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope'] const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h'] const h: typeof import('vue')['h']

View File

@ -6,7 +6,6 @@ declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
IMdiAccountBox: typeof import('~icons/mdi/account-box')['default'] IMdiAccountBox: typeof import('~icons/mdi/account-box')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective']
PageLoading: typeof import('./../components/PageLoading.vue')['default'] PageLoading: typeof import('./../components/PageLoading.vue')['default']
UserCenter: typeof import('./../components/UserCenter.vue')['default'] UserCenter: typeof import('./../components/UserCenter.vue')['default']
} }