本文已参与「新人创作礼」活动,一起开启掘金创作之路
这里我们继续构建src。
plugins 项目插件配置
这里主要是引入一些开发中需要用到的插件,并进行自定义配置,比如ECharts
、Element-Plus
、Vxe-table
、i18n
...
Element-Plus 举例
本项目我们使用Element-Plus作为主要的 UI 组件框架。
由于Vue 3
不再支持IE11
,Element Plus
也不再支持IE
浏览器
这里我们先安装
pnpm install element-plus
以前组件我们都是按需导入,目前官网推荐我们安装几款插件来支持按需导入,你可能要依赖插件手动导入样式,还可能要手动加载非组件模块(比如
ELMessage
)。这种方式不仅在开发上带来许多麻烦,还会影响Vite
热重载的速度,让你打开页面会更慢,所以我们使用全局引入的方式(期待有更好的解决方案吧!)。
引入
// main.ts
import App from "./App.vue";
import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
const app = createApp(App);
app.use(ElementPlus);
app.mount("#app");
使用
关于
element-plus
有一个地方需要注意:element-plus
默认语言为英文,使用一些组件时(如分页组件)会发现默认字体是英文,这时候我们需要转换为英文。
将element-plus
默认语言改为中文
<!-- App.vue -->
<template>
<el-config-provider :locale="currentLocale">
<router-view />
</el-config-provider>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { ElConfigProvider } from "element-plus";
import zhCn from "element-plus/lib/locale/lang/zh-cn";
export default defineComponent({
name: "app",
components: {
[ElConfigProvider.name]: ElConfigProvider,
},
data() {
return {
currentLocale: zhCn,
};
},
});
</script>
当然如果你想做国际化,如中英文切换,只需要将英文也引入,使用计算属性来实现。
<!-- App.vue -->
<template>
<el-config-provider :locale="currentLocale">
<router-view />
</el-config-provider>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { ElConfigProvider } from "element-plus";
import zhCn from "element-plus/lib/locale/lang/zh-cn";
import en from "element-plus/lib/locale/lang/en";
export default defineComponent({
name: "app",
components: {
[ElConfigProvider.name]: ElConfigProvider,
},
computed: {
currentLocale() {
return this.$storage.locale?.locale === "zh" ? zhCn : en;
},
},
});
</script>
router 项目路由
我们采用Vue.js
官方路由 Vue-Router来创建单页应用,将我们的组件都映射到路由上。
引入 Vue-router
安装
pnpm install vue-router
定义路由
首先创建我们的路由文件夹router
,并为该文件夹提供一个出口文件index.ts
。项目所有的路由都采用模块化管理(不同的业务流或者页面模块分别在各自的页面中配置路由)。
路由出口
我们使用router-view
来将路由匹配到的组件进行渲染,放在我们的根组件(App.vue
)下,
<template>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view />
</template>
<script setup lang="ts"></script>
配置基础 router
我们先创建一个单文件组件example.vue
(放在src
目录下创建的views
页面文件中)
<!-- 测试案例 -->
<script setup lang="ts"></script>
<template>
<h1>example...</h1>
</template>
<style scoped></style>
建立路由与组件的映射
// src\router\modules\example.ts
const exampleRouter = {
path: "/example", // 当前组件的url地址
component: () => import("/@/views/example.vue"), // 按需引入组件
};
export default exampleRouter; // 记得默认导出
配置基本 router
// src\router\index.ts
import { createRouter, createWebHistory, Router } from "vue-router";
import exampleRouter from "./modules/example"; // 引入路由模块
const routes = [exampleRouter];
// 创建路由实例
export const router: Router = createRouter({
history: createWebHistory(), // 使用 hash 模式
routes: routes, // 传入我们所有的路由
strict: true, // 开启严格模式
});
export default router; // 导出我们的路由
引入项目中
// main.ts
import App from "./App.vue";
import router from "./router"; // 引入
import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
const app = createApp(App);
// 确保整个应用支持路由
app.use(router).use(ElementPlus);
app.mount("#app");
效果示例
store 状态管理
状态管理我们不再使用以前常用的Vuex
,而是使用 Pinia(PS:pinia
官网的代码字体,属实是爱的不能再爱了,太好看了叭!),我们看看Pinia
的优势:
- 提供了
Composition-API
风格的API
- 完整可靠的
TypeScript
支持 - 将
mutations
移除,action
被调度为常规函数使用 - 极其轻巧(体积约 1KB)
- 支持多个
Store
- 支持
Vue devtools
、SSR
渲染
安装
pnpm install pinia
store
文件结构跟router
一样
配置并引入
创建我们的pinia
出口
// src\store\index.ts
import type { App } from "vue";
import { createPinia } from "pinia";
const store = createPinia();
export function setupStore(app: App<Element>) {
app.use(store);
}
export { store };
引入
// src\main.ts
import App from "./App.vue";
import router from "./router";
import { setupStore } from "/@/store"; // 引入
import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
const app = createApp(App);
setupStore(app); // Configure store
app.use(router).use(ElementPlus);
app.mount("#app");
使用举例
// src\store\modules\example.ts
import { store } from "/@/store";
import { defineStore } from "pinia";
export const useTestStore = defineStore({
id: "huohuo-test", // 为当前store命名唯一id
state: () => ({
// store中存放的数据
msg: "I am HuoHuo!",
}),
getters: {
getMsg() {
return this.msg;
},
},
actions: {
// 操作store中数据的方法
handleMsg(val) {
this.msg = val;
},
},
});
// 以函数的形式返回
export function useTestStoreHook() {
return useTestStore(store);
}
<!-- 测试案例 -->
<script setup lang="ts">
import { ref } from "vue";
import { useTestStoreHook } from "/@/store/modules/example";
const message = ref("Hello HuoHuo");
function useMsg() {
message.value = useTestStoreHook().msg;
}
function changeMsg() {
useTestStoreHook().handleMsg("你好啊!");
}
</script>
<template>
<h1>example...</h1>
<h2>{{ message }}</h2>
<el-button @click="useMsg">测试store的msg</el-button>
<el-button @click="changeMsg">测试store的handleMsg</el-button>
</template>
<style scoped></style>
案例效果展示
style 样式库
我们的CSS
采用Sass来支持,因为我们使用的 Element-Plus 也是使用的Sass
,我们保持一致性。项目的大部分样式都放在这里,包括CSS
初始化文件、插件样式更改文件、自定义样式等。
Sass 安装
pnpm install sass -D
我们在src
根目录下建立style
样式文件,并初始化一些 CSS。
// src\style\index.scss
body {
width: 100%;
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizelegibility;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
}
html {
width: 100%;
height: 100%;
box-sizing: border-box;
}
#app {
width: 100%;
height: 100%;
}
引入 Windi CSS
写样式是一件比较费时间的事情,所以这里我们使用Windi CSS
这个CSS
框架工具,它既能够在开发中让我们十分便捷地写CSS
,又能提供更快的加载体验和更快的HMR
,而且,它是基于TS
开发的!
安装
pnpm install -D vite-plugin-windicss windicss
使用这个插件时,记得在VSCode
中安装该插件的扩展WindiCSS IntelliSense
,能够在开发中给你非常友好的提示。
引入
使用
自定义配置
我们需要在根目录下创建一个windi.config.ts
文件,进行配置(个性化配置较多,大家可自行上官网查阅相关示例)。
import { defineConfig } from "windicss/helpers";
export default defineConfig({
/* 配置项... */
});
scoped
在vue
文件中编写style
样式时,记得添加scoped
属性,如果没有加,默认会被编译成全局样式,可能会造成全局样式污染。
<style scoped></style>
使用
scoped
后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的scoped CSS
和子组件的scoped CSS
的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。
utils 方法库
一个存放着整个项目中使用到的具有一定功能性的工具方法的库,方便统一管理我们封装的方法。
App.vue
项目的根组件,是页面的入口文件,实际上所有的单页面都在该页面下进行切换。一般来说,我们会在这里配置项目路由的入口、项目全局的配置、国际化等功能。
main.ts
项目应用的入口文件,项目所有的插件或依赖都从这里引进,始终服务于后面的开发。