1. v-show 和 v-if 的区别
- v-show 通过 CSS display控制显示和隐藏
- v-if 组件真正的渲染和销毁,而不是显示和隐藏
- 频繁切换显示状态用 v-show ,否则用 v-if
2. 为何在v-for中使用key
- 必需用key,且不能是index和random
- diff算法中通过tag 和 key 来判断,是否是sameNode
- 减少渲染次数,提示渲染性能
3. 描述Vue组件生命周期(父子组件)
- 单组件生命周期图
- 父子组件生命周期关系(类似洋葱模型)
4. Vue组件如何通讯
- 父子组件
props
和this.$emit
- 自定义事件
event.$no
event.$off
event.$emit
- vuex
5. 描述组件渲染和更新的过程
6. 双向数据绑定 v-model 的实现原理
- input元素的value = this.name
- 绑定input事件
this.name
= $event.target.value
- data 更新触发 re-render
7. 对MVVM的理解
8. compuited 有何特点
9. 为何组件data必需是一个函数
- 根本上.vue会编译为一个class,使用组件相当于对组件进行实例化,如果data不是函数,根据原型链组件会使用同一个原型的data即组件的data会共享。如果data是一个函数,则在实例化当中都会执行函数,data就会在闭包之中。不会向互影响
10. ajax请求应该放在哪个生命周期
- mounted
- JS是单线程的,ajax异步获取数据
- 放在mounted之前没有用,只会让逻辑更加混乱
11. 如何将组件所有props 传递给子组件?(细节知识点,优先级不高)
$props
<User v-bind= "$props" />
12. 多个组件组件有相同的逻辑,如何抽离?
<template>
<div>
<MixinDemo/>
</div>
</template>
<script>
import MixinDemo from './MixinDemo'
export default {
components: {
MixinDemo
},
}
</script>
<template>
<div>
<p>{{name}} {{major}} {{city}}</p>
<button @click="showName">显示姓名</button>
</div>
</template>
<script>
import myMixin from './mixin'
export default {
mixins: [myMixin],
data() {
return {
name: '双越',
major: 'web 前端'
}
},
methods: {
},
mounted() {
console.log('component mounted', this.name)
}
}
</script>
export default {
data() {
return {
city: '北京'
}
},
methods: {
showName() {
console.log(this.name)
}
},
mounted() {
console.log('mixin mounted', this.name)
}
}
13. 何时加载异步组件?
<!-- 异步组件 -->
<FormDemo v-if="showFormDemo"/>
<button @click="showFormDemo = true">show form demo</button>
<script>
export default {
components: {
FormDemo: () => import('../BaseUse/FormDemo'),
},
}
</script>
14. 何时需要使用keep-alive?
- 缓存组件,不需要重复渲染
- 如多个静态的tab页的切换
- 优化性能
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
15. 何时需要使用beforeDestroy(生命周期函数)
- 绑定自定义事件
event.$off
- 清除定时器
- 解绑自定义的DOM事件,如 window scroll 等
16. 什么是作用域插槽
<ScopedSlotDemo :url="website.url">
<template v-slot="slotProps"> //定义一个参数接收传来的值
{{slotProps.slotData.title}} //使用
</template>
</ScopedSlotDemo>
<template>
<a :href="url">
<slot :slotData="website"> // 定义一个值用来传给父组件
{{website.subTitle}}
</slot>
</a>
</template>
<script>
export default {
props: ['url'],
data() {
return {
website: {
url: 'http://wangEditor.com/',
title: 'wangEditor',
subTitle: '轻量级富文本编辑器'
}
}
}
}
</script>
17.Vuex中的action和mutation有何区别
- action中处理异步,mutation不可以
- mutation做原子操作(即每次做一个操作)
- action 可以整合多个mutation
18. Vue-router常用的路由模式
- hash默认
- H5history(需要服务端支持)
19. 如何配置Vue-router异步加载
export default new VueRouter({
router:[
{
path:'/',
component:()=>import(
'./../components/Navigator'
)
},{
path:'/feedback',
component:() => import(
'./../components/FeedBack'
)
}
]
})
20. 请用vnode 描述一个DOM结构
<div id="div1" class="container">
<p>vdom</p>
<ul style="font-size:20px">
<li>a</li>
</ul>
</div>
{
tag:'div',
props:{
id:'div1',
class: 'container'
}
children:[
{
tag:'p',
children:'vdom'
},{
tag:'ul',
props:{
style:'font-size:20px'
children:[
{
tag:'li',
children:'a'
}
]
}
}
]
}
21. 监听data变化的核心API是什么
Object.defineProperty
- 以及深度监听、监听数组
详细查看原理重点
function updateView() {
console.log('视图更新')
}
const oldArrayProperty = Array.prototype
const arrProto = Object.create(oldArrayProperty);
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
arrProto[methodName] = function () {
oldArrayProperty[methodName].call(this, ...arguments)
updateView()
}
})
function defineReactive(target, key, value) {
observer(value)
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if (newValue !== value) {
observer(newValue)
value = newValue
updateView()
}
}
})
}
function observer(target) {
if (typeof target !== 'object' || target === null) {
return target
}
if (Array.isArray(target)) {
target.__proto__ = arrProto
}
for (let key in target) {
defineReactive(target, key, target[key])
}
}
const data = {
name: 'zhangsan',
age: 20,
info: {
address: '北京'
},
nums: [10, 20, 30]
}
observer(data)
data.name = 'lisi'
data.age = 21
console.log('age', data.age)
data.x = '100'
delete data.name
data.info.address = '上海'
data.nums.push(4)
22. Vue 如何监听数组变化
- Object.defineProperty不能监听数组变化
- 重新定义原型,重写push pop 等方法,实现监听
- Proxy可以原生支持监听数组变化
23. 请描述响应式原理
- 监听data变化 (即第21题)
- 组件渲染和更新的流程 (即第5题)
24. diff算法的时间复杂度
25. 简述diff算法的过程
- patch(elem,vnode) 和 patch(vnode,newVnode)
- patchVnode 和 addVnodes 和 removeVnodes
- updateChildren(key的重要作用)
26.Vue为何是异步渲染,$nextTick有何用?
- 异步渲染(以及合并data修改),以提高渲染性能
- $nextTick在DOM更新完之后,触发回调
27.Vue常见性能优化方式
- 合理使用
v-show
和 v-if
- 合理使用
computed
v-for
时加key
,以及避免和v-if同时使用
- 自定义事件、
DOM
事件及时销毁
- 合理使用异步组件
- 合理使用
keep-alive
- data层级不要太深
- 使用vue-loader在开发环境做模板编译(预编译)