复习Vue
一.vue使用
computed和watch:
computed有缓存(提高运算性能),data不变则不会重新计算
watch如何深度监听(监听引用类型)
watch监听引用类型(例如对象里面包数组),拿不到oldVal。深度监听要加上deep:true
条件传染:
v-if v-else的用法,可使用变量,也可以使用===表达式
v-if和v-show的区别
v-if不会渲染DOM
v-show display:none
循环(列表)渲染
如何遍历对象? 也可以使用v-for
key的重要性.key不能乱写(如random或者index)
v-for和v-if不能一起使用
事件
event参数,自定义参数
没有传参可以直接用event事件 event.__proto__.constructor//是原生构造函数
所以:1.event是原生的2.事件被挂载到当前元素(event.target)
事件修饰符,按键修饰符 ("观察"事件被绑定到哪里)
表单
v-model
常见表单项 textarea checkbox radio select
修饰符 .lazy .number.trim 等
二.Vue 组件使用
props和$emit
组件间通讯-自定义事件
组件生命周期
生命周期(单个组件)
- 挂载阶段
- 更新阶段
- 销毁阶段
created和mounted的区别
create 页面还没有开始渲染 VUE的实例已经初始化完了
mounted 页面已经传染完了
生命周期(父子组件)
挂载和更新都是从外到内然后从内到外
Vue高级特性
自定义v-model
数据双向绑定
$nextTick
- Vue是异步渲染的框架
- data改变之后,DOM不会立刻渲染
- $nextTick会在DOM渲染之后被触发(再回调),以获取最新DOM节点
slot
基本使用 作用域插槽
父组件里<slot>替换成<template v-slot="自定义取名">{{自定义取名.子组件动态绑定的名.里面的属性}}</template>
具名插槽
动态、异步组件
动态组件
:is="component-name"用法
需要根据数据,动态渲染的场景,即组件类型不确定
异步组件
import()函数 ()=> import('')
按需加载,异步加载大组件
keep-alive
- 缓存组件
- 频繁切换,不需要重复渲染
- 出现在Vue常见性能优化
- 用包裹起来 比如用v-if的时候
mixin
-
多个组件有相同的逻辑,抽离出来
-
mixin并不是完美的解决方案,会有一些问题
-
vue3提出的CompositionAPI旨在解决这些问题
mixin带来的问题? 变量来源不明确,不利于阅读 多个mixin可能造成命名冲突 mixin和组件可能出现多对多的关系,复杂度较高
Vuex使用
- Vuex基本概念!
- state
- getters
- action
- mutation
- 用于Vue组件(api)
- dispatch
- commit
- mapState
- mapGetters
- mapActions
- mapMutations
Vue-router使用
- 路由模式(hash、H5history)后者需要server端支持
- 路由配置(动态路由、懒加载)
三.Vue原理
组件化
组件化基础 数据驱动视图(MVVM,setState)
响应式
组件data的数据一旦变化,立刻触发视图的更新
实现数据驱动视图的第一步
核心API-Object.defineProperty
缺点:
深度监听,需要递归到底,一次性计算量大
无法监听新增属性/删除属性(Vue.set Vue.delete)
无法原生监听数组,需要特殊处理
vdom和diff
- 只比较同一层,不跨级比较
- tag不相同,则直接删掉重建,不再深度比较
- tag和key,两者都相同,则认为是相同节点,不再深度比较
模板编译
vue组件中使用render代替template
渲染过程
- 解析模板为render函数(或在开发环境已完成,vue-loader)
- 触发响应式,监听data属性getter setter 有图3-3
- 执行render函数,生成vnode,path(elem,vnode)
更新过程
- 修改data,触发setter(此前在getter中已被监听)
- 重新执行render函数,生成newVnode
- patch(vnode,newVnode)
异步渲染
- 回顾$nextTick
- 汇总data的修改,一次性更新视图
- 减少DOM操作次数,提高性能
前端路由
hash
特点:
hash变化会触发网页跳转,即浏览器的前进、后退
hash变化不会刷新页面,SPA必需的特点
hash永远不会提交到server端(前端自生自灭)
history
特点:
用url规范的路由,但跳转时不刷新页面
hisroty.pushState
window.onpopstate
两者选择
to B的系统推荐用hash,简单易用,对url规范不敏感
to C的系统,可以考虑选择H5 history,但需要服务支持
能选择简单的,就不用复杂的,考虑成本和利益
四.Vue真题演练
问题解答!!!
v-show和v-if的区别?
v-show通过CSS display控制显示和隐藏
v-if组件真正的渲染和销毁,而不是显示和隐藏
频繁切换显示状态用v-show,否则用v-if
为何v-for中要用key?
必须用key,且不能是index和random
diff算法中通过tag和key来判断,是否是sameNode(相同的节点)
减少渲染次数,提升渲染性能
描述Vue组件生命周期(有父子组件的情况)?
单组件生命周期图
父子组件生命周期关系
Vue组件如何通讯?
父子组件props和this.$emit
自定义事件event.$no event.$off event.$emit
vuex
描述组件渲染和更新的过程?
双向数据绑定V-model的实现原理?
input元素的value=this.name
绑定input事件this.name=$event.tartget.value
data更新触发re-render
对MVVM的理解
computed有何特点?
缓存,data不变不会重新计算
提高性能
为何组件data必须是一个函数?
最根本的核心在于定义的.vue文件是一个class(类)然后每个地方去使用其实是类的一个实例化
ajax请求应该放在哪个生命周期?
mounted
JS是单线程,ajax异步获取数据
放在mounted之前没有用,只会让逻辑更加混乱
如何将组件所有props传递给子组件?
$props
<User b-bind="$props">
如何自己实现v-model?
多个组件有相同的逻辑,如何抽离?
mixin
以及mixin的一些缺点
何时使用异步组件?
加载大组件(比如使用编辑器)
路由异步加载
何时需要使用keep-alive?
缓存组件,不需要重复渲染
多个静态tab页的切换
优化性能
何时需要使用beforeDestory?
解绑自定义事件event.$off
清除定时器
解绑自定义事件的DOM事件,如window scroll等
注意:三者不做的话都有可能造成内存泄漏
什么是作用域插槽?
Vuex中action和mutation有何区别?
action中处理异步,mutation不可以
mutation做原子操作
action可以整合多个mutation
请用vnode描述一个DOM结构?
监听data变化的核心API是什么?
Object.defineProperty
以及深度监听、监听数组
有何缺点
Vue如何监听数组变化?
Object.defineProperty不能监听数组变化
重新定义原型,重写push pop等方法,实现监听
Proxy可以原生支持监听数组变化
请描述响应式原理?
监听data变化的过程
组件渲染和更新的流程
Vue为何是异步渲染,$nextTick有何做用?
异步渲染(以及合并data修改),以提高渲染性能
$nextTick在DOM更新完之后,触发回调
Vue常见性能优化方式
合理使用v-show和v-if
合理使用computed
v-for时加key,以及避免和v-if同时使用
自定义事件、DOM事件及时销毁
合理使用异步组件
合理使用keep-alive
data层级不要太深
使用vue-loader在开发环境做模板编译(预编译)
webpack层面的优化
前端通用的性能优化,如图片懒加载
使用SSR