Skip to content

Commit

Permalink
Merge pull request #1 from kbmjj123/feature-精简版本-2024-03-06
Browse files Browse the repository at this point in the history
Feature 精简版本 2024 03 06
  • Loading branch information
kbmjj123 committed Mar 22, 2024
2 parents 4effc6c + 53e4334 commit 0f7f59d
Show file tree
Hide file tree
Showing 28 changed files with 215 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .env.production
Expand Up @@ -20,7 +20,7 @@ VITE_GLOB_UPLOAD_URL=
VITE_GLOB_IMG_URL=

# 接口前缀
VITE_GLOB_API_URL_PREFIX = /api
VITE_GLOB_API_URL_PREFIX = /

# 是否启用gzip压缩或brotli压缩
# 可选: gzip | brotli | none
Expand Down
60 changes: 59 additions & 1 deletion README.md
Expand Up @@ -329,6 +329,7 @@ declare module '*.vue' {
```
:star2: 在对应的`postcss.config.js`中引入对应的依赖,并同时通过该插件所提供的参数,补充自定义的逻辑
```javascript

const fs = require('fs');
const postcssSprites = require('postcss-sprites');
// postcss.config.js
Expand Down Expand Up @@ -364,4 +365,61 @@ declare module '*.vue' {
})
]
}
```
```

#### 组件库使用过程记录
> 项目所使用的三方ui库为:[naive-ui](https://www.naiveui.com/zh-CN/os-theme),是一个仅能够在vue3.+以及typescript4.+以上版本,运行在现代浏览器上的UI组件库, :point_down: 将项目过程中的相关使用说明给列举出来,以便于后续自己方便查找。
##### 全局插件的的使用
> 在实际的编码过程中,难免需要使用到类似于`showLoading``showToast``showModal`等API,而且想以插件的形式来调用(也就是随时调用),那么需要进行以下的一个配置,在`naive-ui`中主要是`n-loading-bar-provider``n-dialog-provider``n-notification-provider``n-message-provider`
```vue
<!-- App.vue -->
<template>
<n-loading-bar-provider>
<n-dialog-provider>
<n-notification-provider>
<n-message-provider>
<RouterView></RouterView>
</n-message-provider>
</n-notification-provider>
</n-dialog-provider>
</n-loading-bar-provider>
</template>
```
:stars: 这里通过对全局路由对象进行一个包裹,使得在这个全局上下文中,都可以直接访问到外层节点provider,通过每个组件所提供的composite-api(相关的use*方法),可实现对组件的直接访问,如下代码所示:
```vue
<script lang="ts" setup>
import { useLoadingBar } from 'naive-ui'
const loadingBar = useLoadingBar()
loadingBar.start()
</script>
```
:trollface: 这样子之后,我们便能够直接在所有的组件中通过这个`use*`方法对全局组件的一个直接访问了!!

:confused: 而在以往的项目过程中,有时不单单需要在sfc组件中使用到这功能,像store这种非组件上下文或者是网络请求框架`axios`中需要使用到这个功能, :point_right: 我们有必要将它暴露到全局范围中(通过`window.$loadingBar`):
```typescript
import { createDiscreteApi } from 'naive-ui'
const { message, notification, dialog, loadingBar } = createDiscreteApi([
'message', 'dialog', 'notification', 'loadingBar'
], {/*其他参数配置*/})
//! 并将其挂载到全局window对象中
window['$message'] = message
window['$notification'] = notification
window['$dialog'] = dialog
window['$loadingBar'] = loadingBar
```
:+1: 上述通过这个`createDiscreteApi()`可直接引用到当前APP上下文中的已经包裹配置过的全局provider组件,实现一个全局直接访问调用的目的!!

##### 关于接口请求是否需要维护类型
> 在编码的过程中,难免需要与后端接口服务进行通讯, :confused: 那么是否需要声明对应的类型,用于描述各个接口的调用呢? :point_right: 答案是肯定的,虽然单纯的维护这个接口的数据结构会很繁琐,但是这这对我们在进行编码的过程中,对于代码的自动提示以及避免拼写错误,以及提前发现可能存在的代码漏洞有比较大的帮助,因此,建议还是尽量完善好对应的接口类型的声明,项目中由于是基于`axios`来进行发起网络请求的,这边针对`axios`的基础上搭建了一套基础的服务,因此,实际调用方仅需要简单的编写具体对应的业务逻辑接口即可,如下代码所示:
```typescript
// 获取当前登录用户信息
export function getUserInfo(): Promise<IUserState> {
return http.request({
url: '/user/info',
method: 'GET'
})
}
```
:star_struck: 这里我们声明了一方法`getUserInfo`,用于获取登录用户的信息,而且我们将其申明为一Promise响应方法,通过这样子定义,在实际该方法的调用方编写时,即可直接获取到响应结果的数据结构,如下图所示:
![针对声明的类型接口进行调用](./assets/针对声明的类型接口进行调用.png)
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 0 additions & 37 deletions mock/_mockProdServer.bundled_1708482306956_jm566s22q7j.mjs

This file was deleted.

29 changes: 0 additions & 29 deletions mock/_user.bundled_1708482306955_18xu6tjyexi.mjs

This file was deleted.

16 changes: 15 additions & 1 deletion mock/user.ts
Expand Up @@ -6,11 +6,25 @@ const token = Mock.Random.string('upper', 32, 32)

export default [
{
url: '/api/login',
url: '/api/user/login',
timeout: 1000,
method: 'post',
response: () => {
return resultSuccess({ token })
},
},
{
url: '/api/user/info',
timeout: 1000,
method: 'get',
response: () => resultSuccess({
username: 'kbmjj123',
avatar: Mock.Random.image('200x200', '#02adea', 'Koby'),
info: {
name: 'Koby',
email: 'kbmjj123@gmail.com',
phone: '13728009642'
}
})
}
] as MockMethod[]
2 changes: 1 addition & 1 deletion package.json
@@ -1,7 +1,7 @@
{
"name": "national-kb-admin",
"private": true,
"version": "1.0.0",
"version": "1.1.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
37 changes: 37 additions & 0 deletions src/api/account/account.ts
@@ -0,0 +1,37 @@
import { http } from '@/utils/http'
import type { BasicParams } from '../types'
import type { IUserState } from '@/store/modules/user'

// 获取当前登录用户信息
export function getUserInfo(): Promise<IUserState> {
return http.request({
url: '/user/info',
method: 'GET'
})
}

// 登录动作
export function login(params: BasicParams): Promise<{ token: string }> {
return http.request({
url: '/user/login',
method: 'POST',
params,
})
}

// 修改登录密码
export function changePassword(params: BasicParams) {
return http.request({
url: '/changepwd',
method: 'POST',
params
})
}

// 退出登录
export function logout() {
return http.request({
url: '/logout',
method: 'POST'
})
}
15 changes: 0 additions & 15 deletions src/api/account/user.ts

This file was deleted.

9 changes: 7 additions & 2 deletions src/api/types.ts
Expand Up @@ -9,12 +9,12 @@ export interface StringOrBooleanResponseModel extends BasicResponseModel {
}

//? 对象类型响应结果
export interface ObjectResonseModel<T> extends BasicResponseModel {
export interface ObjectResponseModel<T> extends BasicResponseModel {
data: T
}

//? 列表类型响应结果
export interface ArrayResonseModel<T> extends BasicResponseModel {
export interface ArrayResponseModel<T> extends BasicResponseModel {
data: {
list: Array<T>
total: number
Expand All @@ -28,3 +28,8 @@ export type BasicPageParams = {
pageSize: number
total: number
}

// 统一设置关于请求参数类型
export type BasicParams = {
[index: string]: any
}
1 change: 1 addition & 0 deletions src/components/Application/Application.vue
@@ -1,4 +1,5 @@
<template>
<!-- 全局调用的准备工作 -->
<n-loading-bar-provider>
<n-dialog-provider>
<n-notification-provider>
Expand Down
1 change: 1 addition & 0 deletions src/layout/components/AsideMenu/AsideMenu.vue
Expand Up @@ -83,6 +83,7 @@ const updateMenu = () => {
// }
updateSelectedKeys()
}
// 菜单点击事件
const clickMenuItem = (key: string) => {
if (/http(s)/?.test(key)) {
window.open(key)
Expand Down
7 changes: 7 additions & 0 deletions src/layout/components/Footer/Footer.vue
@@ -0,0 +1,7 @@
<template>
<div>
我是底部的footer
</div>
</template>

<script setup lang="ts"></script>
3 changes: 3 additions & 0 deletions src/layout/components/Footer/index.ts
@@ -0,0 +1,3 @@
import Footer from './Footer.vue'

export {Footer}
3 changes: 0 additions & 3 deletions src/layout/components/MainView/MainView.vue
@@ -1,9 +1,6 @@
<template>
<router-view>
<template #default="{ Component, route }">
<!-- <keep-alive>
<component :is="Component":key="route.fullPath"></component>
</keep-alive> -->
<component :is="Component" :key="route.fullPath" />
</template>
</router-view>
Expand Down
31 changes: 9 additions & 22 deletions src/layout/components/PageHeader/PageHeader.vue
@@ -1,16 +1,12 @@
<template>
<div class="layout-header">
<!--顶部菜单-->
<div
class="layout-header-left"
v-if="navMode === 'horizontal' || (navMode === 'horizontal-mix' && mixMenu)">
<div class="layout-header-left" v-if="navMode === 'horizontal'">
<div class="logo" v-if="navMode === 'horizontal'">
<img :src="websiteConfig.logo" alt="" />
<h2 v-show="!collapsed" class="title">{{ websiteConfig.title }}</h2>
</div>
<AsideMenu
v-model:collapsed="collapsed"
v-model:location="getMenuLocation"
:inverted="getInverted"
mode="horizontal" />
</div>
Expand Down Expand Up @@ -38,36 +34,25 @@
</div>
<!-- 面包屑 -->
<n-breadcrumb v-if="crumbsSetting.show">
<template
v-for="routeItem in breadcrumbList"
:key="routeItem.name === 'Redirect' ? void 0 : routeItem.name">
<template v-for="routeItem in breadcrumbList" :key="routeItem.name === 'Redirect' ? void 0 : routeItem.name">
<n-breadcrumb-item v-if="routeItem.meta.title">
<n-dropdown
v-if="routeItem.children.length"
:options="routeItem.children"
@select="dropdownSelect">
<n-dropdown v-if="routeItem.children.length" :options="routeItem.children" @select="dropdownSelect">
<span class="link-text">
<component
v-if="crumbsSetting.showIcon && routeItem.meta.icon"
:is="routeItem.meta.icon" />
<component v-if="crumbsSetting.showIcon && routeItem.meta.icon" :is="routeItem.meta.icon" />
{{ routeItem.meta.title }}
</span>
</n-dropdown>
<span class="link-text" v-else>
<component
v-if="crumbsSetting.showIcon && routeItem.meta.icon"
:is="routeItem.meta.icon" />
<component v-if="crumbsSetting.showIcon && routeItem.meta.icon" :is="routeItem.meta.icon" />
{{ routeItem.meta.title }}
</span>
</n-breadcrumb-item>
</template>
</n-breadcrumb>
</div>
<!-- 右侧菜单 -->
<div class="layout-header-right">
<div
class="layout-header-trigger layout-header-trigger-min"
v-for="item in iconList"
:key="item.icon">
<div class="layout-header-trigger layout-header-trigger-min" v-for="item in iconList" :key="item.icon">
<n-tooltip placement="bottom">
<template #trigger>
<n-icon size="18">
Expand Down Expand Up @@ -120,6 +105,8 @@
import { ref, reactitve, toRefs, computed, unref } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useDialog, useMessage } from 'naive-ui'
import './components'
import websiteConfig from '@/config/websiteConfig'
const props = defineProps<{
collapsed: boolean
Expand Down
3 changes: 3 additions & 0 deletions src/layout/components/PageHeader/index.ts
@@ -0,0 +1,3 @@
import PageHeader from './PageHeader.vue'

export {PageHeader}
9 changes: 9 additions & 0 deletions src/layout/components/TagsView/TagsView.vue
@@ -0,0 +1,9 @@
<template>
<div>
<!-- -->
</div>
</template>

<script setup lang="ts">
</script>
3 changes: 3 additions & 0 deletions src/layout/components/TagsView/index.ts
@@ -0,0 +1,3 @@
import TagsView from "./TagsView.vue";

export { TagsView }

0 comments on commit 0f7f59d

Please sign in to comment.