vue面试——面试题汇总一
1. 什么是vue-loader?
背景:
1.首先,webpack干嘛的? 打包。
2 webpack 中的各种loader干啥用的? webpack只认识Js,loader帮忙转化其他模块(HTML\CSS),把其他模块转化为webpack所能打包的模块,方便打包。
什么是vue-loader?
作用:解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template,再分别把它们交给对应的 Loader 去处理。
2.什么是 mixin?
混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>mixin入门</title>
<!-- 引入vue.js -->
<script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
</head>
<body>
<div id='app'>
</div>
</body>
<script>
let vm = new Vue({
// 用法:导入mymixins , 在当前vue文件中使用mixin选项即可
mixin:[mymixins],
el:'#app',
data:{
num :2
},
methods:{
}
})
const mymixins= {
data:{
num :1
},
methods:{
}
}
</script>
</html>
mixins的特点:
1 方法和参数在各组件中不共享
2 值为对象的选项,如methods,components等,选项会被合并,键冲突的组件会覆盖混入对象的
3 值为函数的选项,如created,mounted等,就会被合并调用,混合对象里的钩子函数在组件里的钩子函数之前调用
3. Vue:Prop验证如何使用?
<template>
<div style="margin-top:100px">
<my-component
:propA="100"
:propB="'sdf'"
:propC="'propC11'"
:propD="100"
:propE="{a:'a'}"
:propF="'warning'">
</my-component>
</div>
</template>
<script type="text/javascript">
import Vue from 'vue'
Vue.component('my-component', {
props: {
//必须是数字类型
propA: Number,
//必须是字符串或数字类型
propB: [String, Number],
//布尔值,如果没有定义,默认值就是true
propC: {
type: String,
required: true
},
//数字,如果没有定义,默认值就是100
propD: {
type: Number,
default: 100
},
**//对象,默认值必须是一个函数来返回,且返回 { message: 'hello' } (如果是数组,默认值也需要函数返回)**
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
//自定义一个验证函数
propF: {
validator: function (value) {
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
},
template: `
<div>
<p>{{ propA }}</p>
<p>{{ propB }}</p>
<p>{{ propC }}</p>
<p>{{ propD }}</p>
<p>{{ propE }}</p>
<p>{{ propF }}</p>
</div>`
})
export default {
name: 'main',
data(){
},
method(){
}
}
</script>
type 可以是下面原生构造器:
String
Number
Boolean
Function
Object (默认值函数形式)
Array (默认值函数形式)
也可以自定义验证规则(函数形式)
4. 怎样理解虚拟DOM?
虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。这句话,也许过于抽象,却基本概况了虚拟DOM的设计思想
具体是怎么操作的?
(1).用JS表示DOM结构
(2).比较两棵虚拟DOM树的差异
(3).对真实DOM进行最小化修改
5. vue渲染函数怎么用?
渲染函数的作用:VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数。
如何写一个render函数,都有哪些常见的api?
关键点一:理解createElement:
createElement 参数
// @return {VNode}
createElement(
// {String | Object | Function}
// 1.一个HTML标签字符串,组件选项对象,或者一个返回值类型为String/Object的函数。该参数是必须的
'div',
// {Object}
// 2.一个包含模板相关属性的数据对象,这样我们可以在template中使用这些属性,该参数是可选的。
{ },
// {String | Array}
// 3.子节点(VNodes),由 createElement() 构建而成。或简单的使用字符串来生成的 "文本节点"。可选参数
)
关键点二:模板相关属性的数据对象
{
// 和`v-bind:class`一样的 API
'class': {
foo: true,
bar: false
},
// 和`v-bind:style`一样的 API
style: {
color: 'red',
fontSize: '14px'
},
// 正常的 HTML 特性 - 属性
attrs: {
id: 'foo'
},
// 组件 props
props: {
myProp: 'bar'
},
// DOM 属性
domProps: {
innerHTML: 'baz'
},
// 事件监听器基于 `on`
// 所以不再支持如 `v-on:keyup.enter` 修饰器
// 需要手动匹配 keyCode。
on: {
click: this.clickHandler
},
// 仅对于组件,用于监听原生事件,而不是组件内部使用 `vm.$emit` 触发的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定义指令。注意事项:不能对绑定的旧值设值
// Vue 会为您持续追踪
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其他组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其他特殊顶层属性
key: 'myKey',
ref: 'myRef'
}
写一个代码实例:
render: (h,params)=>
{
// 可以组织一些下面需要使用的参数
return createElement(
//参数一:标签字符串-必选
'h' + this.level,
//参数三:子节点(VNodes)由 createElement() 构建而成-可选参数
[
createElement(
//参数一:标签字符串-必选
'a',
//参数二:模板相关属性的数据对象-可选
{
attrs: {
name: headingId,
href: '#' + headingId
},
style: {
color: 'red',
fontSize: '20px'
},
'class': {
foo: true,
bar: false
},
// DOM属性
domProps: {
innerHTML: 'baz'
},
// 组件props
props: {
myProp: 'bar'
},
// 事件监听基于 'on'
// 所以不再支持如 'v-on:keyup.enter' 修饰语
// 需要手动匹配 KeyCode
on: {
click: function(event) {
event.preventDefault();
console.log(111);
}
}
}, this.$slots.default)
]
)
}
6. Vue中的nextTick用法和原理详解
背景:
Vue实现响应式并不是数据发生变化之后DOM立即变化,而是异步执行DOM更新的。
异步执行的运行机制是什么样的?阮一峰老师是这样总结的:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
带着阮一峰老师的讲解,理解一下vue异步更新的原理:
1.修改 Vue 中的 Data 时,就会触发所有和这个 Data 相关的 Watcher 进行更新。
2.首先,会将所有的 Watcher 加入队列 Queue。
3.然后,调用 nextTick 方法,执行异步任务。
4.在异步任务的回调中,对 Queue 中的 Watcher 进行排序,然后执行对应的 DOM 更新。
this.$nextTick()的使用场景:看一个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" @click="handleClick" ref="test">{{message}}</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Zeke'
},
methods: {
handleClick() {
this.message = 'Hello'
console.log(this.$refs.test.innerText) // Zeke
this.$nextTick(function () {
console.log(this.$refs.test.innerText) // Hello
})
}
}
})
</script>
</html>
原
理
:
当
执
行
到
n
e
x
t
T
i
c
k
的
时
候
,
他
也
会
把
n
e
x
t
T
i
c
k
里
面
的
代
码
放
到
一
个
队
列
当
中
,
按
照
队
列
的
顺
序
优
先
级
等
一
个
个
按
次
序
执
行
,
新
添
加
的
事
件
都
会
放
在
队
列
末
尾
。
也
就
是
这
段
代
码
执
行
流
程
为
:
1
t
h
i
s
.
m
e
s
s
a
g
e
=
′
H
e
l
l
o
′
先
放
到
队
列
中
,
先
执
行
。
2
n
e
x
t
T
i
c
k
中
的
代
码
也
放
到
队
列
中
,
依
次
执
行
。
如
果
不
用
n
e
x
t
T
i
c
k
直
接
获
取
i
n
n
e
r
T
e
x
t
是
获
取
不
到
的
,
因
为
并
不
是
理
解
渲
染
,
而
是
异
步
渲
染
原理:当执行到nextTick的时候,他也会把nextTick里面的代码放到一个队列当中, 按照队列的顺序优先级等一个个按次序执行, 新添加的事件都会放在队列末尾。也就是这段代码执行流程为:1 this.message = 'Hello' 先放到队列中,先执行。2 nextTick中的代码也放到队列中,依次执行。如果不用 nextTick 直接获取innerText是获取不到的,因为并不是理解渲染,而是异步渲染
原理:当执行到nextTick的时候,他也会把nextTick里面的代码放到一个队列当中,按照队列的顺序优先级等一个个按次序执行,新添加的事件都会放在队列末尾。也就是这段代码执行流程为:1this.message=′Hello′先放到队列中,先执行。2nextTick中的代码也放到队列中,依次执行。如果不用nextTick直接获取innerText是获取不到的,因为并不是理解渲染,而是异步渲染
vue操作DOM节点的时候,一般在mounted钩子函数中,因为在这个时候DOM已经全部渲染完毕,但在实际的开发过程中,如果我们在刚更新完数据之后,就要操作这个相关节点,我们是拿不到更新以后的DOM的,因为vue中DOM节点的更新是异步的。
所以如果我们要想在刚更新完数据之后就要操作DOM,我们可以通过nextTick函数,将要在视图更新完毕之后执行的代码放在回调函数中执行。
7. 什么时候使用keep-alive元素?
keep-alive是Vue.js的一个内置组件。它能够把不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。
在创建时从 API 调用中引入数据的组件。你可能不希望每次动态切换这个组件进行渲染时都调用此 API。这时你可以将组件包含在 keep-alive 元素中。keep-alive 元素缓存该组件并从那里获取它,而不是每次都重新渲染它。