@yyp92-cli/template-vue-mobile 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +15 -0
  3. package/template/.env.development +5 -0
  4. package/template/.env.production +5 -0
  5. package/template/.env.test +5 -0
  6. package/template/README.md +5 -0
  7. package/template/auto-imports.d.ts +10 -0
  8. package/template/components.d.ts +28 -0
  9. package/template/index.html +16 -0
  10. package/template/package.json +35 -0
  11. package/template/pnpm-lock.yaml +2007 -0
  12. package/template/public/vite.svg +1 -0
  13. package/template/src/App.vue +24 -0
  14. package/template/src/assets/vue.svg +1 -0
  15. package/template/src/components/layout/index.vue +68 -0
  16. package/template/src/components/layout/navBar/index.vue +35 -0
  17. package/template/src/components/layout/tabBar/index.vue +47 -0
  18. package/template/src/global/constants.ts +4 -0
  19. package/template/src/main.ts +12 -0
  20. package/template/src/router/index.ts +38 -0
  21. package/template/src/router/routes.tsx +83 -0
  22. package/template/src/service/api.ts +7 -0
  23. package/template/src/service/config.ts +9 -0
  24. package/template/src/service/index.ts +1 -0
  25. package/template/src/service/request/index.ts +270 -0
  26. package/template/src/service/request/type.ts +5 -0
  27. package/template/src/service/service.ts +27 -0
  28. package/template/src/store/index.ts +14 -0
  29. package/template/src/store/login/index.ts +67 -0
  30. package/template/src/styles/global.scss +32 -0
  31. package/template/src/styles/index.scss +4 -0
  32. package/template/src/styles/reset.scss +17 -0
  33. package/template/src/theme/darkTheme.scss +51 -0
  34. package/template/src/theme/lightTheme.scss +53 -0
  35. package/template/src/utils/cache.ts +44 -0
  36. package/template/src/utils/download.ts +27 -0
  37. package/template/src/utils/format.ts +10 -0
  38. package/template/src/utils/index.ts +22 -0
  39. package/template/src/views/403/index.vue +23 -0
  40. package/template/src/views/404/index.vue +34 -0
  41. package/template/src/views/detail/index.vue +19 -0
  42. package/template/src/views/home/index.vue +19 -0
  43. package/template/src/views/login/index.vue +81 -0
  44. package/template/src/views/message/index.vue +19 -0
  45. package/template/src/views/mine/index.vue +19 -0
  46. package/template/src/views/todo/index.vue +19 -0
  47. package/template/src/vite-env.d.ts +4 -0
  48. package/template/tsconfig.app.json +24 -0
  49. package/template/tsconfig.json +7 -0
  50. package/template/tsconfig.node.json +25 -0
  51. package/template/vite.config.ts +59 -0
@@ -0,0 +1,67 @@
1
+ import {defineStore} from 'pinia'
2
+ import { localCache } from '@/utils/cache'
3
+ import { LOGIN_TOKEN, PERMISSION, USER_INFO, MENUS } from '@/global/constants'
4
+ import {routes} from '@/router/routes'
5
+
6
+ interface LoginState {
7
+ token: string,
8
+ userInfo: any,
9
+ userMenus: any,
10
+ permissions: string[]
11
+ }
12
+
13
+ const useLoginStore = defineStore(
14
+ 'login',
15
+ {
16
+ state: (): LoginState => ({
17
+ token: '',
18
+ userInfo: {},
19
+ userMenus: [],
20
+ permissions: []
21
+ }),
22
+
23
+ actions: {
24
+ async loginAccountAction(account: any) {
25
+ try {
26
+ setTimeout(() => {
27
+ const menus = routes[0].children.filter((item: any) => !item.meta.hideMenu)
28
+ const promissions = routes[0].children.map((item: any) => item.path)
29
+ this.userMenus = menus
30
+
31
+ localCache.setCache(MENUS, menus)
32
+ localCache.setCache(PERMISSION, promissions)
33
+ }, 3000)
34
+ }
35
+ catch(error) {
36
+ return error
37
+ }
38
+
39
+ return 'ok'
40
+ },
41
+
42
+ // 用户进行刷新默认加载数据
43
+ loadLocalCacheAction() {
44
+ const token = localCache.getCache(LOGIN_TOKEN)
45
+ const userInfo = localCache.getCache(USER_INFO)
46
+ const userMenus = localCache.getCache(MENUS)
47
+ const permission = localCache.getCache(PERMISSION)
48
+
49
+ this.token = token
50
+ this.userInfo = userInfo
51
+ this.userMenus = userMenus
52
+ // 获取登录用户的所有按钮的权限
53
+ this.permissions = permission
54
+
55
+ // if (token && userInfo && userMenus) {
56
+ // this.token = token
57
+ // this.userInfo = userInfo
58
+ // this.userMenus = userMenus
59
+ // // 获取登录用户的所有按钮的权限
60
+ // this.permissions = permission
61
+ // }
62
+ }
63
+ }
64
+ }
65
+ )
66
+
67
+ export default useLoginStore
@@ -0,0 +1,32 @@
1
+ html,
2
+ body {
3
+ width: 100%;
4
+ height: 100%;
5
+ overflow: hidden;
6
+ }
7
+
8
+ #app {
9
+ width: 100%;
10
+ height: 100%;
11
+ background: var(--bg-white-color);
12
+ }
13
+
14
+ *:focus-visible {
15
+ outline: none;
16
+ }
17
+
18
+
19
+ // element-plus 组件库的样式重写
20
+
21
+
22
+ // 滚动条
23
+ // ::-webkit-scrollbar {
24
+ // width: 8px;
25
+ // height: 8px;
26
+ // }
27
+ // ::-webkit-scrollbar-thumb {
28
+ // border-radius: 6px;
29
+ // background-color: #dde6f0;
30
+ // border: 2px dashed transparent;
31
+ // background-clip: padding-box;
32
+ // }
@@ -0,0 +1,4 @@
1
+ @use "@/theme/lightTheme.scss" as *;
2
+ @use "@/theme/darkTheme.scss" as *;
3
+ @use "@/styles/global.scss" as *;
4
+ @use "@/styles/reset.scss" as *;
@@ -0,0 +1,17 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ }
5
+
6
+ *:focus-visible {
7
+ outline: none;
8
+ }
9
+
10
+ ul,
11
+ li {
12
+ list-style: none;
13
+ }
14
+
15
+ a {
16
+ text-decoration: none;
17
+ }
@@ -0,0 +1,51 @@
1
+ :root[data-theme="dark"] {
2
+ --primary-text-color: #FFFFFF;
3
+ --primary-white-color: #2A2A2D;
4
+
5
+ // 全局主色
6
+ --primary-color: #3591F4;
7
+ --primary-color1: rgba(53, 145, 244, 0.1);
8
+ // 链接色
9
+ --link-color: #3591F4;
10
+ // 成功色
11
+ --success-color: #0CAA43;
12
+ --success-color1: rgba(12, 170, 67, 0.1);
13
+ // 警告色
14
+ --warning-color: #FFA00A;
15
+ --warning-color1: rgba(255, 160, 10, 0.1);
16
+ // 错误色
17
+ --error-color: #F43835;
18
+ --error-color1: rgba(244, 56, 53, 0.1);
19
+
20
+ // 主文本色
21
+ --text-color: #FFFFFF;
22
+ // 次文本色
23
+ --text-color-secondary: #898D97;
24
+
25
+ // 白的背景
26
+ --bg-white-color: #1C1C1C;
27
+ --bg-grey-color: #161616;
28
+ --bg-grey-color1: transparent;
29
+ --bg-black2-color: #222222;
30
+ --bg-hover-color: rgba(53, 145, 244, 0.1);
31
+ --bg-white-color1: rgba(0, 0, 0, 0.5);
32
+
33
+ // 边框、输入框、分割线
34
+ --border-color-base: #2A2A2D;
35
+ // icon
36
+ --icon-color: #898D97;
37
+
38
+ // 主字号
39
+ --font-size-base: 14px;
40
+
41
+ // 组件/浮层圆角
42
+ --border-radius-base: 4px;
43
+ --modal-border-radius-base: 5px;
44
+
45
+ // 阴影
46
+ --box-shadow-color: #000000;
47
+
48
+
49
+ // 大屏主题
50
+ --screen-text-color: #29fcff;
51
+ }
@@ -0,0 +1,53 @@
1
+ :root[data-theme="light"] {
2
+ --primary-text-color: #FFFFFF;
3
+ --primary-white-color: #FFFFFF;
4
+
5
+ // 全局主色
6
+ --primary-color: #3591F4;
7
+ --primary-color1: rgba(53, 145, 244, 0.1);
8
+ // 链接色
9
+ --link-color: var(--primary-color);
10
+ // 成功色
11
+ --success-color: #0CAA43;
12
+ --success-color1: rgba(12, 170, 67, 0.1);
13
+ // 警告色
14
+ --warning-color: #FFA00A;
15
+ --warning-color1: rgba(255, 160, 10, 0.1);
16
+ // 错误色
17
+ --error-color: #F43835;
18
+ --error-color1: rgba(244, 56, 53, 0.1);
19
+
20
+ // 主文本色
21
+ --text-color: #363A45;
22
+ // 次文本色
23
+ --text-color-secondary: #898D97;
24
+
25
+ // 白的背景
26
+ --bg-white-color: var(--primary-white-color);
27
+ --bg-grey-color: #F2F4F9;
28
+ --bg-grey-color1: var(--bg-grey-color);
29
+ --bg-black2-color: var(--primary-white-color);
30
+ --bg-hover-color: rgba(53, 145, 244, 0.1);
31
+ --bg-white-color1: rgba(255, 255, 255, 0.5);
32
+
33
+ // 边框、输入框、分割线
34
+ --border-color-base: #DDE6F0;
35
+ // icon
36
+ --icon-color: #CCD6DD;
37
+
38
+
39
+
40
+ // 主字号
41
+ --font-size-base: 14px;
42
+
43
+ // 组件/浮层圆角
44
+ --border-radius-base: 4px;
45
+ --modal-border-radius-base: 5px;
46
+
47
+ // 阴影
48
+ --box-shadow-color: #000000;
49
+
50
+
51
+ // 大屏主题
52
+ --screen-text-color: #29fcff;
53
+ }
@@ -0,0 +1,44 @@
1
+ enum CacheType {
2
+ Local,
3
+ Session
4
+ }
5
+
6
+ class Cache {
7
+ storage: Storage
8
+
9
+ constructor(type: CacheType) {
10
+ this.storage = type === CacheType.Local
11
+ ? localStorage
12
+ : sessionStorage
13
+ }
14
+
15
+ setCache(key: string, value: any) {
16
+ if (value) {
17
+ this.storage.setItem(key, JSON.stringify(value))
18
+ }
19
+ }
20
+
21
+ getCache(key: string) {
22
+ const value = this.storage.getItem(key)
23
+
24
+ if (value) {
25
+ return JSON.parse(value)
26
+ }
27
+ }
28
+
29
+ removeCache(key: string) {
30
+ this.storage.removeItem(key)
31
+ }
32
+
33
+ clear() {
34
+ this.storage.clear()
35
+ }
36
+ }
37
+
38
+ const localCache = new Cache(CacheType.Local)
39
+ const sessionCache = new Cache(CacheType.Session)
40
+
41
+ export {
42
+ localCache,
43
+ sessionCache
44
+ }
@@ -0,0 +1,27 @@
1
+ import {isFunction} from 'lodash-es'
2
+
3
+ // 下载文件
4
+ export const downloadFile = (
5
+ output: any,
6
+ downloadFileName: string = '未命名文件',
7
+ handleCancel: () => void = () => {}
8
+ ) => {
9
+ if (!output && isFunction(handleCancel)) {
10
+ handleCancel()
11
+ return
12
+ }
13
+
14
+ fetch(output, {responseType: 'blob'} as any)
15
+ .then((res: any) => res?.blob?.())
16
+ .then((res: any) => {
17
+ const link = document.createElement('a')
18
+ link.href = window.URL.createObjectURL(res)
19
+ link.download = downloadFileName
20
+ link.style.display = 'none'
21
+ document.body.appendChild(link)
22
+ link.click()
23
+ })
24
+ .finally(() => {
25
+ isFunction(handleCancel) && handleCancel()
26
+ })
27
+ }
@@ -0,0 +1,10 @@
1
+ import dayjs from 'dayjs'
2
+ import utc from 'dayjs/plugin/utc'
3
+
4
+ dayjs.extend(utc)
5
+
6
+ export function formatUTC(utcString: string, format: string = 'YYYY-MM-DD HH:mm:ss') {
7
+ const time = dayjs.utc(utcString).utcOffset(8).format(format)
8
+
9
+ return time
10
+ }
@@ -0,0 +1,22 @@
1
+ // 主题切换
2
+ export const changeTheme = (isDark: boolean) => {
3
+ // 获取根元素
4
+ const root = document.documentElement;
5
+
6
+ if (!isDark) {
7
+ // 修改 data-theme 属性的值为 "light"
8
+ root.setAttribute('data-theme', 'light');
9
+ return
10
+ }
11
+
12
+ // 修改 data-theme 属性的值为 "dark"
13
+ root.setAttribute('data-theme', 'dark');
14
+ }
15
+
16
+
17
+ // 获取本地权限
18
+ export const getLocalPromission = (routes: any[]) => {
19
+ const promissions = routes[0].children.map((item: any) => item.path)
20
+
21
+ return promissions
22
+ }
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div class="page403">
3
+ <van-empty description="您没有权限访问该页面!" />
4
+ </div>
5
+ </template>
6
+
7
+ <script
8
+ setup
9
+ lang="ts"
10
+ name="Page403"
11
+ >
12
+ </script>
13
+
14
+ <style
15
+ scoped
16
+ lang="scss"
17
+ >
18
+ .page403 {
19
+ width: 100%;
20
+ height: 100%;
21
+ background: var(--bg-white-color);
22
+ }
23
+ </style>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <div class="page404">
3
+ <van-empty description="您访问该页面不存在!">
4
+ <van-button
5
+ round
6
+ type="primary"
7
+ @click="goHome"
8
+ >跳转到首页</van-button>
9
+ </van-empty>
10
+ </div>
11
+ </template>
12
+
13
+ <script
14
+ setup
15
+ lang="ts"
16
+ name="Page404"
17
+ >
18
+ import router from '@/router/index'
19
+
20
+ function goHome() {
21
+ router.push('/home')
22
+ }
23
+ </script>
24
+
25
+ <style
26
+ scoped
27
+ lang="scss"
28
+ >
29
+ .page404 {
30
+ width: 100%;
31
+ height: 100%;
32
+ background: var(--bg-white-color);
33
+ }
34
+ </style>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="detail">
3
+ <h2>detail</h2>
4
+ </div>
5
+ </template>
6
+
7
+ <script
8
+ setup
9
+ lang="ts"
10
+ name="Detail"
11
+ >
12
+ </script>
13
+
14
+ <style
15
+ scoped
16
+ lang="scss"
17
+ >
18
+ .detail {}
19
+ </style>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="home">
3
+ <h2>home</h2>
4
+ </div>
5
+ </template>
6
+
7
+ <script
8
+ setup
9
+ lang="ts"
10
+ name="Home"
11
+ >
12
+ </script>
13
+
14
+ <style
15
+ scoped
16
+ lang="scss"
17
+ >
18
+ .home {}
19
+ </style>
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <div class="login">
3
+ <van-form @submit="onSubmit">
4
+ <van-cell-group inset>
5
+ <van-field
6
+ v-model="username"
7
+ name="username"
8
+ label="用户名"
9
+ placeholder="用户名"
10
+ :rules="[{ required: true, message: '请填写用户名' }]"
11
+ />
12
+
13
+ <van-field
14
+ v-model="password"
15
+ type="password"
16
+ name="password"
17
+ label="密码"
18
+ placeholder="密码"
19
+ :rules="[{ required: true, message: '请填写密码' }]"
20
+ />
21
+ </van-cell-group>
22
+
23
+ <div style="margin: 16px;">
24
+ <van-button round block type="primary" native-type="submit">
25
+ 提交
26
+ </van-button>
27
+ </div>
28
+ </van-form>
29
+ </div>
30
+ </template>
31
+
32
+ <script
33
+ setup
34
+ lang="ts"
35
+ name="Login"
36
+ >
37
+ import { ref } from 'vue'
38
+ import {useRoute} from 'vue-router'
39
+ import { showLoadingToast, closeToast } from 'vant'
40
+ import useLoginStore from '@/store/login'
41
+ import router from '@/router'
42
+
43
+ const route = useRoute()
44
+ const username = ref('')
45
+ const password = ref('')
46
+ const loginStore = useLoginStore()
47
+
48
+
49
+ const onSubmit = (values: any) => {
50
+ showLoadingToast({
51
+ message: '加载中...',
52
+ forbidClick: true,
53
+ duration: 0
54
+ })
55
+
56
+ loginStore.loginAccountAction(values)
57
+ .then((res: any) => {
58
+ if (res === 'ok') {
59
+ // 判断登录的时候,路由路径当中是否有query参数,如果有就往query参数跳转,没有跳转到首页
60
+ const redirect: any = route.query.redirect
61
+ router.push({path: redirect || '/'})
62
+ }
63
+ })
64
+ .finally(() => {
65
+ closeToast()
66
+ })
67
+ }
68
+ </script>
69
+
70
+ <style
71
+ scoped
72
+ lang="scss"
73
+ >
74
+ .login {
75
+ width: 100%;
76
+ height: 100%;
77
+ display: flex;
78
+ justify-content: center;
79
+ align-items: center;
80
+ }
81
+ </style>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="message">
3
+ <h2>message</h2>
4
+ </div>
5
+ </template>
6
+
7
+ <script
8
+ setup
9
+ lang="ts"
10
+ name="Message"
11
+ >
12
+ </script>
13
+
14
+ <style
15
+ scoped
16
+ lang="scss"
17
+ >
18
+ .message {}
19
+ </style>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="mine">
3
+ <h2>mine</h2>
4
+ </div>
5
+ </template>
6
+
7
+ <script
8
+ setup
9
+ lang="ts"
10
+ name="Mine"
11
+ >
12
+ </script>
13
+
14
+ <style
15
+ scoped
16
+ lang="scss"
17
+ >
18
+ .mine {}
19
+ </style>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="todo">
3
+ <h2>todo</h2>
4
+ </div>
5
+ </template>
6
+
7
+ <script
8
+ setup
9
+ lang="ts"
10
+ name="Todo"
11
+ >
12
+ </script>
13
+
14
+ <style
15
+ scoped
16
+ lang="scss"
17
+ >
18
+ .todo {}
19
+ </style>
@@ -0,0 +1,4 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ // * 为了解决 导入.tsx结尾的组件报错
4
+ declare module '*.tsx'
@@ -0,0 +1,24 @@
1
+ {
2
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
3
+ "compilerOptions": {
4
+ "baseUrl": "./",
5
+ "paths": {
6
+ "@/*": [
7
+ "src/*"
8
+ ]
9
+ },
10
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
11
+ /* Linting */
12
+ "strict": true,
13
+ "noUnusedLocals": true,
14
+ "noUnusedParameters": true,
15
+ "erasableSyntaxOnly": true,
16
+ "noFallthroughCasesInSwitch": true,
17
+ "noUncheckedSideEffectImports": true
18
+ },
19
+ "include": [
20
+ "src/**/*.ts",
21
+ "src/**/*.tsx",
22
+ "src/**/*.vue"
23
+ ]
24
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2023",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "verbatimModuleSyntax": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "erasableSyntaxOnly": true,
21
+ "noFallthroughCasesInSwitch": true,
22
+ "noUncheckedSideEffectImports": true
23
+ },
24
+ "include": ["vite.config.ts"]
25
+ }