1
0
mirror of https://github.com/zclzone/vue-naive-admin.git synced 2026-01-22 23:50:22 +08:00

14 Commits

Author SHA1 Message Date
zclzone
70c2098d2e refactor: 操作指引改成非自动触发 2025-03-18 10:14:20 +08:00
zclzone
82748abcc3 fix: unocss废弃api替换 2025-03-18 10:05:50 +08:00
zclzone
e5fd1405da style: lint fix 2025-03-13 10:29:17 +08:00
zclzone
833321d31d chore: update deps 2025-02-28 17:25:28 +08:00
zclzone
53afc9b531 chore: update deps 2025-02-06 16:03:45 +08:00
zclzone
0733b81f82 fix(crud): 浅拷贝 -> 深拷贝 2025-01-21 14:37:16 +08:00
zclzone
26ce0bd551 chore: update deps 2025-01-09 21:15:09 +08:00
zclzone
1201e8e172 chore: update deps 2024-12-27 18:31:08 +08:00
zclzone
78d9bb99f2 chore: update deps and lint fix 2024-12-14 19:56:56 +08:00
zclzone
9b510e8350 fix: pinia持久化paths -> pick 2024-11-29 15:26:07 +08:00
zclzone
7ce6cf1f7c fix: 移除多余的class 2024-11-22 16:00:49 +08:00
zclzone
30ca69cf16 fix: remove scss style 2024-11-22 15:59:20 +08:00
zclzone
c34c3646aa chore: update settings.json 2024-11-22 15:49:08 +08:00
leip247
6563797afc feat(guide): 添加操作指引 (#106)
* fix(slot): 优化部分slot写法,减少手动判断

* fix(slot): 优化部分slot写法,减少手动判断

* feat(guide): 添加操作指引
2024-11-22 15:47:00 +08:00
22 changed files with 2429 additions and 2043 deletions

View File

@@ -19,6 +19,5 @@
"markdown", "markdown",
"json", "json",
"jsonc" "jsonc"
], ]
"common-intellisense.ui": ["naiveUi2"]
} }

View File

@@ -13,42 +13,43 @@
}, },
"dependencies": { "dependencies": {
"@arco-design/color": "^0.4.0", "@arco-design/color": "^0.4.0",
"@vueuse/core": "^11.1.0", "@vueuse/core": "^12.7.0",
"axios": "^1.7.7", "axios": "^1.8.1",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"echarts": "^5.5.1", "echarts": "^5.6.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"naive-ui": "^2.40.1", "naive-ui": "^2.41.0",
"pinia": "^2.2.4", "pinia": "^3.0.1",
"pinia-plugin-persistedstate": "^4.1.1", "pinia-plugin-persistedstate": "^4.2.0",
"vue": "^3.5.12", "vue": "^3.5.13",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",
"vue-router": "^4.4.5", "vue-router": "^4.5.0",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^3.8.0", "@antfu/eslint-config": "^4.3.0",
"@iconify/json": "^2.2.262", "@iconify/json": "^2.2.311",
"@unocss/eslint-config": "^0.63.6", "@unocss/eslint-config": "^66.0.0",
"@unocss/eslint-plugin": "^0.63.6", "@unocss/eslint-plugin": "^66.0.0",
"@unocss/preset-rem-to-px": "^0.63.6", "@unocss/preset-rem-to-px": "^66.0.0",
"@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.0.1", "@vitejs/plugin-vue-jsx": "^4.1.1",
"eslint": "^9.13.0", "eslint": "^9.21.0",
"eslint-plugin-format": "^0.1.2", "eslint-plugin-format": "^1.0.1",
"esno": "^4.8.0", "esno": "^4.8.0",
"fs-extra": "^11.2.0", "fs-extra": "^11.3.0",
"glob": "^11.0.0", "glob": "^11.0.1",
"lint-staged": "^15.2.10", "lint-staged": "^15.4.3",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.14.0",
"simple-git-hooks": "^2.11.1", "simple-git-hooks": "^2.11.1",
"taze": "^0.17.2", "taze": "^18.6.0",
"unocss": "^0.63.6", "unocss": "^66.0.0",
"unplugin-auto-import": "^0.18.3", "unplugin-auto-import": "^19.1.1",
"unplugin-vue-components": "^0.27.4", "unplugin-vue-components": "^28.4.1",
"vite": "^5.4.9", "vite": "^6.2.0",
"vite-plugin-router-warn": "^1.0.0", "vite-plugin-router-warn": "^1.0.0",
"vite-plugin-vue-devtools": "^7.5.2" "vite-plugin-vue-devtools": "^7.7.2",
"vue3-intro-step": "^1.0.5"
}, },
"simple-git-hooks": { "simple-git-hooks": {
"pre-commit": "pnpm lint-staged" "pre-commit": "pnpm lint-staged"

4206
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
<div> <div>
<n-tooltip trigger="hover" placement="left"> <n-tooltip trigger="hover" placement="left">
<template #trigger> <template #trigger>
<div class="f-c-c rounded-4 bg-primary p-8" @click="modalRef.open()"> <div id="layout-setting" class="f-c-c rounded-4 bg-primary p-8" @click="modalRef.open()">
<i class="i-fe:settings cursor-pointer bg-white text-20" /> <i class="i-fe:settings cursor-pointer bg-white text-20" />
</div> </div>
</template> </template>

View File

@@ -2,6 +2,7 @@
<n-tooltip trigger="hover"> <n-tooltip trigger="hover">
<template #trigger> <template #trigger>
<n-color-picker <n-color-picker
id="theme-setting"
class="mr-16 h-32 w-32" class="mr-16 h-32 w-32"
:value="appStore.primaryColor" :value="appStore.primaryColor"
:swatches="primaryColors" :swatches="primaryColors"

View File

@@ -1,5 +1,6 @@
<template> <template>
<i <i
id="toggleTheme"
class="mr-16 cursor-pointer" class="mr-16 cursor-pointer"
:class="isDark ? 'i-fe:moon' : 'i-fe:sun'" :class="isDark ? 'i-fe:moon' : 'i-fe:sun'"
@click="toggleDark" @click="toggleDark"

View File

@@ -6,6 +6,7 @@
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top * Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/ **********************************/
import { cloneDeep } from 'lodash-es'
import { useForm, useModal } from '.' import { useForm, useModal } from '.'
const ACTIONS = { const ACTIONS = {
@@ -21,7 +22,7 @@ export function useCrud({ name, initForm = {}, doCreate, doDelete, doUpdate, ref
/** 新增 */ /** 新增 */
function handleAdd(row = {}, title) { function handleAdd(row = {}, title) {
handleOpen({ action: 'add', title, row: { ...initForm, ...row } }) handleOpen({ action: 'add', title, row: Object.assign({}, cloneDeep(initForm), cloneDeep(row)) })
} }
/** 修改 */ /** 修改 */

View File

@@ -6,9 +6,11 @@
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top * Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/ **********************************/
import { cloneDeep } from 'lodash-es'
export function useForm(initFormData = {}) { export function useForm(initFormData = {}) {
const formRef = ref(null) const formRef = ref(null)
const formModel = ref({ ...initFormData }) const formModel = ref(cloneDeep(initFormData))
const rules = { const rules = {
required: { required: {
required: true, required: true,

View File

@@ -0,0 +1,120 @@
<template>
<n-tooltip trigger="hover">
<template #trigger>
<i
class="i-fe:beginner mr-16 cursor-pointer text-20"
@click="show = true"
/>
</template>
操作指引
</n-tooltip>
<Vue3IntroStep
ref="myIntroStep"
v-model:show="show"
:config="config"
>
<template #prev="{ tipItem, index }">
<NButton class="mr-12" type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="prev(tipItem, index)">
上一步
</NButton>
</template>
<template #next="{ tipItem }">
<NButton class="mr-12" type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="next(tipItem)">
下一步
</NButton>
</template>
<template #skip>
<NButton type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="skip">
跳过
</NButton>
</template>
<template #done>
<NButton type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="done">
完成
</NButton>
</template>
</Vue3IntroStep>
</template>
<script setup>
import Vue3IntroStep from 'vue3-intro-step'
const myIntroStep = shallowRef(null)
const show = shallowRef(false)
const config = {
backgroundOpacity: 0.8,
titleStyle: {
textAlign: 'left',
fontSize: '18px',
},
contentStyle: {
textAlign: 'left',
fontSize: '14px',
},
tips: [
{
el: '#toggleTheme',
tipPosition: 'bottom',
title: '切换系统主题',
content: '一键开启护眼模式',
},
{
el: '#fullscreen',
tipPosition: 'bottom',
title: '全屏/退出全屏',
content: '一键开启全屏',
},
{
el: '#theme-setting',
tipPosition: 'bottom',
title: '设置主题色',
content: '调整为你喜欢的主题色',
},
{
el: '#user-dropdown',
tipPosition: 'bottom',
title: '个人中心',
content: '查看个人资料和退出系统',
},
{
el: '#menu-collapse',
tipPosition: 'bottom',
title: '展开/收起菜单',
content: '一键展开/收起菜单',
},
{
el: '#top-tab',
tipPosition: 'bottom',
title: '标签栏',
content: '鼠标滚轮滑动可调整至最佳视野',
},
{
el: '#layout-setting',
tipPosition: 'left',
title: '调整系统布局',
content: '将系统布局调整为你喜欢的样子',
},
],
}
function skip() {
show.value = false
}
function done() {
show.value = false
}
function next() {
// tipItem当前的提示项信息
// 调用vue3-intro-step的next方法 手动触发下一步
myIntroStep.value.next()
}
function prev() {
// 调用vue3-intro-step的prev方法 手动触发上一步
myIntroStep.value.prev()
}
</script>

View File

@@ -1,5 +1,6 @@
<template> <template>
<i <i
id="fullscreen"
class="mr-16 cursor-pointer" class="mr-16 cursor-pointer"
:class="isFullscreen ? 'i-fe:minimize' : 'i-fe:maximize'" :class="isFullscreen ? 'i-fe:minimize' : 'i-fe:maximize'"
@click="toggle" @click="toggle"

View File

@@ -8,6 +8,7 @@
<template> <template>
<div <div
id="menu-collapse"
class="f-c-c cursor-pointer rounded-4 p-6 text-22 transition-all-300 auto-bg-hover" class="f-c-c cursor-pointer rounded-4 p-6 text-22 transition-all-300 auto-bg-hover"
@click="appStore.switchCollapsed" @click="appStore.switchCollapsed"
> >

View File

@@ -8,7 +8,7 @@
<template> <template>
<n-dropdown :options="options" @select="handleSelect"> <n-dropdown :options="options" @select="handleSelect">
<div class="flex cursor-pointer items-center"> <div id="user-dropdown" class="flex cursor-pointer items-center">
<n-avatar round :size="36" :src="userStore.avatar" /> <n-avatar round :size="36" :src="userStore.avatar" />
<div v-if="userStore.userInfo" class="ml-12 flex-col flex-shrink-0 items-center"> <div v-if="userStore.userInfo" class="ml-12 flex-col flex-shrink-0 items-center">
<span class="text-14">{{ userStore.nickName ?? userStore.username }}</span> <span class="text-14">{{ userStore.nickName ?? userStore.username }}</span>

View File

@@ -1,3 +1,4 @@
export { default as BeginnerGuide } from './BeginnerGuide.vue'
export { default as BreadCrumb } from './BreadCrumb.vue' export { default as BreadCrumb } from './BreadCrumb.vue'
export { default as Fullscreen } from './Fullscreen.vue' export { default as Fullscreen } from './Fullscreen.vue'
export { default as MenuCollapse } from './MenuCollapse.vue' export { default as MenuCollapse } from './MenuCollapse.vue'

View File

@@ -7,7 +7,7 @@
---------------------------------> --------------------------------->
<template> <template>
<div> <div id="top-tab">
<n-tabs <n-tabs
:value="tabStore.activeTab" :value="tabStore.activeTab"
:closable="tabStore.tabs.length > 1" :closable="tabStore.tabs.length > 1"

View File

@@ -13,6 +13,8 @@
<BreadCrumb /> <BreadCrumb />
<div class="ml-auto flex flex-shrink-0 items-center px-12 text-18"> <div class="ml-auto flex flex-shrink-0 items-center px-12 text-18">
<BeginnerGuide />
<ToggleTheme /> <ToggleTheme />
<Fullscreen /> <Fullscreen />
@@ -35,7 +37,7 @@
<script setup> <script setup>
import { ToggleTheme } from '@/components' import { ToggleTheme } from '@/components'
import { BreadCrumb, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components' import { BeginnerGuide, BreadCrumb, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components'
function handleLinkClick(link) { function handleLinkClick(link) {
window.open(link) window.open(link)

View File

@@ -15,6 +15,8 @@
<span class="mx-6 opacity-20">|</span> <span class="mx-6 opacity-20">|</span>
<div class="flex flex-shrink-0 items-center px-12 text-18"> <div class="flex flex-shrink-0 items-center px-12 text-18">
<BeginnerGuide />
<ToggleTheme /> <ToggleTheme />
<Fullscreen /> <Fullscreen />
@@ -37,7 +39,7 @@
<script setup> <script setup>
import { ToggleTheme } from '@/components' import { ToggleTheme } from '@/components'
import { AppTab, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components' import { AppTab, BeginnerGuide, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components'
function handleLinkClick(link) { function handleLinkClick(link) {
window.open(link) window.open(link)

View File

@@ -50,7 +50,7 @@ export const useAppStore = defineStore('app', {
}, },
}, },
persist: { persist: {
paths: ['collapsed', 'layout', 'primaryColor', 'naiveThemeOverrides'], pick: ['collapsed', 'layout', 'primaryColor', 'naiveThemeOverrides'],
storage: sessionStorage, storage: sessionStorage,
}, },
}) })

View File

@@ -88,7 +88,7 @@ export const useTabStore = defineStore('tab', {
}, },
}, },
persist: { persist: {
paths: ['tabs'], pick: ['tabs'],
storage: sessionStorage, storage: sessionStorage,
}, },
}) })

View File

@@ -11,14 +11,14 @@ import { createStorage } from './storage'
const prefixKey = 'vue-naive-admin_' const prefixKey = 'vue-naive-admin_'
export const createLocalStorage = function (option = {}) { export function createLocalStorage(option = {}) {
return createStorage({ return createStorage({
prefixKey: option.prefixKey || '', prefixKey: option.prefixKey || '',
storage: localStorage, storage: localStorage,
}) })
} }
export const createSessionStorage = function (option = {}) { export function createSessionStorage(option = {}) {
return createStorage({ return createStorage({
prefixKey: option.prefixKey || '', prefixKey: option.prefixKey || '',
storage: sessionStorage, storage: sessionStorage,

View File

@@ -98,7 +98,7 @@
<script setup> <script setup>
import { sleep } from '@/utils' import { sleep } from '@/utils'
const handleDelete = function () { function handleDelete() {
$dialog.confirm({ $dialog.confirm({
content: '确认删除?', content: '确认删除?',
confirm() { confirm() {

View File

@@ -8,13 +8,13 @@
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders' import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
import presetRemToPx from '@unocss/preset-rem-to-px' import presetRemToPx from '@unocss/preset-rem-to-px'
import { defineConfig, presetAttributify, presetIcons, presetUno } from 'unocss' import { defineConfig, presetAttributify, presetIcons, presetWind3 } from 'unocss'
import { getIcons } from './build/index.js' import { getIcons } from './build/index.js'
const icons = getIcons() const icons = getIcons()
export default defineConfig({ export default defineConfig({
presets: [ presets: [
presetUno(), presetWind3(),
presetAttributify(), presetAttributify(),
presetIcons({ presetIcons({
warn: true, warn: true,