第1章 简介
我们在学习新技术的时候,习惯于将官方文档先过一遍,将全部的知识点全部掌握之后,再进行项目实战,但是因为太多都是概念的知识,学习过程枯燥乏味,很少有人能坚持下来。
所以我在想,怎么改变这种现象?以我个人的经验来说,过多深究官方文档,反而将自己陷入知识点的海洋之中,抓不到重点,往往水过鸭背,因为学了没有真正应用,不久之后就会忘记,我的意思是,不用看什么官方文档,以终为始,不用管自己到底会不会,直接上手开发项目,根据当前的需求,去学习对应的知识点,比如现在你要生成一个 Vue3.0 项目,那么你可能只需要去学一下Vite对应的知识点就好了,不用去学Vue3.0中父子组件应该怎么传值?比如你要学习开发一个登陆页面,那你就需要去看Element-Plus应该怎么引入?如果你所学并不能为当下所用,那将毫无意义。
其实在你一步一步完成真实项目的过程中,就一直在学习Vue3.0的知识点了。
本书计划将 Vue3.0
的知识过一遍,所以一些 Vue2.0
就需要的环境配置就不再过多说明,只会提到 Vue3.0
开发环境配置相关的内容,用到的技术有 Vue3.0+Vite+TypeScript+Element-Plus+Less
。
第2章 开发环境配置
2.1 新建项目
在 Vite官方文档 中,已经提供了很多预设的模板,这里因为只关注当前使用的技术,所以其他模板并不详细说明,使用 Vite
生成 Vue3.0
项目模板,如果是使用 JaveScript
进行开发,使用 vue
,如果是使用 TypeScript
进行开发,使用 vue-ts
,具体命令如下所示:
# npm 6.x
npm init vite@latest my-vue-app --template vue
# npm 7+, 需要额外的双横线:
# 如果是使用JaveScript开发,使用vue
npm init vite@latest my-vue-app -- --template vue
# 如果是使用JaveScript开发,使用vue-ts
npm init vite@latest my-vue-app -- --template vue-ts
打开chrome,就会显示项目模板的内容,如下图所示:
2.2 Chrome 91版本以上跨越问题
第3章 Vue3.0基础知识
3.1 Router
3.2 Comand
3.3 Porps
3.4 Emit
3.5 Vuex
3.5.1 computed
computed
主要用于涉及到视图更新的处理,比如用户名username的更新,刷新后,右上角用户名没有赋值成功。在App.vue
中已经添加了getUserInfo
的网络请求,但是在右上角上赋值显示失败了。
使用方式如下所示,并没有触发视图更新:
const username = store.state.userInfo.username
触发视图更新:
improt { useStore } from 'vuex'
const store = useStore()
const username = computed(() => {
return store.state.userInfo.username
})
userInfo敲定刷新后的获取策略
通过在App.vue中重新发起请求获取用户信息
问题:1.登录页面刷新因为没有token会报错,解决可以加上判断,但是代码很难看。
2.每个组件中都需要watch监听usrInfo,很繁琐。
登录后将用户信息保存在localStorage,刷新后通过vuex中获取
问题: 1.如果更新了用户信息,刷新后获取的还是旧的数据
2.在getters.ts中判断数据为空就重新发起网络请求,获取用户信息,但是因为异步的原因,数据并没有同步。
登录后触发commit,然后在mutations.ts中,将用户信息保存到localStorage,刷新后通过vuex获取。
问题: 1.需解决刷新后还是旧数据的问题,那就需要更新后,通过commit更新localStorage中的用户信息
最终确定以方式3实现:
使用方式:
import { useStore } from 'vuex' let userInfo = store.getters.userInfo
在ZHeaderArea.vue中的 let userInfo = computed(() => { return store.state.userInfo })
改为getter获取就报错
### 3.5.2 watch
`watch`用于监听数据有变化触发,用于需要对数据进行操作时使用,比如个人中心,刷新后,使用`computed`方式`userInfo`没有成功获取,原因是`<template>`上并没有使用userInfo进行关联。
```tsx
let userInfo = store.state.userInfo
setUserInfoListValue(userInfo)
watch(
() => store.state.userInfo,
(newValue, oldValue) => {
userInfo = newValue
setUserInfoListValue(userInfo)
}
)
function setUserInfoListValue(info: any) {
userInfoList.forEach((item: any) => {
for (var key in info) {
if (item.prop === key) {
item.content = info[key] ? info[key] : '--'
}
}
})
}
3.5 Vite.config.ts
3.5.1 如何设置路径别名
在项目中,因为组件或者ts文件引入,需要指定路径,如果文件层级很深,在开发中就会变得很繁琐,使用别名可以有效的解决这个问题。
第一步,需要在vite.config.ts文件中加上,如下所示:
const path = require('path')
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
......
})
第二步,需要在tsconfig.json文件中加上,如下所示:
{
"compilerOptions": {
......
"baseUrl": "./",
"paths": {
"@/*":["./src/*"]
}
}
此时,就可以在项目中使用@了。
第4章 搭建项目框架
4.1 Container布局容器
4.1 左侧菜单栏实现
左侧菜单栏,实现过程中遇到了一个问题,那就是el-aside的宽度默认是300px,项目中需求是200px,这个不难,只需要在
中设置width=“200px"就可以解决了,然后如果要实现展开和收缩,就需要设置 ,而它的宽度需要单独设置的 ,设置为200px,实现展开和收缩功能,收缩时宽度变为60px,但是 还是200px,其实要实现联动,只需要动态设置width的值就好了,但是实现左侧菜单栏,我们通常是单独抽成组件来使用的,这样要联动就很麻烦,其实要实现也是可以的,使用props就好了,但我还是想着有没有更好的方法,有什么办法能够动态设置 的宽度? 因为去掉
的宽度属性发现, 实现的效果是很理想的,后来发现只需要设置width为auto即可 左侧菜单栏,如何使用组件递归实现?
el-menu折叠时为何不显示二级菜单?
当菜单栏折叠时,发现首页的图标没有显示,实现的代码如下所示:
<el-menu-item v-if="!item.childrens" :index="`${String(index)}`" :route="item.index"> <template #title> <div class="zws-aside-menu-item"> <i :class="`zws-aside-menu-item-iconSetting iconfont ${item.icon}`"></i> <span>{{ item.title }}</span> </div> </template> </el-menu-item>
之前的项目没有这个问题是因为不是使用collapse这个属性实现的,而是动态设置宽度,200和60切换达到的效果。查看官方文档的案例,发现这个写法,当折叠时,是显示图标的,如下所示:
<el-menu-item index="4"> <i class="el-icon-setting"></i> <span slot="title">导航四</span> </el-menu-item>
然后按照官网的写法,将去掉就没再出现这个问题了。
点击左侧菜单栏,没有触发路由跳转?
原因是:在
组件中忘记加上router了 路由跳转到新的页面,怎么让新的页面是在
组件中的? 需要设置嵌套路由,而且path设置时需要/,但是子路由path前面不用加/。
当
的width设置为auto时,出现多余边框,如下图所示: 但是如果把width设置为200px,是没有这个问题的,问题应该出在
组件上面,当把它设置width为200px时,实际上 的width是201px,这个1px到底是从哪里来的?
4.2 主题色切换
4.2.1 在项目中改变 SASS 变量
由于Element-Plus处于开发状
态,所以官方文档里并没能做到实时更新,导致按照提供的方式,其实出现了很多问题,经过研究,当前版本,正确的配置方式为:
在项目目录新建
element-variables.scss
文件,并加上覆盖的样式代码:/* 改变主题色变量 */ $--colors: ( "primary": ( "base": #80b33f, ), ); /* 改变 icon 字体路径变量,必需(将~去掉,不然不显示图标) */ $--font-path: "element-plus/lib/theme-chalk/fonts"; /* 将~改为node_modules后,确实解决了路径引用报错的问题,但是项目每次刷新都很慢,需持续留意解决方案*/ @import "node_modules/element-plus/packages/theme-chalk/src/index.scss"; /* 一般以上就够满足需求了,其他设置*/ $--colors: ( "primary": ( "base": #003261, ), "success": ( "base": #21ba45, ), "warning": ( "base": #f2711c, ), "danger": ( "base": #db2828, ), "error": ( "base": #db2828, ), "info": ( "base": #42b8dd, ), );
在项目
main.ts
文件中引入import App from './App.vue'; import ElementPlus from 'element-plus'; import { createApp } from 'vue' import { router } from './router/index'; import './assets/iconfont/iconfont.css' // 引入 element-variables.scss 文件 import '../element-variables.scss' const app = createApp(App) app.use(ElementPlus) app.use(router) app.mount('#app')
4.2.2 命令行主题工具
如果项目中没有使用SASS,推荐使用这个方式。
在使用Elment-Plus时,打算切换主题色,安装官方文档实现,运行
et -i
时,显示如下报错信息:Run `npm audit` for details. weihao@weihao-mac-mini vue3.0 % et -i fs.js:45 } = primordials; ^ ReferenceError: primordials is not defined at fs.js:45:5 at req_ (/usr/local/lib/node_modules/element-theme/node_modules/natives/index.js:143:24) at Object.req [as require] (/usr/local/lib/node_modules/element-
这个原因是因为Node.js版本过高导致的,官方推荐最好小于12版本。
4.3 项目部署服务器
项目部署服务器的时候,发现console里显示报错,没有加载到相关js等等问题,原因是在vite.config.ts
文件中少了设置base:'./'
,再次部署,加载资源文件没有显示报错,但是页面显示空白,这是因为router/index.ts
文件中,指定的路由模式为history: createWebHistory()
,需要改为history: createWebHashHistory()
,这两种模式的差别可看一下文章:VUE3.0 createWebHistory和createWebHashHistory
第5章 其他问题
- Vue3.0项目中引入.js文件,打包报错的问题
@mouseenter 和 @mouseleave事件闪烁问题
不是后来才了解到,只能父子元素形成,不可以兄弟元素,兄弟元素就会闪烁
本书待补充知识点记录
vuex使用指南,pinia使用指南,其与vuex的区别在哪里?
vue项目,vscode中debug使用指南
提供vue学习路线,包括js、html、css、vue、vite、element plus等等