第一板块
注意
- 前端这块重点搞js,多花点时间复习拓展js板块的知识
- 更多的针对知识点问为什么,以及是什么
- npm 的文件包不能有大写字母,单词之间用 - 连接
- 由于webpack 基于Node开发的工具,所以其配置文件采用的是 CommonJS模块化规范
- 入口:可以是相对路径,规律:能用相对路径的地方一般都可以用绝对路径,但用绝对路径的地方,大多不支持相对路径
- 平时写代码(src目录)都是使用ES6 的模块化方法,只有在webpack的配置文件中时
webpack.config.js用CommonJS模块化规范 - yarn安装的所有包都是开发依赖
- 如果要将文件打包,就需要将文件和入口文件形成引用关系
补充
- 如果要用commonJS导出的话,就用
module.exports导出,不要直接用exports导出 - script标签中的
defer="defer"属性,等待html页面加载之后再运行标签内容
<script defer="defer" src="bundle.js"></script>
- 三种导入方式
- 图片标签的src只能设置两种值,URL和BASE64
- 用live server打开页面是通过服务器打开
webpack
- 定义:静态模块打包工具
- 功能:减少文件数量,缩减代码体积
- 提高网页打开速度
webpack 入口和出口文件
注意: 就是说必须要设置入口文件,出口文件能够通过执行命令自动生成,就是说必须创建一个src文件,并且文件下需要有个index.js文件
webpack 打包流程
打包js文件
打包html文件-插件
打包css文件
将css文件引入到入口文件中,导入css就用import '路径'
注意:
- webpack默认只能处理js文件,如果需要打包其他文件,就需要引入其他文件打包的模块,也就是说,除了js文件不需要另外下载模块,其他文件都需要下载模块
- 这个模块不需要require引入
打包less文件
打包图片文件
注意: 不用下载模块
打包字体图标
各种文件打包设置
- js文件(不需要下载loader)
- html文件(需要)
- css文件(需要)
- less文件(需要)
- 图片文件(不需要下载loader)
- 字体图标(不需要下载loader)
图片处理区别
注意: 这是webpack对于图片的自动处理,8kb以下的小图片能自动转成base64
bable 降级
需要下载这几个包
解决bug
- 描述bug
- 什么原因
- 自己尝试过哪些事情
webpack开发服务器
-
以前把文件从硬盘读出来放在内存中,webpack处理读取的内容,再把文件放到出口(
硬盘) -
现在通过webpack的服务器能够从硬盘读出来的内容放在
内存中.(实现代码自动运行,打包变化的代码,就不用每次手动打包,不用每次重新打开页面看效果) -
作用: 解决每次需要手动打包的问题,服务器模块能够实现自动打包
需要设置模式
- 平时开发的时候用
yarn serve,平时开发时mode用development - 项目上线时用
yarn build, 项目上线时mode用production
需要配置端口
注意: 只有配置了端口之后才能实现改动代码之后页面实时渲染(服务器端口提取的是内存中的数据,如果不设端口就提取的是硬盘中的数据)
第二板块
vue板块学习方法
- 考虑怎么做报错总结
- 每天把知识点自测弄懂
- 知识点文档总结
- 知识点xmind总结
注意
- 工程化开发方式: 在webpack环境中开发vue
脚手架
- 重点留意其中的几个文件
- 文件中的关系
eslint语法检测
注意: 能够在变量不使用时提醒,在现阶段不用在乎变量问题,避免因为报错找不出的问题
单vue文件的好处
- js独立的作用域互不影响,因此不用担心变量名冲突的问题
- style标签的scoped属性能够让样式只作用于当前页面
- template里只能有一个根标签
补充
- 表达式:有结果的式子
MVVM设计模式(视图模型层)
vue语法
v-bind
v-bind:能够简写成:
v-on
v-on:能简写成@
- vue的on事件,函数中能实现传参
事件对象的获取方式有两种
- 有传参
- 无传参
阻止默认行为和阻止冒泡
第三板块
注意
- 重绘和回流
- 回流(重排): 当浏览器必须重新处理和绘制部分或全部页面时,回流就会发生
- 重绘: 不影响布局, 只是标签页面发生变化, 重新绘制
- 注意: 回流(重排)必引发重绘, 重绘不一定引发回流(重排)
- vue的重要思想是用数据驱动DOM树,而不是直接操作DOM树
- v-html 会覆盖其中的插值表达式
- vue没有帮我们装包,比如各种loader,需要手动下载,但不需要在config.js文件中配置 5. vue 会根据数据尽可能保留原有dom树,只更新由于数据变更影响的dom树,因此在性能上提升很大
修饰符
- 事件修饰符(针对所有事件都可以用,比如
.stop.prevent) - 键盘修饰符(只有键盘事件能用)
双向绑定(表单元素)
- 作用: 插值表达式是单向绑定,表单元素是双向绑定
- 用法: 将
v-model="变量"放入表单标签中,当改变变量数据时,页面会发生变化,同样,当用户在页面输入数据时,同样变量也会发生改变
复选框: v-model绑定复选框时分两种情况,由变量的类型决定
- 数组
- 非数组(最终都会转成boolean)
应用场景:
- 全选反选功能(非数组)
- 考试系统(数组)
- 收集用户信息(数组)
注意: v-model要写在select标签上,并且其中option标签的value需要有内容(value用于传参发送后端)
表单元素总结:
v-model的修饰符
注意:其中lazy 双向绑定同步数据的时机默认是 input(实时监控) 事件,lazy就是改为了 change(改变并失去焦点时) 事件
v-show 和 v-if 和 v-else
注意:
- v-show只是将当前标签设置display:none,不会将标签从dom树上移除; v-if 会重新创建元素并插入到dom树
- v-show有较大的初始渲染开销; v-if有较大的切换渲染开销
- 其中的v-else 表示当v-if不显示的时候,else显示; 必须紧贴着v-if书写,其间不能书写其他标签,注释除外;
- 代码如果只有一行的话,可以不用绑定事件,直接写在引号中,同时注意调用变量不要用this
- 第8行的代码很有意思
案例
- 注意第7行和第8行代码
v-for案例
数组的方法
注意
- 直接修改数组索引,不会更新的bug : vue2的设计缺陷(只有vue2才有这个问题,vue3不会有),使用this.$set(数组,数组下标,修改值)
重绘和回流
- 回流(重排): 当浏览器必须重新处理和绘制部分或全部页面时,回流就会发生
- 重绘: 不影响布局, 只是标签页面发生变化, 重新绘制
- 注意: 回流(重排)必引发重绘, 重绘不一定引发回流(重排)
虚拟DOM
- 频繁操作真实DOM很耗费性能,因此vue设计生成虚拟DOM树,并且根据变更数据局部更新虚拟DOM树
key
- 无key的情况:就地复用
- key设置为index: 等于没设,还是就地复用
- 因此将key设置为id,虚拟DOM树会根据key更新
- key值要求唯一不重复的字符串或数值
- 结论: 有id用id,没有id用索引(但是索引在重绘时也会有问题)
- key能提高更新的性能
- 有key值为索引, 基于key的来比较新旧虚拟DOM, 移除key不存在元素
标签的class和style设置
注意:
- 引号中是一个对象,并且属性值为变量时,如果变量和类名一致,还可以用解构简写
- class中对象的属性值为布尔值; style中对象的属性值为样式的属性值,都可以设为变量,并且用逗号可以拼接多个css样式
报错
- 这是当id的上一层数据不存在的时候会报错,因为
undefined.id而报错
注意: 当时这个错误出现在,案例删除最后一个数据后,其中有一项是要根据数据中最后一项的id动态生成新的id,因为没有数据,所以找不到数据中的id
案例思路:
第四板块
补充
-
作用域
-
开发依赖和项目依赖的区分: 看项目上线之后还用不用(比如axios上线之后还要用,那么就放在项目依赖中,像webpack的包如果项目上线之后不用,就可以放在项目依赖中)
-
二进制无法准确表示小数,可以用
数字.toFixed(2)表示保留两位小数,这是number类型的方法 -
用数组方法reduce进行求和计算
-
moment模块能够将呈现出想要的时间格式
moment(time).format('YYYY-MM-DD')
注意
-
能用"或"的地方就不要用三元运算符(这个地方出现在当||左边)
-
v-model返回的数据类型
计算属性
注意:
- 计算属性如果只用一次,那么和函数没有区别,优势在于多次使用时,计算属性第一次计算时所依赖的变量和返回的结果会存在缓存区中
- 计算属性中的属性(用函数的形式写),在调用的时候不要添加
(),不然会报错
计算属性实现双向绑定
- get获取函数属性值的时候执行
- set修改函数属性值的时候执行
监听器
-
浅度侦听
-
深度侦听(如果侦听的目标是对象)
注意:存在一个bug,深度侦听中的newVal和oldVal一样
案例 - 深度侦听
注意
组件
描述: 组件是可复用的vue实例(对象),封装标签,样式和js代码
注意:
- 利用的vue组件(一个组件就是一个vue文件)局部作用域的特点,能够实现局部独立开发互不影响
- 一个组件就是一个vue实例对象
组件的使用步骤
注意:
- 全局组件注册,注意Vue.component ,只能单个注册
- 局部注册,components ,可以同时注册多个
scoped 的作用
组件通信,父向子,props
注意:
- 子组件的变量名设在props中的数组中,并且是字符串的形式
- 子组件中的标签能够通过插值表达式传递props中的变量
- 父组件中在标签中设置属性的方式传递给子组件props中的变量
- 父向子传值的意思是通过app.vue父组件 向 其他子组件传值
- props 单向数据流,如果是父组件传递给子组件的数据,不能在子组件中直接修改,如果修改,父组件是无法收到更新的数据
单向数据流
补充:
- 不允许在子组件中修改数据,只能在app.vue中修改数据.
子传父
第五板块
vue 生命周期
bug
初始化阶段
注意: 把变量挂到vue组件的对象身上
- beforeCreate 钩子函数不能拿到data函数中的变量数据,访问data数据的最早的钩子是created
- 发请求一般放在create中发(发请求越早越好,但不能早过create钩子函数)
- option一般指的是配置对象
$mount的作用是用来挂载,将指定的组件挂载到 #app处,也可以用el: '#app'的方式书写- $mount和el: '#app' 的区别: 如果说在创建对象到设置el之间,还想做点其他事,那么就只能用$mount
- created钩子函数能获取data数据,但不能获取真实DOM
vue 挂载阶段
注意: 这里的render函数稍稍解释了下,可以查查
注意:
- beforeMount还没有创建真实DOM, 到mounted 才挂载了真实DOM
- mounted用得比较少,vue不建议直接对真实DOM进行操作,使用频率比created少
- 当组件执行到mounted钩子时,进入到稳定状态,此时页面也加载完成
更新阶段
- 只有当数据变化
之后才执行beforeUpdate 函数,然后再进行真实树的打补丁,完成之后再执行updated函数 - beforeUpdate不能获取更新后的真实DOM,但是可以获取更新后的数据,updated可以获取更新后的真实DOM
补充
注意: 只有当数据变化之后才执行beforeUpdate 函数
销毁阶段
- 应用场景: 全局定时器的清除,全局事件的清除
第六板块
针对 "父组件向子组件中传值,并在子组件中改变变量" 的问题
原理解释
注意:
- 只要没有修改从父组件传过来的数据的地址,就可以对数据进行修改,并且父组件能够更新(这种情况可以实现在子组件中修改数据
this.list.push({...})) - 子组件不能对父组件传递过来的数据直接赋值(指的是这种情况不行: 在子组件中
this.list=[],只要list的地址不被修改就行)
头部自定义
补充:
props有哪2种定义方式, 区别是?
- props: [] - 只声明变量, 不能类型校验
- props: {} - 声明变量和校验类型规则 - 不对则报错
为什么自己挂载到vue组件对象中的变量和方法没有$开头,官方方法都是用$开头,避免自己定义的变量和官方方法重名,如果重名并调用,会优先使用自己的(写法不受限制,只是约定俗称)
补充
-
reduce中需要注意的点
-
将axios方法挂载到Vue的原型上,并且给官方的方法设置美元符号
- 使用(在created函数中发送请求,拿到数据并赋值给data中的数据)
插槽
注意:
- template 只是起到包裹区分代码块的作用,没有什么限制,可以放很多根元素,template不会被渲染到页面上
v-slot:能设置在template上,可以省写为#
多个插槽
插槽和具名插槽区分
作用域插槽
- 往插槽slot上绑定数据,
:row ="变量名"(其中的row是约定俗称的属性,不是必须用这个名字) - 使用插槽时接收
v-slot="变量名",作用域插槽只能在设置的template的内部使用 - 右边的slot还可以绑定多个数据,都会同时传递到左边的scope对象中
自定义指令
全局注册和局部注册
注意: 局部注册的指令只能在当前的vue使用
局部注册
注意: 表示当前元素在插入DOM树时,执行insert函数,其中函数el参数能够拿到当前标签(这里实现的是刷新自动获取标签)
vue获取DOM元素的方式
步骤
- 给标签设置ref属性
- 使用
this.$ref.ref属性获取DOM元素
通过$ref获取组件对象
- 在当前组件拿到其他组件对象时,能够实现跨组件操作其他组件的数据(可以实现不用传值操作数据)
- 一般是用来获取组件对象中封装的方法
针对 "数据更新后获取更新后的DOM元素" 的问题
vue中响应式,在数据更新后,DOM更新是异步任务,设计成异步是为了提高性能
解决:
- 可以使用this.$nextTick() 传入一个回调函数,该回调函数在下一次DOM 更新后触发
- 当然也可以用updated钩子函数,但写出来的代码会不连续
注意: 这里的回调函数用箭头函数
$nextTick()进一步用法
this.$nextTick()会返回一个Promise对象
- 就可以用await + async 优化
- 也可以用
this.$nextTick().then(放要处理的代码)
注意
- 开发中一般把表格单独作为一个组件,因为使用频次高
- vue的数据存哪里好,一般都是放在app.vue中,子组件一般都是用接收来的数据
- v-model="变量"
- 用在input的输入框中时,双向绑定的是输入数据的value值;
- 用在input的checkbox中时,双向绑定需要看变量设置的数据类型,如果设置的是数组,则返回checkbox中的value值,如果变量设置的不是数组,则返回的是checkbox的checked布尔值
- 全选反选功能一般会用到计算属性,是因为不仅要根据全选按钮来控制所有单选框,还要有根据单选框来控制全选框,计算属性能的双向绑定能做到这点
第七板块
v-model是一个语法糖
- 给表单标签设置value属性
- 绑定input自定义事件,子组件触发事件执行事件,并赋值给value的变量
注意
- components文件夹中一般放的都是可复用的组件 ; views文件夹一般放的是页面组件,一般不用于复用
- 一个template标签中只能有一个v-slot指令(这里的#body="scope" 是两个v-slot指令的简写,分别是
v-slot:body和v-slot="scope"等价于v-slot:body="scope") - 浏览器默认鼠标触发事件,需要按下时和弹起时都在触发事件源(就是说如果点击下去时,按钮变化不在鼠标内弹起,则不能触发事件)
路由
- 路由是什么: 路由是接口和服务的映射关系
- vue中的路由是什么: 路径和组件的映射关系
- 作用: 实现业务场景切换
单页面应用: 所有功能在一个html页面上实现(主流开发,而不是开发多个页面)
- 优点:
- 整体不刷新页面,用户体验更好
- 数据传递容易,开发效率高
- 缺点:
- 首次加载会比较慢一点,不利于seo(只有一个html的meta标签)
注意: 这种应用场景就需要用到路由
重定向
注意 : 捕捉网址为 / 时,跳转到指定路径
404(找不到匹配的url时)
注意: 设置path为* 通配符,并跳转到指定组件
vue模式设置
注意: 默认为hash模式,会在url中显示#号 ,改成history后不会有#号,但需要和后台配合
vue组件的布局
约定俗成的文件夹布局,重复使用的组件放在components中, 页面组件放在view中
vue-router的使用
- 用router-view作为挂载点, 切换不同的路由页面
注意
-
Vue2需要搭配 vue-router@3.5.3的版本才可以运行,不然会报错
-
#号在a标签使用,能够让页面不跳转,不刷新
- 路由跳转的过程: 需要在main.js中设置路由规则,当访问path的路径时,能够跳转到component 的组件页面,组件页面设置在app.vue中,用
<router-view>标签占位,当点击<router-link>标签时,能够根据to属性中设置的路径,跳转到特定的组件(替代<router-view>占位标签)
router-link
传参
编程式导航
使用name进行配置需要,在main.js中给组件设置name属性
路由跳转传参
推荐用法: path + query 或者 name + params
补充
- 路由规则
- path
- component
- redirect
url?name=xiaoxiong适合用于刷新页面参数依然存在的情况, 如果通过params传参,刷新页面数据就会消失- 编程式跳转中, 使用path跳转时会忽略params参数
第八板块
路由嵌套
注意:
- 则中的chilren注意 path书写不要写
/,否则不会匹配前面的/find,也就是说不加/表示为相对路径,用户访问时要匹配父级路由path/子路由path - 同时注意二级子组件的文件夹布局,写在views中的second文件中
声明式导航中类名区别
注意:
- router-link-active用来做样式高亮, 模糊匹配,只要组件的路径是url中hash值的一段,就会给组件添加此类名,页面上就会呈现高亮(就是说子组件的父组件都呈现为高亮)
全局前置守卫
注意:
- 回调函数会在每一次
路由跳转前触发, 应用场景为当用户没有登录时点击"我的"页面,就需要让页面跳转到指定页面或者阻止跳转 - 其中的
next('/part')能够指定跳转到指定页面 - 全局前置守卫主要用来做权限控制(页面权限)
组件缓存
组件匹配缓存(缓存或不缓存)
在keep-alive标签中设置include="组件名,组件名"表示缓存的组件; exclude="组件名,组件名",表示不缓存的组件
组件缓存-设置条件
注意: 组件缓存扩展的方法,能够在数据
vuex
- vuex是为了解决数据复杂传递问题(子组件间要传递很多次), 通过建立公共仓库,进行数据存取
- 适合存储的数据: 共享的数据; 应用场景: 频繁大范围的数据共享
- 最大的好处是存到vuex中的数据能够响应式更新
State(定义数据)
访问state数据第一种方式: state用来存储全局的数据, 并在state中定义数据 ,在组件中通过this.$store.state.count 调用数据
访问state数据的第二种方式
- 导入mapState辅助函数
- 在计算属性中调用mapState()并将其结果展开
- 在当前页面调用函数中传过来的变量
注意:
- mapState(['count','username'])展开的是 mapState调用的结果, 注意要接收的变量用数组包起来,
...mapState(['count','username'])表示展开了mapState()这个对象,对象中有两个函数,通过...展开对象,将函数放在计算属性中 - 将括号中的数据从State中接收过来,并能够在当前页面调用变量
- 这种方式适用于数据量大的场景
Mutation(修改state中数据)
不建议在子组件中直接修改state中数据,虽然可以通过
this.$store.state.count = 2会导致修改来源不明确,不利于后期修改和维护
是什么
三者的关系
注意:
- 所有mutations中的函数,第一个参数永远都是state
- 为什么传递state过来?
- 因为mutations要修改state中的数据,无法直接获取到state
- 在组件中怎样调用 mutation 方法?
- 答案:
this.$store.commit('方法名')
- 通过
this.$store.commit('方法名')修改state中数据,能够在vuex浏览器的timeline界面显示详情,但如果用this.$store.state.count的方式修改,就不能够看到数据的变化,不利于维护
传参的方式
注意: mutations中方法的参数只能有两个,一个是state,一个是payload,一般将payload写成对象的形式,便于承载多个参数
使用方式
注意:
- mutations不能监视到异步操作, 比如ajax和定时器,但是能做到修改数据,只是timeline中看不到异步后的结果,mutation中定时器只能拿到上一次定时器的数据
- mutation必须是同步函数
Action的基本使用
因为Mutations中不能发送异步请求拿数据,需要在Actions中请求拿到数据后,再通过Mutations将数据存到State中
同样,actions中方法也mutations中的方法一样传参
mapActions
- 除了state的调用是放在computed中,mutations和actions要放在methods中
Getter方法
注意:
- getters和mutations中计算属性的第一个参数默认是state,因为都需要对state中数据进行操作
- getters的出现是为了解决多个组件重复使用的问题
mapGetters
命名空间
注意:
- namespaced(命名空间)可以解决不同模块之间成员名称冲突的问题。在实际项目开发中,建议为每 个 Module 模块都开启命名空间
- 在定义模块时,只需在模块的根节点中声明 namespaced: true 选项,即可为当前模块开启命名空间
- 当模块启用了 namespaced: true 选项之后,模块就有了自己的命名空间。此时,模块内的成员需要通过模块的注册名称才可以访问到。
命名空间下的数据访问
- 通用模块注册访问
- 访问state中的变量
- 访问mutations中的函数
- 访问action和getter中的数据
注意
- 开启命名空间的子模块可以通过两种方式访问
- 通过辅助函数的形式(适合使用次数多的场景)
- 或者直接通过(适合使用次数少):
$store.dispatch(模块名/模块中变量)
- 如果需要用命名空间的子模块中的getters数据,只能通过辅助函数拿到
vuex中modules总结
注意: 如果mutations和actions使用少的话就用commit和dispatch直接访问; 如果需要多次使用就可以用辅助函数导入、注册并调用
补充
- 组件中,export default中自动生成的name属性,能够在vue调试工具中作为标签名显示
- 其中mapState 和 mapMutations内容是一样的,通过 {mapState,mapMutations} 是为了拿到其中的某一项,从而有针对性的拿到数据
注意
- 声明式导航一般用在导航条中的按按钮; 编程式导航一般用来某些页面中的小按钮,条件逻辑跳转
- vue中路径中辅助函数 + computed 计算属性
- 访问数据的mapState和mapGetters放在computed计算属性里面
- 修改数据的mapMutations和mapActions放在methods方法里面
第九板块
购物车案例
- 在MyGoods中不能使用v-model直接修改父组件传递的数据(数据改变必须要经过mutations)
- 没有在子组件中直接调用mutations中的方法,而是将通过子传父将修改的命令传给父组件app.vue中,这样子组件就不用承当修改数据的任务,让结构更加清晰
- 全选反选功能得注意下
- 一般在项目中会给每个子模块封装单独的api模块,便于项目维护
vue脚手架手动进行基础配置
ESLint
注意:
- 可以通过
yarn lint用脚手架命令自动修改 - 保存的时候自动格式化为 ESLint 规范代码
- 注意关闭vscode自动保存的功能, 以免插件冲突产生bug
常见的vue技术栈组件库
- 移动端(Vant, Cube-UI, NutUI )
- PC端 ( element-ui, Ant Design of Vue, iView)
- 小程序: uniapp
element 的使用
注意: 这里的el-table为组件, 其中的标签为插槽
补充
- 组件中computed和vuex中getters区别: 单个组件中设置computed计算属性, 可以设置get(val) 根据获取的值来进行操作, 并且根据set(){return ...} 返回一个值, 就是说在单个组件中的计算属性能完成拿和取两个动作, 但vuex中的getters只能用return来返回值, 就是说只能完成取的行为.
注意
- 根据传来的值显示对应数据
- 如果不让eslint的函数名前没有空格报错,可以在配置文件中添加这么一句
'space-before-function-paren': ['error', 'never']
- 当分子模块并开启命名空间之后, 一定不要忘了每次调用数据时都要加模块名
- 当分子模块并开启命名空间之后, getters 中的计算属性不能通过$store的方式访问数据, 只能通过辅助函数的形式访问
- 注意store文件夹中的index.js, 可以直接在main.js中引入
import './store', vue能够直接找到index.js, 然后其他子模块就通过export default {} 导出, 并引入到index.js中, 通过在index.js中modules对象中引入子模块(其他文件夹都可以进行类似的操作, 引入文件夹, 直接就能找到其中的index)