Vue面试题总结 - 基础知识总结 - 复习专用
Posted YK菌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue面试题总结 - 基础知识总结 - 复习专用相关的知识,希望对你有一定的参考价值。
本来是想总结一些面试题,这一总结起来,直接又重新学了一遍Vue
就当作复习Vue用的,总结了一些基础知识也有一些面试题
持续更新…
1. 基础知识
1.1 指令
v-text
: 更新元素的 textContent
v-html
: 更新元素的 innerHTML
v-if
: 如果为true, 当前标签才会输出到页面
v-else
: 如果为false, 当前标签才会输出到页面
v-show
: 通过控制display样式来控制显示/隐藏
v-for
: 遍历数组/对象
v-on
: 绑定事件监听, 一般简写为@
v-bind
: 强制绑定解析表达式, 可以省略v-bind
v-model
: 双向数据绑定
ref
: 为某个元素注册一个唯一标识, vue对象通过$refs属性访问这个元素对象
v-cloak
: 使用它防止闪现表达式, 与css配合: [v-cloak] { display: none }
1.2 v-if与v-show
v-if
是控制元素是否加载到页面上(有性能开销)
v-show
是控制元素的显示与隐藏 (初始创建时加载一次)
频繁切换使用v-show
1.3 v-for
数组
(item, index) in array
对象
(value, key, index) in object
1.4 v-if与v-for不能同时用
v-for
优先级高一点,会循环之后再判断条件,开销比较大
可以把v-if
放在父标签或者子标签中
1.5 data、计算属性、方法
data对象:可以使用它来存储字符串、数组和对象等数据;
方法:可以使用它来存储函数并在模板中调用;
计算属性:可以使用它将函数存储下来,然后像访问data对象中的属性一样调用
1.6 计算属性与方法
-
计算属性会被缓存(只有当计算属性的依赖发生变化时,代码才会被再次执行)
-
计算属性可以设置setter和getter
1.7 方法中的this
在方法中,this指向该方法所属的组件。可以使用this访问data对象的属性和其他方法
1.8 事件对象
默认传入 $event
有参数时,显式在最后传入 $event
<p>{{number}}</p>
<button @click="incrementBy1">点击+1</button>
<button @click="incrementBy10(10, $event)">点击+10</button>
data(){
return {
number: 0
}
}
methods: {
incrementBy1(e){
this.number++
console.log(e.__proto__.constructor) // f MouseEvent()
console.log(e.target) // <button>点击+1</button>
console.log(e.currentTarget) // <button>点击+1</button>
},
incrementBy10(step, e){
this.number+=step
console.log(e.__proto__.constructor) // f MouseEvent()
}
}
1.9 事件修饰符
.prevent
阻止执行事件默认行为
.stop
阻止事件继续传播
.once
只在第一次触发事件的时候触发事件侦听器
.capture
使用捕获模式
.self
只监听元素自身而不是它的子元素上触发的事件
1.10 侦听器 watch
侦听器可以监听data对象属性或者计算属性的变化
当监听的属性发生变化时,侦听器会被传入两个参数:所监听属性的当前值和原来的旧值
监听整个对象被称作深度监听,通过将deep选项设置为true来开启这一特性
data() {
return {
name: 'YK菌',
info: {
hobby: '写博客'
}
}
},
watch: {
name(newValue, oldValue){
console.log(newValue, oldValue);
},
info: {
handle: function(newValue, oldValue){
console.log(newValue, oldValue);
},
deep: true
}
当数据改变时,会调用watch里对应的函数
引用类型值改变后,新旧值都改变了,所以拿不到oldValue
1.11 动态绑定class、style
1. 类名class
对象
:class="{ 'active': isActive, 'error': isError }"
data(){
return {
isActive: true,
isError: false
}
}
数组
:class="[activeCls, errorCls]"
data(){
return {
activeCls: 'active',
errorCls: 'error'
}
}
对象数组之间可以互相嵌套
2. 内联样式style
对象
:style="{ 'color': color, 'fontSize': fontSize + 'px' }"
data(){
return {
color: 'red',
fontSize : 14
}
}
数组
:style="[ styleA, styleB ]"
1.12 过滤器
使用
只可以在插值和v-bind指令中使用过滤器
{{ origin | format }}
组件中定义
filters: {
format(value){
return value + 2;
}
}
全局定义
Vue.filter('format', function(value){
return value + 2;
})
过滤器是组件中唯一不能使用this来访问数据或者方法的地方
因为过滤器应该是纯函数,也就是说对于同样的输入每次都返回同样的输出,而不涉及任何外部数据。如果想在过滤器中访问其他数据,可以将它作为参数传入
1.13 v-clock
解决初始化慢导致页面闪动
不需要表达式,和CSS的display:none
配合使用
<div v-clock>{{ data }}</div>
[v-clock] {
display: none;
}
1.14 生命周期钩子
生命周期钩子是一系列会在组件生命周期——从组件被创建并添加到DOM,到组件被销毁的整个过程——的各个阶段被调用的函数
一个有八个 四组
beforeCreate
在实例初始化前被触发。
created
会在实例初始化之后、被添加到DOM之前触发。
beforeMount
会在元素已经准备好被添加到DOM,但还没有添加的时候触发。
mounted
会在元素创建后触发(但并不一定已经添加到了DOM,可以用nextTick
来保证这一点)。
beforeUpdate
会在由于数据更新将要对DOM做一些更改时触发。
updated
会在DOM的更改已经完成后触发。
beforeDestroy
会在组件即将被销毁并且从DOM上移除时触发。
destroyed
会在组件被销毁后触发
1.15 什么是nextTick
Vue.nextTick( [callback, context] )
vm.$nextTick( [callback, context] )
在下次 DOM 更新循环结束(异步)之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
2. 组件相关
2.1 data为什么是函数
一个组件可以在同一个页面上被多次引用,不希望它们共享一个data对象
因为同一个组件的每个实例的data属性是同一个对象的引用,当该组件的某个实例修改了自身的data属性,相当于所有实例的data属性都被修改了
所以组件的data属性应该是一个函数,在组件初始化时Vue会调用这个函数来生成data对象
2.2 组件间通信
2.2.1 props
父 —> 子
父组件通过标签传递数据 list
<MyList :list="list" />
子组件通过props接收数据list
props: {
list: Array
}
父组件通过props向下传递数据给子组件
注:组件中的数据共有三种形式:data
、props
、computed
2.2.2 $emit
子 —> 父 + 自定义事件
子组件 向外触发一个事件,携带需要传出去的数据this.title
this.$emit('add', this.title)
父组件监听add事件
<MyInput @add="add">
父组件中定义add方法,获取传入的数据,进行操作
methods: {
add(title){
// 得到数据可以进行操作了
this.list.push({
id: Math.random(),
title
})
}
}
2.2.3 EventBus事件总线 .$emit
.$on
定义一个event-bus.js
import Vue from 'vue'
const eventBus = new Vue()
export default eventBus
在需要用到的组件中导入
import eventBus from './event-bus'
在事件中派发到eventBus中并携带数据
eventBus.$emit('addItem', this.title)
在需要用到数据的组件中接收数据
mounted() {
eventBus.$on('addItem', this.handleAddTitle)
}
使用数据
methods: {
handleAddTitle(title){
console.log(title)
}
}
解绑事件监听
beforeDestroy(){
eventBus.$off('addItem', this.handleAddTitle)
}
2.2.4 PubSubJS发布订阅
组件中引入PubSubJS库
import PubSub from 'pubsub-js'
发布消息(触发事件)传递数据
PubSub.publish('deleteTodo', this.index)
订阅消息(绑定事件监听) 接收数据
export default {
mounted () {
// 订阅消息(deleteTodo)
PubSub.subscribe('deleteTodo', (msg, index) => {
this.deleteTodo(index)
})
}
}
2.2.5 作用域插槽
见下面的
2.3 slot
插槽
2.3.1 匿名slot
子组件内部定义一个占位符,父组件使用时可以向组件标签中插入任何内容替换子组件slot中的内容
2.3.2 具名slot
给slot元素指定一个name后,可以分发多个内容
例子
子组件模板定义
<template>
<div class="container">
<div class="header">
<slot name="header"></slot>
</div>
<div class="main">
<slot></slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>
</template>
父组件使用
<child-component>
<h2 slot="header">标题</h2>
<p>内容</p>
<p>更多</p>
<div slot="footer">底部</div>
</child-component>
最后相当于
<div class="container">
<div class="header">
<h2>标题</h2>
</div>
<div class="main">
<p>内容</p>
<p>更多</p>
</div>
<div class="footer">
<div>底部</div>
</div>
</div>
这里的slot
已经废弃了,用v-slot
替代
必须由template
标签包裹,且v-slot
可以简写成#
<child-component>
<template v-slot:header>
<h2>标题</h2>
</template>
<p>内容</p>
<p>更多</p>
<template #footer>
<div slot="footer">底部</div>
</template>
</child-component>
2.3.3 作用域插槽
子组件的数据通过标签传给父组件
<template>
<h1>
<slot :user="user">
{{ user.name }}
</slot>
</h1>
</template>
<script>
export default {
data() {
return {
user: {
name: 'YK',
age: 18
}
}
}
}
</script>
父组件接收数据并使用
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.age }}
</template>
</current-user>
对象结构赋值更简洁
<current-user>
<template v-slot:default="{ user }">
{{ user.age }}
</template>
</current-user>
2.4 动态组件
Vue.js提供了一个特殊的元素
<component>
用来动态地挂载不同的组件,使用is特性来选择要挂载的组件
这个相当于是一个组件占位符,等待填充
示例
这里有三个组件 MyImage、MyVideo、MyTextApp 组件要根据数据来动态渲染组件
数据
data() {
return {
produceData: [
{ id: 1, type: 'Video' },
{ id: 2, type: 'Text' },
{ id: 3, type: 'Image' },
{ id: 4, type: 'Text' }
]
}
}
引入组件
import MyImage from './components/MyImage.vue'
import MyText from './components/MyText.vue'
import MyVideo from './components/MyVideo.vue'
动态渲染组件
<div v-for="item in produceData" :key="item.id">
<component :is="`My${item.type}`"></component>
</div>
2.5 异步组件
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue
允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue
只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
修改引入方式
components: {
AsyncTest: () => import('./components/AsyncTest')
}
只有在点击按钮之后才会加载请求响应的组件文件
可以通过webpack魔法注释给文件起一个名字
AsyncTest: () => import(/* webpackChunkName: "AsyncTest" */'./components/AsyncTest')
2.6 keep-alive实现组件缓存
<h1>keep-alive</h1>
<button @click="state = 'A'">A</button>
<button @click="state = 'B'">B</button>
<button @click="state = 'C'">C</button>
<comp-a v-if="state === 'A'"></comp-a>
<comp-b v-if="state === 'B'"></comp-b>
<comp-c v-if="state === 'C'"></comp-c>
子组件
<template>
<div>
组件A
</div>
</template>
<script>
export default {
mounted() {
console.log('组件A渲染')
},
destroyed() {
console.log('组件A销毁')
}
}
</script>
切换组件的时候,另外的组件就会销毁,没有缓存,频繁切换的话开销比较大
利用keep-alive将需要缓存的组件包裹起来就可以了
<keep-alive>
<comp-a v-if="state === 'A'"></comp-a>
<comp-b v-if="state === 'B'"></comp-b>
<comp-c v-if="state === 'C'一到三年经验前端面试题总结——看完这些月薪过万没问题(持续更新中)
Android面试复习框架及题型解析,最新Android中高级面试题合集
Android面试复习框架及题型解析,最新Android中高级面试题合集
前端面试套餐:Vue面试题总结+JavaScript前端经典面试题+100道 CSS 面试题