现在前端框架越来越像后端了,特别是TypeScript这样的语言出现后,开发前端的体验跟后端渐渐接近了。当然,作为一个后端,直接上手前端,还是有很多坑要填的。
本次开发,前端页面框架直接选择Vue。原因很简单,用的人多,之前没用过。
一顿搜索,各个官网文档看下来,采用Vue3 + Element UI Plus。作为CSS低手,有一个成熟的UI框架可以节省不少事情,特别是现在这些框架都是模块化,组件化的。跟WebForm时代的控件思想一脉相承,降低了使用难度,赞!
开搞……
首先开始创建项目,有两个选择,Vue 的 create, ElementUI Plus的starter,本着学习的态度,从vue的create开始吧。
1. 创建vueDemo
npm create vue@latest
, 然后全部选是。
根据推荐,使用VS Code进行开发,打开后,命令行依次执行上图绿色命令。
页面出来了:
到此为止,都是so easy。
2. 引入Element UI Plus
这里面官方文档上就是一堆引入方法,第一次完全没有看懂。所以采用了最笨最直接的方法,就是对比文件。对比的就是刚刚创建的vueDemo和 starter。
Vue脚手架下的 package.json
{"name": "vuedemo","version": "0.0.0","private": true,"scripts": {"dev": "vite","build": "run-p type-check \"build-only {@}\" --","preview": "vite preview","test:unit": "vitest","test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'","test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'","build-only": "vite build","type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false","lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore","format": "prettier --write src/"},"dependencies": {"pinia": "^2.1.7","vue": "^3.3.4","vue-router": "^4.2.5"},"devDependencies": {"@rushstack/eslint-patch": "^1.3.3","@tsconfig/node18": "^18.2.2","@types/jsdom": "^21.1.3","@types/node": "^18.18.5","@vitejs/plugin-vue": "^4.4.0","@vitejs/plugin-vue-jsx": "^3.0.2","@vue/eslint-config-prettier": "^8.0.0","@vue/eslint-config-typescript": "^12.0.0","@vue/test-utils": "^2.4.1","@vue/tsconfig": "^0.4.0","cypress": "^13.3.1","eslint": "^8.49.0","eslint-plugin-cypress": "^2.15.1","eslint-plugin-vue": "^9.17.0","jsdom": "^22.1.0","npm-run-all2": "^6.1.1","prettier": "^3.0.3","start-server-and-test": "^2.0.1","typescript": "~5.2.0","vite": "^4.4.11","vitest": "^0.34.6","vue-tsc": "^1.8.19"}
}
Element-plus-vite-starter 下的package.json
{"name": "element-plus-vite-starter","private": true,"version": "0.1.0","scripts": {"dev": "vite","build": "vite build","generate": "vite-ssg build","preview": "vite preview","typecheck": "vue-tsc --noEmit"},"dependencies": { "element-plus": "^2.3.12","vue": "^3.3.4"},"devDependencies": {"@iconify-json/ep": "^1.1.12","@types/node": "^20.6.0","@vitejs/plugin-vue": "^4.3.4","sass": "^1.66.1","typescript": "^5.2.2","unocss": "^0.55.7","unplugin-vue-components": "^0.25.2","vite": "^4.4.9","vite-ssg": "^0.23.1","vue-tsc": "^1.8.11"},"license": "MIT"
}
通过对比可以发现, dependencies只需要安装element-plus,但是devDependencies 则需要其它内容,参照Element UI Plus文档 按需导入
安装unplugin-vue-components 和 unplugin-auto-import这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
因为之前脚手架默认使用了Vite,则修改Vite配置文件vite.config.ts
修改后,会发现目录下多了 auto-imports.d.ts 和 components.d.ts 两个文件
可以看到,这两个文件内容都是自动生成的。
3. 调整页面代码
下图左侧是vueDemo的main.ts,右侧是Element Plus Vite Starter 的 main.ts。
可以看到不同的地方集中在css上,这里使用了unocss,安装为开发依赖项。
npm install -D unocss
同时,修改vite.config.ts,这里注意反复修改过好几次,最后定稿如下:
import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'import path from 'path'
const pathSrc = path.resolve(__dirname, 'src')import Unocss from 'unocss/vite'
import {presetAttributify,presetIcons,presetUno,transformerDirectives,transformerVariantGroup,
} from 'unocss'// https://vitejs.dev/config/
export default defineConfig({css: {preprocessorOptions: {scss: {additionalData: `@use "~/styles/element/index.scss" as *;`,},},},plugins: [vue(),vueJsx(),AutoImport({// Auto import functions from Vue, e.g. ref, reactive, toRef...// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等imports: ['vue'],// Auto import functions from Element Plus, e.g. ElMessage, ElMessageBox... (with style)// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)resolvers: [ElementPlusResolver(),// Auto import icon components// 自动导入图标组件IconsResolver({prefix: 'Icon',}),],dts: path.resolve(pathSrc, 'auto-imports.d.ts'),}),Components({resolvers: [// Auto register icon components// 自动注册图标组件IconsResolver({enabledCollections: ['ep'],}),// Auto register Element Plus components// 自动导入 Element Plus 组件ElementPlusResolver({importStyle: 'sass',}),],dts: path.resolve(pathSrc, 'components.d.ts'),}),Icons({autoInstall: true,}),// https://github.com/antfu/unocss// see unocss.config.ts for configUnocss({presets: [presetUno(),presetAttributify(),presetIcons({scale: 1.2,warn: true,}),],transformers: [transformerDirectives(),transformerVariantGroup(),]}),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url)),'~/': `${pathSrc}/`,}}
})
要特别说明的是,有些文章中,ElementPlusResolver 没有任何参数,因为之前已经引入了Sass,会导致页面样式错乱。
另外,对路径`~/`的解析,是在上面代码最后一行。关于这个我的理解是在页面代码中引用其它文件时对src目录引用的一种快捷方式,可以是 ~/, 也可以是其它符号。
4. 复制页面布局
修改App.vue文件,复制BaseSide.vue等组件,按starter的样子搞一下,还有styles目录,assets下的logo.svg等等。
另外,
最后就是执行
npm run dev
呃,报错 Failed to resolve import "@element-plus/icons-vue" from "src\components\layouts\BaseSide.vue". Does the file exist?
又是一顿搜,原来这个组件已经独立出来,@element-plus/icons-vue 需要单独安装,没啥说的,继续安装。 参考 这篇文档,其中自动导入参考 这个示例
终于排除了种种困难,页面效果如下:
这篇文章只是简单的从vue脚手架中,引入了ElementUI Plus,本身没啥可说的,但是在引入过程中,明白了package.json , tsconfig.json, vite.config.ts 这三个文件的作用。配置性的内容应该都在这三个文件里了,所以有哪里不对,多半都是这三个文件的配置不对。