v-show 与 v-if 区别
为何v-for 中要用key
computed 和 watch
动态绑定class的方法
组件间通信/ue组件如何通信 自定义事件
props $emit $ref
描述vue生命周期 (在父子组件的情况下)
何时使用beforeDestroy
描述组件渲染和更新过程
自定义v-model /自定义组件的语法糖 v-model 是怎样实现的
$nextTick
slot
动态、异步组件/何时使用异步组件
keep-alive/ 何时使用keep-alive
mixin / 多个组件有相同逻辑 抽离出来如何抽离
Vuex 中action 和 mutation 有什么区别
如何设置动态路由
如何实现路由懒加载/异步加载
双向数据绑定v-model的实现原理
vue-router 有哪几种导航钩子
Vue.js 2.x 双向绑定原理
什么是 MVVM,与 MVC 有什么区别
vue的原理
理解Vue中的Render渲染函数
怎样理解单向数据流
路由跳转
请用一个vNode 描述一个Dom结构
监听Data变化的核心api 是什么
Vue如何监听数组变化
请描述响应式原理
为何组件data必须是一个函数
diff算法的事件复杂度
简述diff算法过程
Vue 为何是异步渲染,$nextTick有何用
VUe 常见性能优化
ajax应该放在哪个生命周期
如何将组件所有props 传递给子组件
只不过v-show是改变元素的css属性display。当v-show表达式的值为false是,元素会隐藏,查看DOM结构看到元素上加载了内联样式display:none; (v-show 显示和隐藏)
v-if是真正的条件渲染,它会根据表达式适当地销毁或重建元素及绑定的事件或子组件。若表达式初始值为false,则一开始元素/组件并不会渲染,只有当条件第一次变为真时才开始编译。(v-if 可用于刷新组件)(v-if 渲染和销毁)
而v-show只是简单的css属性切换,无论条件真与否,都会被编译。相比之下,v-if更适合条件不经常改变的场景,因为它切换开销相对较大,而v-show适用于频繁切换条件。
必须使用key 且不能是index和random (尽量不要使用index作为key的值)
diff算法中通过tag和key来判断 是否是sanmeNode
减少渲染次数 提升渲染性能
在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。
<li v-for="(item,index) in students" :key="item.id" >
{
{
index}}:{
{
item.name}} - {
{
item.age}}
</li>
通俗来讲,既能用computed 实现又可以用 watch 监听来实现的功能,推荐用 computed,重点在于 computed 的缓存功能
computed计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量改变时,计算属性也会跟着改变;
有缓存,原data数据不变,不会重新计算 (computed的值可以不在data中定义)(提升性能)
watch 监听的是已经在 data 中定义的变量,当该变量变化时,会触发 watch 中的方法;(监听引用类型 拿不到oldvalue )
data:{
a:1,
b:{
c:1
}
},
watch:{
a(val, oldVal){
//普通的watch监听
console.log("a: "+val, oldVal);
},
b:{
//深度监听,可监听到对象、数组的变化
handler(val, oldVal){
console.log("b.c: "+val.c, oldVal.c);//watch 监听引用类型 拿不到oldvalue
},
deep:true //true 深度监听
}
}
参考:vue动态绑定class的常用几种方式
参考:vue采用EventBus实现跨组件通信及注意事项
考点 :props $emit $ref eventBus
vue本身具有自定义事件能力()
取消事件订阅必须跟事件订阅成对出现,否则会重复订阅,对javascript性能造成不必要的浪费
自定义事件
event. n o e v e n t no event noeventoff event$emit
参考:vue 组件通信的几种方式解读
子组件的props选项能够接收来自父组件数据。没错,仅仅只能接收,props是单向绑定的,即只能父组件向子组件传递,不能反向
$emit 绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数。
如果ref用在子组件上,指向的是组件实例,可以理解为对子组件的索引,通过 r e f 可 能 获 取 到 在 子 组 件 里 定 义 的 属 性 和 方 法 。 如 果 r e f 在 普 通 的 D O M 元 素 上 使 用 , 引 用 指 向 的 就 是 D O M 元 素 , ∗ ∗ ∗ 通 过 ref可能获取到在子组件里定义的属性和方法。 如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,***通过 ref可能获取到在子组件里定义的属性和方法。如果ref在普通的DOM元素上使用,引用指向的就是DOM元素,∗∗∗通过ref可能获取到该DOM 的属性集合,访问到DOM元素***,
prop和$ref之间的区别:
prop 着重于数据的传递,它并不能调用子组件里的属性和方法。像创建文章组件时,自定义标题和内容这样的使用场景,最适合使用prop。
$ref 着重于索引,主要用来调用子组件里的属性和方法,其实并不擅长数据传递。而且ref用在dom元素的时候,能使到选择器的作用,这个功能比作为索引更常有用到。
总结:
props 用于 父 -> 子 传值
$emit 用于 子 -> 父传值
$ref 用于 父 -> 子 传值
create vue的实例 存在于js内存模型中,是内存中的一个变量 并没有开始渲染 vue组件初始化完成
mounted 网页绘制、渲染完成
创建 初始组件是由外到内 (父->子)
渲染组件是由内到外的 (子->父)
销毁组件是由内到外的 (子->父)
子组件的数据更新,不会引起父组件的beforeUpdate和updated生命周期钩子
解绑自定义事件
清楚定时器
解绑自定义的DOM事件 如 window scroll (销毁子组件以及事件监听器 )
解绑 evenbus 绑定事件或者自定义事件 (防止可能造成内存泄漏)(mounted 中添加eventbus 绑定的事件)
input 元素的value = this.name
绑定 input 事件 this.name = $event.target.value
data 会触发 re-render
异步渲染 $nextTick 待dom完成后再回调
页面渲染 会将data的修改数据整合 ,多次data修改只会渲染一次
作用域插槽:
使用时候子组件标签中要有标签,再通过scopeName.childProp就可以调用子组件模板中的childProp绑定的数据,所以作用域插槽是一种子传父传参的方式,解决了普通slot在parent中无法访问child数据的去问题;
具名插槽:
何时使用异步组件:
加载大组件
路由异步加载
动态组件:
// currentTabComponent 组件名称
<!--动态组件-->
<component :is="slotDemo"></component>
<script>
import slotDemo from './slotDemo'
import scopedSlotDemo from './scopedSlotDemo'
import nameSlot from './nameSlot'
export default {
components:{
slotDemo,scopedSlotDemo,nameSlot
},
}
</script>
异步组件:
import 大函数
按需加载,异步加载大组件
<slotDemo v-if="showSlotDemo">
<script>
export default {
components:{
slotDemo: () => import('./slotDemo')
},
}
</script>
何时使用keep-alive:
缓存组件,不需要重复渲染
多个静态tab页切换
性能优化
缓存组件
频繁切换,不需要重新渲染
vue常见性能优化
// 如果没有 下面三个组件切换时会销毁其他组件
// 如果使用 下面三个组件切换时不会销毁其他组件,只会切换显示隐藏
<keep-alive>
<slotDemo v-if="stat ===1 "/>
<scopedSlotDemo v-if="stat ===2 " />
<nameSlot v-if="stat ===3 " />
</keep-alive>
<script>
import slotDemo from './slotDemo'
import scopedSlotDemo from './scopedSlotDemo'
import nameSlot from './nameSlot'
export default {
components:{
slotDemo,scopedSlotDemo,nameSlot
},
}
</script>
多个组件有相同逻辑 抽离出来
mixin 不是完美的解决方案 会有一些问题
vue3 提出的Composition API旨在解决这些问题
缺点:
变量来源不明确,不利于阅读
多mixin可能造成mixin命名冲突
mixin和组件可能出现 多对对关系,复杂度较高
state
getter
action
mutation
用于vue的组件
dispatch
commit
mapState
mapGetter
mapAction
mapMutation
action 中处理异步 mutation 不可以
mutation 做原子操作
action 可以整合 多个mutation
路由模式 hash模式 H5 history模式
H5 history模式 需要server段提供支持(why)
路由设置 动态路由 懒加载
const = {
// 获取参数 10 20
template: ' {
{ }}'
}
const router= new VueRouter({
router:[
// 动态路径参数 以冒号开头, 能命中 'user/10' 'user/20' 等格式的路由
{
path: '/user/:id',component : User}
]
})
{
path: '/rank-list',
name: 'RankList',
meta: {
title: '排行榜'
},
component: RankList
}
const RankList = () => import( /* webpackChunkName: "RankList" */ '@/components/RankList')
Object.defineProperty
深度监听 监听数组
有何缺点
Object.defineProperty 不能监听数组变化
重新定义原型 重写push pop等写法 实现监听
Proxy 可以原生支持监听数组变化
监听data变化
组件渲染 和更新的流程
O(n)
在O(n^3) 基础上做了一些调整
patdh(elem,vnode) 和 patch(vnode,newVnode)
patchVnode 和 addVnodes 和 removeVnodes
updateChildren (key的重要性)
$nextTick 是在DOM更新后 触发回调
合理使用 v-show 和 v-if
合理使用 computer
v-for 时 加key 避免和v-if同时使用
自定义事件 DOM事件及时销毁
合理使用异步组件
合理使用keep-alive
data 层级不要太深
使用vue-loader 在开发环境做模板变异(预编译)
webpack 层面的优化
前端通用的性能优化
使用SSR
应该放在 mounted 中
js 是单线程的 ajax异步获取数据
p r o p s < U s e r v − b i n d = " props
框架的使用(高级特性、周边插件)
框架的原理(基本原理、热门技术的深度、全面性)
框架的实际应用 设计能力(组件结构、数据结构)
技术追求 (考察原理)
独立承担项目 (考察设计能力)
熟悉基本使用,了解使用场景级项目结合的使用经验
98道经典Vue面试题总结(长期更新)