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 计算属性与方法

  1. 计算属性会被缓存(只有当计算属性的依赖发生变化时,代码才会被再次执行)

  2. 计算属性可以设置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向下传递数据给子组件
注:组件中的数据共有三种形式:datapropscomputed

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 面试题

前端面试套餐:Vue面试题总结+JavaScript前端经典面试题+100道 CSS 面试题

几道 SQL 笔试题面试题总结