总结了一下vue面试会问到的问题,各位大佬如发现有错误之处,请指出。拜谢!!!
1.什么是vue?谈谈对你对vue的理解
vue是一个js的渐进式框架,简单,易用,灵活
2.vue生命周期都有哪些?
vue的生命周期是vue实例从创建到销毁的一系列过程。每个过程都有相对应的钩子函数,分为 beforeCreate(创建前),created(创建后),beforeMount(加载前),mounted(加载后),beforeUpdate(更新前),updated(更新后),beforeDestroy(销毁前),destroyed(销毁后)。
当使用keep-alive时,有activated和 deactivated两个钩子函数。当组件用keep-alive包裹时切换文件时不会进行销毁,而是进行缓存并执行deactivated 钩子函数,组件被激活时执行actived 钩子函数。
3.谈谈MVVM和MVC
MVVM是Model-View-ViewModel的简写,model是模型,view是视图,ViewModel是视图模型。模型是后台传递的数据,视图是所看见的界面,视图模型是将模型和视图连接起来的桥梁。它本质上就是MVC的改进版。采用双向数据绑定,View的变动,自动反映在 ViewModel,反之亦然。
MVC全名是Model-View-Controller的简写,M和V和MVVM中的M和V一样的意思也是模型和视图,controller是控制器,业务逻辑。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
MVVM和MVC区别
-
MVC中的Controller演变成了MVVM中ViewModel
-
在MVC中View是可以直接访问Model的,而在MVVM中View和Model是不能直接交互的,而是通过ViewModel进行连接的
-
mvvm 通过数据来驱动视图层的显示而不是节点操作
-
MVC是单向通信,MVVM是双向通信
-
MVVM的响应式原理
vue核心即采用数据劫持结合发布者-订阅者模式,通过ES5中Object.defineProperty()的特性来劫持各个属性的setter,getter,在数据变动时发消息给订阅者,触发对应watcher的回调,以致于view更新的效果。
MVVM优缺点
优点
-
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
-
可重用性。可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
-
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计
-
可测试。界面素来是比较难于测试的,测试可以针对ViewModel来写。
缺点
-
双向绑定让bug难以调试
-
消耗内存
4.Vue是如何实现数据双向绑定的?
vue数据双向绑定是通过数据劫持结合订阅者,发布者的方式来实现的,通过Object.defineProperty()来劫持各个属性的setter,getter,当数据变动时发布消息给订阅者,触发相应的监听回调
5.v-show和v-if的区别
-
v-show和v-if都是用来控制隐藏和显示的
-
v-show和css中的display一样进行显示和隐藏,dom还在,适合不断切换显示隐藏使用
-
v-if是当满足条件时才会进行显示,每次显示显示都会重新渲染dom,隐藏时销毁dom
6.v-if和v-for可以一起使用吗?
不可以,vue的官网有明确的说明:v-for的优先级比v-if高,先循环再做判断会造成性能浪费,使用过程中不要把它们放在同一个元素上。
7.computed和watch的区别
首先computed和watch都是监听数据变化的属性
- component是计算属性,基于data中声明过的或者props中的值变化计算出的新值;会有缓存;依赖值发生变化时才会发生调用;第一次执行的时候就会有监听;必须有return返回;不支持异步
- watch是监听属性,数据变化后的回调,深度监听添加deep:true,第一个执行时候没有监听,如果需要第一次执行时候监听,添加immediate:true;有两个参数第一个是数据改变后的新值,第二个是数据改变之前的值;可以没有return;支持异步;函数名必须与data中声明过的或者props中的数据一致
8.$ router和$route的区别
-
$ router是Vue Router的一个实例,包含了所有路由,包括跳转的方法、钩子函数还有一些子对象,比如:$ router.push、$ router.replace、$router.go等。 $router是一个全局API,可以在组件内部和外部使用
-
$ route是当前活动路由信息对象,包含当前路由的路径、参数、query等信息。$ route可以用来访问当前路由信息,比如:$ route.params、$ route.query等。$ route只能在组件内部使用,因为$ route包含了当前活跃路由的具体信息,只有组件与路由深度绑定时才会有$route属性。
总之,$ router用来控制路由跳转,$route用来访问当前路由信息。
9.vue中组件间通信方法
- props 和$emit
父传子 props+v-bind/:
子传父 $emit + v-on/@ - 兄弟间传参
首先要创建一个新的vue实例,然后引入在通过$ emit发送$on接收
创建新的vue实例
import vue from ‘vue’
const eventBus = new Vue()
export default eventBus
发送事件
import eventBus from './eventBus .js'
eventBus.$emit('name', data)
接收事件
import eventBus from './eventBus .js'
eventBus.$on('name', (data)=>{
console.log(data)
})
-
$parent 和 $children
父组件获取子组件数据和方法$children
子组件获取父组件数据和方法$parent
-
refs和$ref
在父级引入子组件并定义refs,然后就可以在父组件$ ref使用 this.$ref.childName.事件名/变量
-
Provide 和 Inject
Provide 和 Inject可以将父组件传给所有后代组件
父组件通过 provide 提供数据
export detault {
provide:{
mes:'你好'
}
}
子组件通过Inject接收
export detault {
inject:['mes']
}
- vuex
vuex是vue用于状态管理的一个官方插件。属性有state,getter,mutations,actions,module。
首先我们要创建一个Vuex store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = { // 在这里定义状态 }
const mutations = { // 修改state中的数据 }
const actions = { // 定义异步操作函数 }
export default new Vuex.Store({
actions,
mutations,
state
})
10. data为什么是一个函数?
为保证组件的可重用性和独立性。如果直接使用一个对象作为data,则不同的组件将共享同一个data对象,如果某个组件修改了data,则会影响到其他组件,导致数据混乱。所以data必须是一个函数,每个组件实例都有自己的独立的data数据。这样每次创建组件都会返回一个新的data对象就避免了组件间共享问题。
11.key的作用
唯一标识。提高渲染性能,避免出现重复渲染,渲染错误等问题
12.diff优化方法
在Vue.js中,diff算法是虚拟DOM的核心,用于对比新旧DOM树的差异,并进行最小化更改的渲染操作。
- v-show代替v-if
- 使用key来提高性能
- 异步渲染,减少不必要的DOM操作,提高页面性能
13.vue中常见指令
- v-text
- v-html
- v-model
- v-bind
- v-on
- v-for
- v-if v-else
- v-show
- v-slot
13. vue-router有哪些导航钩子?
-
beforeEach:全局前置守卫router.beforeEach(to,from,next),用于在路由切换之前进行一些操作,比如身份验证等,可以通过next函数进行路由拦截或跳转。
-
afterEach:全局后置钩子,在路由切换后进行一些操作,比如页面统计等。
路由组件内守卫
-
beforeRouteEnter:在路由进入组件之前触发,可以通过next函数获取组件实例,并进行异步操作,比如获取数据等。
-
beforeRouteUpdate:在当前路由改变,但该组件被复用时触发,比如多个路由共用一个组件时。
-
beforeRouteLeave:在路由离开组件之前触发。可以用来确认是否要离开当前页面,比如弹窗提示等。
14.vue常用修饰符
- .prevent:阻止默认事件
- .stop:阻止冒泡事件
- .self:只在自己本身触发
- .once:只触发一次
- .capture:捕获模式
- .lazy:懒加载模式
- .trim:去除首尾空格
- .number:格式化为数字类型
15.vue2.0和3.0的区别
- 双向数据绑定原理
Vue2.0数据双向绑定原理采用数据劫持结合订阅者、发布者模式,通过Object.defineProperty()来劫持各个属性的setter,getter,当数据变动时发布消息给订阅者,触发相应的监听回调
Vue3.0 数据双向绑定采用new Proxy() 对数据进行代理
数据和方法定义
Vue2使用Options API,Vue3使用合成型Composition API
// vue2.0
data(){
return {}
},
methods:{}
//vue3.0 数据和方法都在setup中
setup(){
// setup 中是不能使用 this 的,因为setup 函数会在 beforeCreate 之前调用,此时组件的 data 和 methods 还没有初始化
//setup 中this 是undefined
return {}
}
- Vue.js 3.0 完全支持 TypeScript
- 生命周期
onRenderTracked(() =>{})和onRenderTriggered(() => {}) 新增的debug钩子 ,生产环境中会被忽略 - vue3.0支持 Fragments 碎片化节点
// vue2.0
<template>
<div class="content">
<p>这里是vue2.0</p>
</div>
</template>
// vue3.0
<template>
<div class="content">
<p>这里是vue3.0</p>
</div>
<p>这里也是vue3.0</p>
</template>
- 父子传值方式不同
// 父传子 props
// vue2.0
export default {
props: {
title: String
}
}
// vue3.0
import { toRefs } from 'vue'
export default {
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
}
}
// 子传父 $emit
// vue2.0
export default {
methods:{
saveClick(){
this.$emit('save', {name:'张三', sex: '男'})
}
}
}
//vue3.0
export default {
setup(props, { emit }) {
const sonClick = () => {
emit('save', {name:'张三', sex: '男'})
}
}
}
- Vue3.0添加Teleport传送组件
有什么问题,大家可以提出来哦!我会及时改正的,多多指教。嘻嘻