课程链接

一、vue2篇

1. 关于生命周期

1.1 生命周期有哪些?发送请求在created还是mounted?

  • vue2.x系统自带有8个
    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • beforeDestroy
    • destroyed
  • 这个问题具体要看项目和业务的情况了,因为组件的加载顺序是,父组件引入了子组件,那么先执行父的前3个生命周期,再执行子的前4个生命周期,那么如果我们的业务是父组件引入子组件,并且优先加载子组件的数据,那么在负组件中当前的请求要放mounted中,如果当前组件没有依赖关系那么放在哪个生命周期中请求都是可以的。

1.2 为什么发送请求不在beforeCreate里?beforeCreate和created有什么区别?

  • 如果请求是在methods封装好了,在beforeCreate调用的时候,beforeCreate阶段是拿不到methods里面的方法的(会报错)
  • 区别:
    • beforeCreate没有$data
    • created中有$data
    • created是可以拿到methods的方法的
    • beforeCreate拿不到methods的方法

1.3 在created中如何获取dom?

  • 只要写异步代码、获取dom是在异步中获取的,就可以了
    • 例如:setTimeout、请求、Promise.xxx()等等
  • 使用vue系统内置的this.$nextTick

1.4 一旦进入组件会执行哪些生命周期?

  • beforeCreate:没DOM没data
  • created:没DOM有data
  • beforeMount:没DOM有data
  • mounted:有DOM有data

1.5 第二次或者第N次进去组件会执行哪些生命周期?

  • 如果当前组件加入了keep-alive,只会执行一个生命周期
    • activated
  • 如果没有加入keep-alive
    • beforeCreate
    • created
    • beforeMount
    • mounted

1.6 父组件引入子组件,那么生命周期执行的顺序是?

  • 父:beforeCreate、created、beforeMount
  • 子:beforeCreate、created、beforeMount、mounted
  • 。。。
  • 父:mounted

1.7 加入keep-alive会执行哪些生命周期?

  • 如果使用了keep-alive组件,当前的组件会额外增加2个生命周期(系统8+2)
    • activated
    • deactivated
  • 如果当前组件加入了keep-alive第一次进入这个组件会执行5个生命周期
    • beforeCreate
    • created
    • beforeMount
    • mounted
    • activated

1.8 你在什么情况下用过哪些生命周期?说一说生命周期使用场景?

  • created ===> 单组件请求
  • mounted ===> 同步可以获取dom,如果线子组件请求后父组件请求
  • activated ===> 判断id是否相等,如果不相同发起请求
  • destroyed ===> 关闭页面记录视频播放的时间,初始化的时候从上一次的历史开始播放

2. 关于组件

2.1 组件传值(通信)的方式

  • 父传后代(后代拿到了父的数据)
    • 第一种
      • 父组件引入子组件,绑定数据<List :str1="str1"></List>
      • 子组件通过props来接收props:{str1:{type:String,default:''}}
      • 这种方式父传子很方便,但是父传给孙子辈分的组件就很麻烦(父=>子=>孙)
      • 这种方式:子不能直接修改父组件的数据
    • 第二种
      • 子组件直接使用父组件的数据
      • 子组件通过:this.$parent.xxx使用父组件的数据
      • 这种方式:子可以直接修改父组件的数据
    • 第三种
      • 依赖注入
      • 优势:父组件可以直接向某个后代组件传值(不用一级一级的传递)
      • 父组件 provide(){return {val1:''}}
      • 后代组件inject:['val1']
  • 后代传父(父拿到了后代的数据)
    • 第一种:子组件传值给父组件
      • 子组件定义自定义事件btn(){this.$emit('change',this.str2)}
      • 父组件@change="homeBtn" homeBtn(val){console.log(val)}
    • 第二种:父组件直接拿到子组件的数据<List ref="child"></List> this.$refs.child
  • 平辈之间的传值(兄弟可以拿到数据)
    • 通过新建bus.js文件来做

bus.js

import Vue from 'vue'
export default new Vue()

传值方List.vue

<button @click="btn">按钮</button>
import bus from '@/utils/bus'
btn(){
	bus.$emit('change',this.str3)
}

接收方new.vue

bus.$on('change',val=>{
	console.log(val)
})

2.2 父组件如何直接修改子组件的值

<List ref="child"></List>
this.$refs.child.xxx = 'yyy'

2.3 子组件如何直接修改父组件的值

  • 子组件中可以使用:this.$parent.xxx去修改

2.4 如何找到父组件

  • this.$parent

2.5 如何找到根组件

  • this.$root

2.6 keep-alive

缓存当前组件

2.7 slot

  • 匿名插槽:插槽没名字
    • <slot></slot> <List><div>温馨提示</div></List>
  • 具名插槽:插槽有名字
    • <slot name="footer"></slot> <List><template #footer><div>温馨提示</div></template></List>
  • 作用域插槽:传值
    • <slot name="footer" :arr='arr'></slot> <List><template #footer='{arr}'><div>温馨提示</div></template></List>

2.8 provide/inject

  • provide/inject===>依赖注入

2.9 如何封装组件

  • 组件一定要难点,涉及的知识点:slot、组件通信…

3. 关于Vuex

3.1 Vuex有哪些属性

  • state:全局共享属性
  • getters:针对于state数据进行二次计算
  • mutations:存放同步方法的
  • actions:存放异步方法的,并且是来提交mutations
  • modules:把vuex再次进行模块之间的划分

user.js

export default{
	state:{
		token:'fagnymnsytdm'
	}
}

store/index.js

import user from './modules/user'
modules:{
	user
}
{{token}}
import {mapState} from 'vuex'
computed:{
	...mapState({
		token:state=>state.user.token
	})
}

3.2 Vuex使用state值

  • this.$store.state.xxx
  • 辅助函数:import {mapState} from 'vuex' computed:{...mapState(['str'])}
  • 以上两种方式都可以拿到state的值,那么区别是什么?
    • 使用this.$store.state.xxx是可以直接修改vuex的state数据的
    • 使用辅助函数的形式,是不可以修改的

3.3 Vuex的getters值修改

  • getters是不可以修改的
  • 面试官可能会这么问:组件使用了getters中的内容,组件使用采用v-model的形式会发生什么?
    • 页面可以显示,但是页面修改就会报错
getters:{
	changStr(state){
		return state.str + 'x'
	}
}
//第一种
{{$store.getters.changStr}}--{{changeStr}}
//第二种
import {mapGetters} from 'vuex'
computed:{
	...mapGetters(['changeStr'])
}

3.4 Vuex的mutations和actions区别

  • 相同点:mutations和actions都是用来存储全局方法的,这个全局方法return的值拿不到
  • 区别:
    • mutations:同步
    • actions:返回的是一个Promise,他可以执行相关异步操作
    • mutations是来修改state的值的,actions的作用是来提交mutations

3.5 Vuex持久化存储

  • vuex本身不是持久化存储的数据。vuex是一个状态管理仓库(state:全局属性)===> 就是存放全局属性的地方
  • 实现持久化存储
    • 自己写localstorage
    • 使用vuex-persistedstate插件

4. 关于路由

4.1 路由的模式和区别

  • 路由的模式:history、hash
  • 区别:
    • 关于找不到当前页面发送请求的问题
      • history会给后端发送一次请求而hash不会
    • 关于项目打包前端自测问题
      • hash是可以看到内容的
      • history默认情况下是看不到内容的
    • 关于表象不同
      • hash:#
      • history:/

4.2 子路由和动态路由

4.3 路由传值

4.4 导航故障

官网说明
解决:

import VueRouter from 'vue-router'
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function(location){
	return routerPush.call(this,location).catch(error => error)
}

4.5 $router和$route区别

  • $router不仅包含当前路由还包含整个路由的属性和方法
  • $route包含当前路由对象

4.6 导航守卫

  • 全局守卫
    • beforeEach:路由进入之前
    • afterEach:路由进入之后
  • 路由独享守卫
    • beforeEnter:路由进入之前
    • {path:'/about',name:about,beforeEnter:function(to, from, next){if(false){next()}else{next('/login')}}}
  • 组件内守卫
    • beforeRouteEnter:路由进入之前
    • beforeRouteUpdate:路由更新之前
    • beforeRouteLeave:路由离开之前

5. 关于API

5.1 $set

面试官:你有没有碰到过,数据更新视图没更新的问题==>$set

this.$set(this.arr,'1','xxxxx')

5.2 $nextTick

  • $nextTick返回的参数【函数】,是一个异步的。功能:获取更新后的dom
  • 源码|原理:
  • $nextTick(callback){return Promise.resolve().then(()=>{callback()})}

5.3 $refs

  • 来获取dom

5.4 $el

  • 来获取当前组件的根节点

5.5 $data

  • 获取当前组件data数据的

5.6 $children

  • 是获取到当前组件的所有子组件的

5.7 $parent

  • 找到当前组件的父组件,如果找不到返回自身

5.8 $root

  • 找到根组件

5.9 data定义数据

数据定义在data的return内和return外的区别:

  • return外:单纯修改这个数据是不可以修改的,因为没有被get/set
  • return内:是可以修改的
data(){
	this.num = 222
	return {
		str:1111
	}
}

5.10 computed计算属性

  • computed计算属性的结果值,可以修改吗?可以的,需要通过get/set写法
  • 当前组件v-model绑定的值是computed来的,那么可以修改吗?可以的,需要通过get/set写法

5.11 watch

watch:{
	obj:{
		handler(new,old){
			console.log('obj',new,old)
		},
		immediate:true,
		deep:true
	}
}

5.12 methods和computed区别

computed是有缓存机制的(单价、总价、数量、购物车、…),methods是没有缓存机制的(调用几次执行几次)

6. 关于指令

6.1 如何自定义指令

  • 全局:main.js
Vue.directive('demo',{
	inserted:function(a,b,c){
		console.log(a,b,c)
	}
})
  • 局部:某一个组件内
export default{
	directives:{
		demo:{
			bind:function(el){
				console.log(1)
			}
		}
	}
}

6.2 vue单向绑定

  • 双向绑定:v-model
  • 单向绑定:v-bind

6.3 v-if和v-for优先级

  • vue2中:v-for > v-if
  • vue3中:v-if > v-for

7. 关于原理

7.1 $nextTick原理

  • $nextTick功能:获取更新后的dom
  • $nextTick(callback){return Promise.resolve().then(()=>{callback()})}

二、vue3篇

1. vue2和vue3区别

  • vue2和vue3双向绑定方法不同
    • vue2:Object.defineProperty()
      • 后期添加爹属性是劫持不到的
    • vue3:new Proxy()
      • 即使后添加的也可以劫持到
      • 还不需要循环
  • $set在vue3中没有,因为new Proxy不需要
  • 关于写法
    • vue2是选项式
    • vue3是可以向下兼容(选项式API),也可以组合式api或setup语法糖形式
  • vue2 + webpack ; vue3 + ts + pinia + vite
  • v-if和v-for优先级不同了
  • ref和$children也不同

2. vue3如果用setup写怎么组织代码 / vue3 hooks

  • mixins===>写了一些属性 | 方法,可以在全局或者某个组件中使用,没有template
  • hooks(就是函数式),主要让功能模块细分(提升项目的可维护性)
    • 解决问题:<script setup>//代码===>比较乱</script>
  • 面试官:你们写vue3写代码的方式 ===> setup形式
  • 不会乱吗?解决:hooks

3. vue3如果用setup写如何获取类似于vue2中的this

loading/index.js

export default {
	install(app){
		app.config.globalProperties.$loading = '加载中...'
	}
}
import {getCurrentInstance} from 'vue'
let app = getCurrentInstance()
console.log(app.appContext.app.config.globalProperties.$loading)

4. vue3常用api有哪些

  • createApp() ⇒ 创建一个应用实例
    • 说明:等于vue2的 ===> new Vue()
    • 使用场景:写插件(封装全局组件会使用)
  • provide/inject ===> 依赖注入
    • 说明:其实就是传值
    • 使用场景:某一个父组件传值到后代组件,如果层级过多传递麻烦,所以使用
    • 缺点:不好维护和查询数据来源
  • directive
    • 说明:自定义指令
    • 场景:后台管理系统中的按钮权限控制( 一个用户拥有某些权限,但是只能查看和修改,不能删除)
  • mixin
    • 说明:1.全局混入 2. 局部
    • 场景:可以添加生命周期,我在小程序的分享功能会用到
    • 缺点:不好维护和查询数据来源
  • app.config.globalProperties
    • 说明:获取vue这个全局对象的属性和方法
    • 场景:自己封装插件的时候需要把方法添加到对象中
  • nextTick
    • 说明:等待下一次 DOM 更新刷新的工具方法 :nextTick返回一个Pormise,回调函数是放在Promise中的,所以是异步执行的
    • 场景:就是把dom要更新,那么vue是数据驱动dom,所以数据的赋值就要在nextTick进行
  • computed
    • 说明:计算属性
    • 场景:有缓存
  • reactive、ref
    • 说明:来定义数据的和vue2的data类似
  • watch
    • 说明:监听(Vue3不需要深度监听)
  • markRaw()
    • 说明:不被new Proxy代理,说白了就是静态的数据
  • defineProps()
    • 说明:父组件传递的值,子组件使用setup的形式,需要用defineProps接收
  • defineEmits()
    • 当前组件使用setup形式,自定义事件需要使用defineEmits
  • slot
    • 说明:分为 1. 匿名 2. 具名 3. 作用域
    • 场景:后台管理系统,左侧是固定菜单,右侧是不固定内容,那么右侧就是slot

5. 请介绍一下vue3常见的响应式数据类型

  • ref :基本类型
  • reactive :复杂类型
  • toRef :解构某一个值let name = toRef(obj, 'name')
  • toRefs : 解构多个值let {name, age} = roRefs(obj)

6. 请介绍一下teltport组件集齐使用场景

在这里插入图片描述

teleport组件是一个传送门
假如自己写弹出框,需要在页面居中位置展示,不受当前组件的限制,可以把盒子传送到body中

<teleport to='body'>
	<div class='no' v-if='show'></div> //居中显示的内容
</teleport>
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐