项目概述与搭建
项目概述:使用Vue.js实现多人共享博客
吹逼:一个基于 Vue3 + Pinia + TypeScript + Vite2 + ant-design-vue 完整技术路线开发的项目,秒级开发更新启动、新的vue3 composition api 结合 setup纵享丝滑般的开发体验、全新的 pinia状态管理器和优秀的设计体验(1k的size)、antd无障碍过渡使用UI组件库 ant-design-vue、安全高效的 TypeScript 类型支持
- 该项目使用 Vue3 实现了一个在线博客分享的平台。包含首页、用户文章列表、个人管理等页面,实现了登录、注册、编辑、发布等功能。
- 项目使用 Vite2 为编译打包工具创建项目模版。之后考虑升级到
Vite3 - 使用 SCSS 作 CSS 预处理,使用 Grid 作页面布局,使用 Ant-Design-Vue 作UI组件
- 通过 Vue Router 实现路由的跳转、异步加载、权限验证等
- 通过 Pinia 实现状态管理
- 用 Axios 获取数据,并对接口进行了封装
介绍文字
- 一个基于 Vue 3 / TypeScript / SCSS 和 Vite 2 构建的单页面应用
- 这是我从自己记录学习笔记的需求出发,设计出的极简博客应用, 特点是使用
markdown语法快速记录技术博客,并且实现不同用户博客共享 - 主要功能包括 前端页面的登录、注册、首页文章列表展示、博客详情展示、博客创建、发布、编辑和删除(
markdown格式)、我的页面和其他用户文章列表展示等。 实现的步骤已总结为 博客 - 使用了开源的后端API接口,并用 Axios 封装请求,实现对应的 拦截器 和 JWT 身份认证功能 并且使用了 ApiPost 接口测试工具,导出详细的 接口文档 ,让我对鉴权和接口封装有了一定的认识和实践
- 该项目使用基于
Composition API实现的Vue3 Hooks,让我对hooks有了深刻的理解和应用。 项目中的 hooks,代替之前项目中使用的 mixin 写法 解决mixin缺点 - 尝试完全使用
TSX和CSS module语法代替 模板SFC,将使用心得总结为博客 - 使用了
Pinia作为统一的状态管理,对组件通信有了 新的理解
项目信息
- 设计稿
- 项目预览地址: https://xmasuhai.xyz/vite-share-blog-website/#/
- 项目功能包含:
- 首页:展示所有作者设置到首页的博客列表
- 详情:展示博客详情
- 登录、注册: 用户登录注册
- 用户页面: 展示某个用户的所有博客列表
- 我的: 展示个人主页
- 编辑、删除、创建博客,博客是以
markdown格式编写
- 项目使用
Vue.js技术栈的 单页面应用,版本为Vue 3.2Vue全家桶:- 脚手架
vite2.X代替vue-cli和webpack - 路由
vue-router4 - 状态管理
pinia代替vuex4 vitest- 使用
JSX语法与组合式API es6语法- 封装
axios - UI框架采用
ant-design-vue - 后期更换为自己造的轮子UI框架
axios及api接口封装、jwt等Hooks库使用vueUse
- 后端使用饥人谷的共享博客后端接口,共享博客接口文档
- 后期自己搭建服务器,使用
Node.js编写后端代码
- 后期自己搭建服务器,使用
大纲链接 §
[toc]
项目搭建 ⇧
初始化项目 ⇧
Node.js@16pnpm代替yarn- 在安装时项目时
- 如果使用
pnpm create vite就一直使用pnpm - 如果使用
yarn create vite就一直使用yarn
- 如果使用
使用vite搭建vue-ts项目 ⇧
|
|
选
vue-ts1 2 3 4 5 6# 安装依赖 pnpm install # 开发预览 pnpm dev # 打包 pnpm build
配置智能提示
使用 defineConfig 工具函数,这样不用 jsdoc 注解也可以获取类型提示:
Vite 直接支持 TS 配置文件。可以在
vite.config.ts中使用defineConfig工具函数1 2 3 4 5import { defineConfig } from 'vite' export default defineConfig({ // ... })
配置 ip 访问项目 ⇧
vite 启动后出现
Network: use --host to expose1 2 3 4vite v2.7.13 dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose是因为
IP没有做配置所以不能从
IP启动需要在
vite.config.js做相应配置在
vite.config.js中添加server.host为0.0.0.01 2 3 4 5 6 7 8 9 10import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], server: { host: '0.0.0.0' } })重新启动
pnpm dev后显示1 2 3 4 5 6 7 8 9vite v2.7.13 dev server running at: > Network: http://172.27.128.1:3000/ > Network: http://192.168.0.109:3000/ > Local: http://localhost:3000/ > Network: http://172.25.176.1:3000/ > Network: http://172.25.224.1:3000/ ready in 692ms.
vite创建的初始项目目录 ⇧
|
|
vite创建代码简单分析 ⇧
- 可以看到
index.html中的入口文件导入方式<script type="module" src="/src/main.ts"></script>的类型为type="module"支持模块化导入 - 框架代码中
main.ts中就可以使用ES6 Module方式组织代码,不用再转译为低版本的模块化方式
*区别于使用vue/cli搭建vue-ts项目
- 使用古老的
@vue/cli搭建vue-ts项目,不推荐使用pnpm 使用
yarn即可1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38cd ~ vue create share-world # Choose # Manually select features ---- # Choose Choose Vue version (*) Babel (*) TypeScript (*) Progressive Web App (PWA) Support (*) Router (*) Vuex (*) CSS Pre-processors (*) Linter / Formatter >(*) Unit Testing ( ) E2E Testing ---- # Choose # 3.x ---- # Choose # y ---- # Choose # y ---- # Choose # n ---- # Choose # Sass/SCSS (with dart-sass) ---- # Choose # ESLint with error prevention only ---- # Choose # ( ) Lint on save >(*) Lint and fix on commit ---- # Choose # Jest ---- # Choose # In dedicated config files ---- # Choose # N cd share-world yarn serve注意,使用
@vue/cli构建的项目,许多依赖已经停止维护deprecated1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32λ pnpm install WARN deprecated eslint-loader@2.2.1: This loader has been deprecated. Please use eslint-webpack-plugin WARN deprecated html-webpack-plugin@3.2.0: 3.x is no longer supported WARN deprecated @hapi/joi@15.1.1: Switch to 'npm install joi' WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained WARN deprecated @hapi/address@2.1.4: Moved to 'npm install @sideway/address' WARN deprecated @hapi/topo@3.1.6: This version has been deprecated and is no longer supported or maintained WARN deprecated @hapi/hoek@8.5.1: This version has been deprecated and is no longer supported or maintained WARN deprecated har-validator@5.1.5: this library is no longer supported WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain cir cumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. WARN deprecated @hapi/joi@15.1.1: Switch to 'npm install joi' WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain cir cumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fse vents 2. WARN deprecated @hapi/hoek@8.5.1: This version has been deprecated and is no longer supported or maintained WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies WARN deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x. WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated WARN deprecated core-js@2.6.12: core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even i f nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.
配置 scss 全局样式文件 ⇧
- 需要先配置别名
虽然
vite原生支持less/sass/scss/stylus,但是你必须手动安装他们的预处理器依赖
- 安装依赖
dart-sass,但包的名字为sass 不要安装为
dart-sass:deprecated dart-sass@1.25.0: This package has been renamed to 'sass'.1 2# yarn add sass --dev pnpm add sass -D
在
src/assets下新增style文件夹,用于存放全局样式文件
新建
src/assets/style/main.scss, 设置一个用于测试的颜色变量 :1$test-color: red;配置
vite.config.ts,让vite识别scss全局变量1 2 3 4 5 6 7 8 9 10... css:{ // 指定传递给 CSS 预处理器的选项 preprocessorOptions:{ scss:{ additionalData:'@import "@/assets/style/main.scss";' } } }, ...
在任意组件中使用,不需要任何引入可以直接使用全局
scss定义的变量
|
|
移动端适配 px to viewport(vw/vh)
使用
postcss-px-to-viewport,将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件
- 样式需要做根据视口大小来调整宽度,这个脚本可以将你CSS中的px单位转化为vw,1vw等于1/100视口宽度
换用
@jonny1994/postcss-px-to-viewport支持TS引入配置文件
vite.config.ts
|
|
参考
- vite css.postcss
- Jonny-china/postcss-px-to-viewport
- miari-adaptive 自适应布局方案对比:饿了么移动端方案(postcss-px-to-viewport)、网易移动端方案(rem+vw)
- 移动端布局之postcss-px-to-viewport(兼容vant)
- Vue移动端 / PC端适配解决方案:postcss-px-to-viewport
- postcss-px-to-viewport使用
- postcss-px-to-viewport 移动端适配方案
- postcss-px-to-viewport之vw、vh、rem
- 前端使用postcss-px-to-viewport实现移动端或者PC端自适应
- 2022 年移动端适配方案指南 — 全网最新最全
对TS的相关配置 ⇧
vue/cli项目中shimes-vue.d.ts文件的作用
- 为了
typescript做的适配定义文件,因为.vue文件不是一个常规的文件类型 ts是不能理解.vue文件是干嘛的 加这个文件是是告诉 ts,.vue文件是这种类型的。
vite项目中env.d.ts文件的作用
- 为了声明 在
vite中使用env环境的配置 可以通过import.meta.env.<变量名称来访问>
vue-tsc和tsc
tsc只能验证 ts 代码类型vue-tsc可以验证ts + Vue Template中的类型(基于 Volar)
JSX支持 ⇧
Vue 3 JSX 相关语法
使用
tsx风格代替template模板方式,需要注意相应改变的地方:
src/router/引入页面文件.tsx代替.vue文件src/main.ts修改引入App文件.tsx代替.vue文件
安装依赖插件
|
|
配置
tsconfig.json,在.tsx文件里支持JSX
|
|
改造
App.vue为App.tsx
|
|
- 运行命令
pnpm dev查看效果
在*.tsx文件中使用css modules ⇧
- 只有在
*.tsx文件中可以正常使用
配置
vit.config.ts
|
|
定义一个
*.module.scss或者*.module.css文件创建
src/styles/app.module.scss1 2 3 4 5 6 7 8.app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; }
在
*.tsx中引入使用改写
App.tsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19import HelloWorld from '@/components/HelloWorld.vue'; import {defineComponent} from 'vue'; import appClass from '@/styles/app.module.scss' // css modules import logoImg from '@/assets/logo.png'; // static assets // 用defineComponent定义组件且要导出 export default defineComponent({ render: () => ( <main class={appClass.app}> <img alt="Vue logo" src={logoImg}/> <HelloWorld msg="Hello Vue 3 + TypeScript + Vite"/> <router-link to="/">Go to Home</router-link> <router-link to="/about">Go to About</router-link> <router-view></router-view> </main> ), });
样式文件
xxx.module.scss中定义类样式.yyy {...}引入到
*.tsx文件后,在模板中使用<main class={xxx.yyy}>...</main>
如何优雅的在TSX语法中切换多个className?
|
|
- 使用第三方包
classnames - 安装
pnpm add classnames - 引入
import classname from 'classnames'
上述代码可替换为:
|
|
或者使用数组
|
|
和普通样式写在一起
|
|
参考
TSX基础语法 ⇧
替换v-bind语法
|
|
|
|
tsx天然支持属性的动态绑定- vue3 v-bind 文档
替换v-model语法
|
|
|
|
- 注意使用
v-model时,必须明确父组件的监听自定义事件名称xxx,和子组件发布事件的名称update:xxx - TSX 支持的更多 v-model 写法
替换v-for语法
|
|
|
|
- 此处如果
item是一个对象,可以用解构语法来取出对象属性 - 需要指定
key属性,来优化diffkey属性使用数据中的唯一id作为值
替换v-if跟v-else语法
|
|
|
|
/* v-else */
|
|
|
|
- 更多条件判断使用表
替换@click等事件
|
|
|
|
- 监听事件想到用
onChange,onClick等 - 需要注意的是
- 传参数不能使用
onClick={this.removePhone(params)} - 这样子会每次
render的时候都会自动执行一次方法 - 应该使用
bind,或者箭头函数来传参
- 传参数不能使用
原生事件必须监听到存在对应事件的标签上,比如
input标签的input事件,否则报错1 2 3 4 5 6 7 8 9// tsx <button type="button" onClick={this.handleClick.bind(this, 11)}> 使用bind传参 </button> <button type="button" onClick={(/*event: MouseEvent*/) => this.handleClick(11)}> 使用箭头函数 </button>
JSX 自定义事件
- 需要在子组件的选项中声明
emits: ['diyEvent'], - 父组件中使用 on + 驼峰式命名 的形式,例如
<Son onDiyEvent={...}/>
使用自定义事件
- 要声明一个自定义事件:
onHandleSubmit - 子组件
- 声明选项
emits: ['handleSubmit',], - 在
setup选项中传参setup(props, ctx) {} - 定义 发布方法
const clickHandler = () => {ctx.emit('handleSubmit');} - 返回
return {clickHandler} - 在
render方法中使用render() {return <button onClick={this.clickHandler}></button>}
- 声明选项
- 父组件
- 在
setup选项中 - 定义 处理逻辑的方法
const clickHandler = () => {} - 在
render方法中使用自定义事件<UserSubmitBtnTip onHandleSubmit={this.clickHandler}/>
- 在
判断键盘抬起时,键盘值
- 自定义组件中有
<input/>,事件keyup不能绑定在自定义组件上,而是绑定在内部的的<input/>上 - 通过
props传一个keyUpHandler到内部 - 无修饰符,只能使用
event: KeyboardEvent中的event.key来判断,是否按下Enter键["Enter"].includes(event.key)
UserInput.tsx
|
|
Login.tsx
|
|
参考
- Vue JS - Conditional keyup.enter is not working stackoverflow
- JSX Introduction by facebook
- Using Vue 3 with JSX and TypeScript
- Lightweight Components with Vue 3 and JSX
- Programming VIP Vue-3 props, $emit, slot, render, JSX and createElement
- Vue3 Listening to Events
- Vue3 Declaring Emitted Events
- Emitting and Listening to Events
- How to emit event from JSX functional component in Vuejs
- 在vue3中编写jsx的两种方式
- vue中正确使用jsx语法的姿势分享1
- vue中正确使用jsx语法的姿势分享2
- 在vue中使用jsx的正确姿势3
- vue使用typeScript+jsx报错问题
用监听事件来实现 v-modal 双向绑定
|
|
事件修饰符
和指令一样,除了个别的之外,JSX 中大部分的事件修饰符都无法在像模板那样直接使用
替代方案:
.stop: 阻止事件冒泡,在TSX中使用event.stopPropagation()来代替.prevent:阻止默认行为,在TSX中使用event.preventDefault()来代替.self与.enter:只当事件是从侦听器绑定的元素本身触发时才触发回调,使用下面的条件判断进行代替1 2 3 4 5 6 7 8 9 10 11// tsx if (event.target !== event.currentTarget){ return ... } // .enter与keyCode: 在特定键触发时才触发回调 if(event.keyCode === 13) { // 执行逻辑 }
使用
vue自带的withModifiers()方法
|
|
替换插槽v-slot
-
1 2 3 4 5 6 7 8// vue <template> <van-nav-bar title="标题" left-text="返回" left-arrow> <template #right> <van-icon name="search" size="18" /> </template> </van-nav-bar> </template>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43// tsx <van-nav-bar title="标题" left-text="返回" left-arrow v-slots={{ 'left': () => <van-icon name="search" size="18" /> }} ... // 子组件 export default defineComponent({ name: "Test", render() { return ( <> <span>I'm Child</span> { this.$slots.default?.() } { this.$slots.header?.() } </> ) } }) // 父组件 import TestComponent from './TestComponent' export default defineComponent({ name: "Test", components: { TestComponent }, render() { return ( <TestComponent v-slots={{ default: () => ( <>这是默认插槽</> ), header: () => ( <>这是header插槽</> ) }}> </TestComponent> ) } }) 父组件通过
v-slots属性去定义插槽,子组件直接在render中通过this.$slots[name]去获取
作用域插槽
作用域插槽在JSX中的写法也一样,只需要将scope作为参数传递即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21// vue // 子组件 <template> <div> <span>I'm Child</span> <slot name="content" :value="value"></slot> </div> </template> <script setup> const value = ref({name: 'xzw'}) </script> // 父组件 <template> <TestComponent> <template #content="scope"> {{ scope.value.name }} </template> </TestComponent> </template>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42// tsx // 子组件 import { defineComponent } from "@vue/runtime-core"; export default defineComponent({ name: "Test", setup() { return { value: { name: 'xzw' } } }, render() { return ( <> <span>I'm Child</span> { this.$slots.content?.(this.value) } </> ) } }) // 父组件 import TestComponent from './TestComponent' export default defineComponent({ name: "Test", components: { TestComponent }, render() { return ( <TestComponent v-slots={{ content: scope => ( <>{scope.name}</> ) }}> </TestComponent> ) } })作用域插槽
this.$slots.default?.(this.value)this.$slots.content?.(this.value)
参考
- vue中 jsx 的语法使用详解
- Vue3 + TS 开发前端组件库 丨走进 JSX
- 使用 JSX/TSX 开发 Vue3 组件
- 以 JSX 的方式来编写 Vue3 代码
- Vue3 开发一个基础的的 tabs 组件 - 体验 JSX 的灵活性
- vite2.x+vue3搭建项目,使用jsx开发(建议收藏,多多点赞)
- JSX + Vue3 + Vant 实现 网易云播放器
- vue3组合式 API配合JSX实现高阶组件使用踩坑记录
- huawei developer
- Vue3.0在JSX/TSX下如何使用插槽(slot)
- Vue3.0在JSX/TSX下如何使用插槽(slot)
vite 常用插件
自动导入插件 unplugin-auto-import/vite ⇧
setup语法让我们不用再一个一个的把变量和方法都return出去就能在模板上使用,大大的解放了我们的双手- 然而对于一些常用的Vue API,比如ref、computed、watch等,还是每次都需要在页面上手动进行import
- 可以通过unplugin-auto-import实现自动导入,无需import即可在文件里使用Vue的API
- 自定义组件自动引入
unplugin-vue-components - vue3等插件 hooks 自动引入,Api 自动引入
unplugin-auto-import/vite - message, notification 等引入样式自动引入
vite-plugin-style-import eslint脱敏插件vue-global-api
参考文章:
- 尤大推荐的神器unplugin-vue-components,解放双手…
- 用vite重构了vuecli的模版项目
- 插件会生成一个ui库组件以及指令路径
components.d.ts文件,详情看这个vue3的issue
自动导入组件unplugin-vue-components ⇧
- 借助
unplugin-vue-components这个插件
安装
|
|
配置
vite.config.ts
|
|
- 直接写组件名即可,插件会自动引入进来 注意别重名
自动导入vue3的hooks ⇧
- 原本 vue 的 api 需要自行 import
- 借助
unplugin-auto-import/vite这个插件 - 支持
vue,vue-router,vue-i18n,@vueuse/head,@vueuse/core等方法自动按需引入
效果
|
|
|
|
目前模板支持自动引入 api 的库列表包括:
- vue
- pinia
- vueuse
- vue-router
安装
|
|
vite.config.ts配置
|
|
- 原理: 安装的时候会自动生成
auto-imports.d文件(默认是在根目录下src/auto-imports.d) - 可以选择
auto-import.d.ts生成的位置,使用ts建议设置为src/auto-import.d.ts - 其他插件 vue-router, vue-i18n, @vueuse/head, @vueuse/core等自动引入的自动引入请查看文档
vue-global-api 解决未显示导入依赖导致 eslint 报错 ⇧
- 在页面没有显示引入的情况下,使用
unplugin-auto-import/vite来自动引入hooks时 - 在项目中肯定会报错的,这时需要在
eslintrc.js中的extends引入vue-global-api - 这个插件是
vue3hooks的,其他自己找找,找不到的话可以手动配置一下globals vue-global-api文档
自动UI库引入样式插件vite-plugin-style-import ⇧
- 当你使用
unplugin-vue-components来引入ui库的时,message, notification 等引入样式不生效 - 安装
vite-plugin-style-import即可 vite-plugin-style-import文档
setup name 增强插件 ⇧
- 使用setup语法糖带来的第一个问题就是无法自定义name属性
- 而使用
keep-alive往往是需要定义name的 - 解决这个问题通常是通过写两个script标签来解决,一个使用
setup,一个不使用 - 但这样必然是不够优雅的,见 5个知识点,让 Vue3 开发更加丝滑
- 借助插件
vite-plugin-vue-setup-extend可以更优雅的解决这个问题 - 不用写两个
script标签,可以直接在script标签上定义name
安装
vite-plugin-vue-setup-extend
|
|
配置
vite.config.ts
|
|
在
setup语法糖中使用name属性
|
|
引入svg图标 ⇧
使用现成的vite插件,有三个选择:
- 推荐 vite-plugin-svg-icons
- unplugin-icons (改名前身为
vite-plugin-icons,默认使用Iconify图标库) - Vite SVG loader
vite-svg-loader单独引入*.svg文件文件,封装为Vue组件使用 - 使用
svgo和svgstore自己写vite插件
- Vite项目使用插件 vite-plugin-svg-icons 生成 svg 雪碧图 封装SvgIcon组件
- 最佳实践参考:vitecamp
- 汇总最近遇到的几个问题 vite-svg-loader是什么,如何使用?
参考 使用 阿里巴巴
iconfont
- 在vue3+vite项目中使用svg
- SVG Sprite在Vite应用
- vue3 vite 封装svg
- 真香定律!vite2配置篇vite.config.js(基础篇)
- 从 16 个方向逐步搭建基于 vue3 的前端架构 - 封装 SVG 的图标组件
- vite-svg-loader是什么,如何使用?
- Vue 3 + Vite仿YesPlayMusic网易云 SVG
- Vue3打造SVG设计器+图标库
- vue实战之从零搭建Vite2+Vue3全家桶(三)
- Vue实战之从零搭建Vite2+Vue3全家桶(三)
- 迁移vue-cli到vite吗?我把坑都给你踩了
- SVG在VUE3上的配置与使用
- svg动态改变颜色以及在vite的应用
- vite工程化实践
- vue中引入.svg图标,使用iconfont图标库
- 在vite中使用svg(vue)
- 优雅的在vue3.0+vite项目中管理自己的Icon
手动自制
vite插件src/plugins/svgBuilder.js
- SVG在 VUE3 上的配置与使用 非使用
svg-sprite-loader手动封装vite插件 - vue3 + vite 中封装svg icon组件
- Vue3 + vite+ts 中使用svg-icon
- vue3 + vite+ts项目中使用svg图标
- 在vue3 + vite项目中使用svg
- JetBrains/svg-sprite-loader How to use svg-sprite-loader with vite #434
- SVG Sprite在Vite应用
- vite+vue3下如何使用动态导入的svg-sprite雪碧图
第三方图标库 Iconify
- 基于
Iconify实现的 vite svg 插件 unplugin-icons - 优雅的在vue3.0 + vite项目中管理自己的Icon Iconify + vue3 + vite
- Vue3打造 SVG 设计器 + 图标库
https://juejin.cn/post/7063415079928070157 | 前端工程化之SvgIcon组件 - 掘金 https://juejin.cn/post/6990159719558021133 | 工程化使用 SVG 图标最佳实践 - 掘金 https://juejin.cn/post/7055878408365932557 | 2022年大厂前端必备,开箱即用的Vue3+Vite2最强模板 - 掘金 https://juejin.cn/post/7062681169627709448 | iconfont的原理与实践 - 掘金 https://juejin.cn/post/7000560093804625957 | icones:支持即时搜索的图标资源管理器,尤雨溪等开发者赞助支持 - 掘金 https://juejin.cn/post/7067418893899268103 | 采用 @svgr/webpack 支持 svg 作为组件引入 - 掘金 https://juejin.cn/post/6863414887931084814 | Vue项目中使用svg小图标,可修改大小颜色 - 掘金 https://juejin.cn/post/7017657405265674271 | vue工程使用svg图片,svg-sprite-loader缺陷,你们的按需加载svg是错误的。 - 掘金 https://juejin.cn/post/6975380991762235422 | 当webpack有了vite的速度你会喜欢吗? - 掘金
markdown 插件,用户文本输入文章,插件渲染成网页 ⇧
安装
marked
|
|
引入
|
|
参考
- markedjs/marked
- Marked Documentation
- highlightjs/highlight.js
- GitHub Markdown CSS demo
- sindresorhus/github-markdown-css
- cure53/DOMPurify
- How to render Markdown field in Vue3? by stackoverflow markedjs & dompurify
- Build A Vue.js Markdown Renderer Component with marked.js and highlight.js
其他
markdown方案
- vue3-markdown-it
- A Vue 3 markdown-it wrapper plugin
- vite-plugin-md
- vite-plugin-md2vue
- 最佳实践参考:vitecamp
- 最佳实践参考:vitecamp
其他插件
- vite-plugin-mock-server
- vite-plugin-remove-console 生产环境删除console.log的vite插件
- vite-plugin-dynamic-base
- 资源压缩插件 vite-plugin-compression
vite项目中安装vue-router@4 ⇧
- 需要先配置别名
alias,将src/映射为@,详见插件部分
在 src 文件下新增 router 文件夹 =>
index.ts文件,内容如下:
- 使用
hash模式的createWebHashHistory方法生成实例,原理为监听window.onhashchange事件,无需后端配置 使用
history模式的createWebHistory方法生成实例,原理为监听window.onpopstate事件,需要后端配置(由history.pushState()或history.replaceState()触发,popstate)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16import {createRouter, /*createWebHistory, hash 模式 */ createWebHashHistory, RouteRecordRaw} from 'vue-router'; const routes: RouteRecordRaw[] = [ { path: '/', name: 'Login', component: () => import('@/pages/login/Login.vue'), // 注意这里要带上 文件后缀.vue }, ]; const router = createRouter({ history: createWebHashHistory(), // hash 模式 routes, }); export default router;
修改入口文件
mian.ts:
|
|
到这里路由的基础配置已经完成了,更多配置信息可以查看
vue-router官方文档:
vue-router: https://next.router.vuejs.org/zh/guide/vue-router4.x支持typescript,配置路由的类型是RouteRecordRaw,这里meta可以让我们有更多的发挥空间,这里提供一些参考:title:string;页面标题,通常必选。icon?:string;图标,一般配合菜单使用。auth?:boolean;是否需要登录权限。ignoreAuth?:boolean;是否忽略权限。roles?:RoleEnum[];可以访问的角色keepAlive?:boolean;是否开启页面缓存hideMenu?:boolean;有些路由我们并不想在菜单中显示,比如某些编辑页面。order?:number;菜单排序。frameUrl?:string;嵌套外链。
keep-alive缓存路由
对axios的封装 ⇧
安装
|
|
导入
|
|
使用
|
|
安装pinia ⇧
安装
|
|
导入
|
|
使用
|
|
代替安装vuex ⇧
安装
|
|
导入
|
|
使用
|
|
vite其他配置 ⇧
- 别名配置
- 配置
scss全局样式文件 css modulesmockjs模拟数据配置- 配置多环境变量
- 动态导入环境配置
esbuild一些打包配置
别名配置 ⇧
导入
path的时候提示报错,需要安装@types/node类型检测1pnmp add @types/node -D
修改
vite.config.ts文件配置
|
|
修改
tsconfig.json文件配置
|
|
mockjs模拟数据配置
安装
|
|
配置
package.json字段script > dev
|
|
配置
vite.config.ts
|
|
supportTs: true,是否用了ts,可以根据自己选择true or false- 要将
watchFiles: true,文件夹监听打开,这样更改mock的时候,不需要重新启动编译
使用
- 在与
node_modules同级 目录建立mock目录 mock目录下建立mock文件user.ts1 2 3 4 5 6 7 8 9 10 11 12 13 14 15import { MockMethod } from 'vite-plugin-mock' export default [ { url: '/api/getUser', method: 'get', response: (req: Record<string, unknown> /*拿到请求的数据*/) => { // console.log('body>>>>>>>>') return { code: 0, message: 'ok', data: ['aa', 'bb'] } } } ] as MockMethod[]
使用
1 2 3 4 5 |
// 代码请求
axios.get('/api/getUser')
.then(res => {
console.log(res)
}) |
- 这里就配置完成了
参考
- vite2配置mockjs
- vite + vue3 + setup + pinia + ts 项目实战
- 方案:Vue 集成 Mock.js
- 在vue3中加入mock模拟请求,并介绍本地代理如何管理mock请求以及服务器请求
- vite + typesctipt+mockjs搭建mock环境
- 备战2021:vite工程化实践,建议收藏
- 关于 vite.config.js 相关配置,拿走不谢
- vue3+vite+ts+vuex+vue-router+Element-plus+tailwindcss+mock 搭建完整项目
- vite.config.js常用配置
- Vite项目中使用插件 apite 进行数据mock
按照接口文档模拟数据
- 后端使用饥人谷的共享博客后端接口,共享博客接口文档
入口
api-mock.ts
|
|
https://juejin.cn/post/7032926228055556126 | vite + typesctipt+mockjs搭建mock环境 - 掘金 https://juejin.cn/post/6910014283707318279 | 备战2021:vite工程化实践,建议收藏 - 掘金 https://juejin.cn/post/7039879176534360077 | 关于 vite.config.js 相关配置,拿走不谢 - 掘金 https://juejin.cn/post/7053717060295065614 | vue3+vite+ts+vuex+vue-router+Element-plus+tailwindcss+mock 搭建完整项目 - 掘金 https://juejin.cn/post/7028481421022855175 | vite.config.js常用配置 - 掘金 https://www.cnblogs.com/linbudu/p/11375775.html | Vue项目中引入Mock.js & Mock.js语法整理 - 林不渡 - 博客园 https://github.com/nuysoft/Mock/wiki/Mock.mock() | Mock.mock() · nuysoft/Mock Wiki · GitHub https://github.com/enjoycoding/vite-plugin-mock-server | GitHub - enjoycoding/vite-plugin-mock-server: A mock server plugin for Vite. https://juejin.cn/post/6901615700364918791 | vue中mock.js的使用 - 掘金 https://juejin.cn/search?query=vite-plugin-mock-server | vite-plugin-mock-server - 搜索 - 掘金 https://juejin.cn/post/6993740289605124126 | vite-plugin常用的插件 - 掘金 https://juejin.cn/post/7000283590642630687 | Vue3 + Vite2 + Vue-Router 4.x + Vuex 4.x + Element-Plus + Axios + Mockjs 项目搭建 - 掘金 https://juejin.cn/post/6936771237452464165 | VUE3 项目开发实战入门系列 (7.-Mock接口) - 掘金 https://juejin.cn/post/6844903492235034632 | Mockjs,再也不用追着后端小伙伴要接口了 - 掘金 https://github.com/Tencent/APIJSON | GitHub - Tencent/APIJSON: 🚀 零代码、热更新、全自动 ORM 库,后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构。 🚀 A JSON Transmission Protocol and an ORM Library for automatically providing APIs and Docs. https://juejin.cn/post/7048916480032768013 | 「前端该如何优雅地Mock数据🏃」每个前端都应该学会的技巧 - 掘金 https://juejin.cn/post/7043420433613324325 | Vite + Vu3项目中 Mockjs 插件的学习使用 - 掘金 https://juejin.cn/post/7040701806887993381 | 两个项目实例+常用语法解析带你掌握Mock.js✨ - 掘金 https://www.cnblogs.com/student007/p/15180190.html | (o゚v゚)ノ Hi - vite使用mock插件(vite-plugin-mock)记录 https://www.jianshu.com/p/72fffae58761 | vite2+vue3项目中引入vite-plugin-mock - 简书 https://www.cnblogs.com/leiting/p/15125707.html | vite mock 数据插件:vite-plugin-easy-mock - c-137Summer - 博客园 https://www.npmjs.com/package/cross-env | cross-env - npm https://www.jianshu.com/p/e8ba0caa6247 | cross-env使用 - 简书
配置开发/生产环境变量 ⇧
基本概念
import.meta.url
不单单是开发环境或生产环境,api 请求的域名会根据不同环境而不同
- 线上环境 和 测试环境 在打包策略有所不同「如线上要隔离sourceMap、屏蔽vue|react devtools等…」
- 前端 SPA 组件根据不同环境做出不同逻辑
环境变量和多环境适配的 Vite 实现
dev开发环境test测试环境beta公测版环境release生产发布环境
- 环境变量
.env - 把系统配置放到
config/constant.ts管理了 - 为了方便管理不同环境的接口和参数配置
- 可以使用环境变量
.env - 如
.env.development、.env.production - 配合
vite + import.meta.env使用
参考
动态导入环境配置 ⇧
安装
|
|
导入
|
|
使用
|
|
esbuild一些打包配置 ⇧
vite.config.ts完整配置 ⇧
|
|
项目结构与组件样式 ⇧
布局
|
|
App.tsx根组件
|
|
App.tsx根组件按需引入UI组件库样式App.tsx根组件使用provide提供全局message方法App.tsx根组件引入布局组件Layout.tsx
布局组件
Layout.tsx
|
|
layout.module.scss
|
|
- layout 布局只控制页面结构,组件具体的样式在各自组件中写
在
<BlogHeader/>组件中,判断用户是否登录,从而展示不同的登录样式
|
|
src/styles/blog.module.scss
|
|
其他静态页面 ⇧
src/pages/blog/index/BlogIndex.tsx
|
|
``
|
|
参考文章 ⇧
- vite + vue3 + ts 现代开发最佳实践
- 尤大推荐的神器unplugin-vue-components,解放双手…
- 用vite重构了vuecli的模版项目
- 5个知识点,让 Vue3 开发更加丝滑
- 基于pnpm搭建monorepo项目
相关文章
- 无
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名