题目来源:牛客
Vue生命周期函数都有哪些
Vue2
- beforeCreate: 组件初始化之后,进行数据侦听和事件/侦听器的配置之前执行
- created: 组件创建完成之后立即同步执行,已配置数据侦听、计算属性、方法等回调函数
- beforeMount: 挂载开始之前执行,相关的render函数首次被调用
- mounted: 组件挂载后执行,不能保证所有的子组件也都被挂载完毕
- beforeUpdate: 数据发生改变,DOM被更新之前执行
- updated: 数据更改导致虚拟DOM重新渲染和更新完毕之后调用
- activated: 被keep-alive缓存的组件激活时调用
- deactivated: 被keep-alive缓存的组件失活时调用
- beforeDestoryed: 组件销毁之前调用
- destoryed: 组件销毁之后调用
- errorCaptured: 捕获到后代组件的错误时调用
Vue3
- onMounted: 组件挂载完毕后执行
- onUpdated: 组件因为响应式状态变更而更新其DOM树后执行
- onUnmounted: 组件卸载之后执行
- onBeforeMount: 组件挂载之前执行
- onBeforeUpdate: 组件因为响应式状态变更而更新其DOM树前执行
- onBeforeUnmount: 组件卸载之前执行
- onErrorCaptured: 捕获了后代组件传递的错误时执行
- onRenderTracked: 组件渲染过程中追踪到响应式依赖时调用
- onRenderTriggered: 组件响应式依赖的变更触发了组件渲染时调用
- onActivated: 若组件是keepAlice缓存树的一部分,当组件被插入到DOM中执行
- onDeactivated: 若组件是keepAlice缓存树的一部分,当组件被从DOM中移除执行
- onServerPrefetch: 组件实例在服务器上被渲染之前调用
computed和watch的区别
computed
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed是计算属性,也就是依赖某个值或者props通过计算得来的数据
- computed的值实在getter执行之后进行缓存的,只有在它依赖的数据发生改变时才会重新调用getter来计算
- 默认在第一次加载时就开始监听
- 适用于一条数据受多个数据影响
watch
- 不支持缓存,依赖数据的改变会直接触发相应的操作
- 支持异步操作
- watch是监听器,可以监听某一个数据,然后执行相应的操作
- 监听的函数接收两个参数,第一个参数是最新的值,第二个参数是输入之前的值
- 默认在第一次加载时不监听,可以设置immediate为true
- 适用于一条数据影响多个数据
v-系列有哪些
- v-if: 根据表达式的值的真假渲染元素,值为false时会直接销毁元素
- v-show: 根据表达式的值的真假显示/隐藏元素,值为false会把元素的display设置成hidden
- v-for: 循环指令,基于一个数组或者对象渲染一个列表,需配合key使用
- v-bind: 动态绑定一个或多个特性
- v-on: 用于监听指定元素的DOM事件,比如点击事件
- .stop: 禁止事件冒泡
- .prevent: 阻止事件默认行为
- .capture: 采用捕获模式
- .self: 只当事件是从侦听器绑定的元素本身触发时才执行
- .native: 监听组件根元素的原生事件
- .once: 只触发一次回调
- .left: 鼠标左键点击触发
- .right: 鼠标右键点击触发
- .middle: 鼠标中键点击触发
- v-model: 实现表单输入和应用状态之间的双向绑定
= .lazy: 取代监听input改为监听change事件- .number: 输入字符串转为数字
- .trim: 过滤首位空格
- v-pre: 跳过这个元素和它的子元素的编译过程
- v-once: 只渲染元素和组件一次,随后的重新渲染会跳过组件及其子节点
双向绑定原理
Vue2
当把一个普通的JS对象传入Vue实例作为data选项,Vue将遍历此对象所有的属性并通过Object.defineProperty为其设置getter和setter,从而让Vue能够追踪依赖的变化,在被访问和修改时通知变更。每个组件实例都有一个wacher实例,会把渲染过程中需要的数据记录为依赖,当依赖项的setter触发时,会通知watch,然后把它关联的组件重新渲染
- Vue无法检测对象属性的添加或移除,可以使用vm.$set(obj, property, value)为响应式对象添加响应式属性
- Vue无法检测直接使用索引值设置数组项或修改数组长度,可以使用vm.$set(array, index, newValue)来响应式按索引修改属性值或者使用splice
Vue3
Vue3采用Proxy和Reflect的方法拦截对对象的交互
const exam= {
name: "TOM"
};
const handler = {
get: function (target, property) {
// 检查当前运行的副作用,并将当前属性添加为副作用的依赖——订阅
track(target, property);
return Reflect.get(target.key);
},
set: function (target, property, value) {
// 触发以target.property为依赖的副作用进行更新——发布
trigger(target, property);
return Reflect.set(target, key, value);
}
};
const proxy = new Proxy(exam, handler);
proxy.name = "Jerry";
console.log(proxy.name);
v-model和:value的区别
v-model实现了视图和data中数据的双向绑定,两者其一改变均改变
v-bind:value只是将初始化时data中的数据绑定到input上,修改input中的值并不会改变data中的数据
<template>
<input type="text" v-model="name" />
<input type="text" :value="age" @input="name = $event.target.value">
</template>
v-bind和v-model的区别
同上
v-if和v-show的区别
- v-if: 是真正的条件渲染,会确保子组件被适当的销毁和重建,具有惰性
- v-show: 不管初始条件是什么,元素总会被渲染,并基于CSS进行切换
v-permission怎么用
v-permission是自定义权限控制指令,可以在指令的inserted周期中拿到绑定的value,并与拿到的用户信息作对比,从而选择是否展示组件
// 指令内容
export default {
inserted(el, binding) {
const perValue = binding.value;
if (binding.value) {
const privileges = ['add', 'delere'];
if (!privileges.some(item => item == perValue)) el.style.display = "none";
}
}
}
import permission from "premission";
const directives = { permission };
export default {
install(Vue) {
Object.keys(directives).forEach(key => {
Vue.directive(key, directives[key]);
});
}
}
Vue怎么注册组件
Vue2
import ZmTable from './table'
const components = [ZmTable]
const allGlobalComponents = {
install(Vue) {
try {
components.forEach(component => {
if (!component.name) {
// 跳出 forEach 的技巧
throw new Error('组件必须提供名字,并且使用大驼峰式命名')
} else {
Vue.component(component.name, component)
}
})
} catch (error) {
console.error(error)
}
}
}
export default allGlobalComponents
Vue3
import { App, defineAsyncComponent } from 'vue'
export default {
install(app: App, obtions: any) {
const requireModules = import.meta.glob('../components/common/*.vue')
for (const path in requireModules) {
const result: Array<any> = path.match(/.*/(.+).vue$/)!
const modulesConent: any = requireModules[path]
app.component(result[1], defineAsyncComponent(modulesConent))
}
}
}
状态管理
状态管理用于管理全局状态,通常用于大型项目
VueX
VueX的核心是State+Getter+Mutation+Action,其中State管理全局状态,Getter类似计算属性,Mutation是用于修改State的操作,Action是异步的Mutation,组件中通过this. s t o r e . s t a t e / g e t t e r e 访问状态, t h i s . store.state/gettere访问状态,this. store.state/gettere访问状态,this.store.commit/dispatch修改状态
Pinia
Pinia的核心是Data+Computed+Methods,使用defineStore创建仓库,为了从store中提取属性保持其响应式,需要使用storeToRefs进行包裹
组件通信
- props/$emit
- enevtBus
- VueX
- 本地/会话缓存
- provide/inject
CSS垂直居中
- 设定行高line-height
- 添加伪元素
div { display: inline-block, vertical-align: middle, } div::before { content: "", width: 0, height: 100%, display: inline-block, position: relative, vertical-align: middle }
- calc动态计算
- 使用表格
- transform
- 绝对定位
- flex布局
JS对象有哪些方法
- 增删改查对象或其属性
- 遍历枚举对象的键值
- Object.assign合并对象
- Object.keys遍历对象的键
- Object.values遍历对象的值
- Object.entities遍历对象的键值对数组
- Object.entities将键值对数组转成对象
- Object.prototype访问对象原型
- Object.hasOwnProperty检测对象本身的属性
- Object.freeze冻结对象
JS基本数据类型
- Number
- String
- Boolean
- Null
- Undefined
- Object
- Symbol
const PROP_NAME = Symbol(); const person = { [PROP_NAME]: "123" }; console.log(person[PROP_NAME]);
- Bigint
null和ubdefined的区别
- null表示没有,此处不应该有值,转数值等于0
- undefined表示缺少,此处本应该有值,转数值为NaN
箭头函数和普通函数指向有什么区别
箭头函数的this永远指向其创建时的上下文的this,任何方法都改变不了其指向
普通函数的this指向调用它的那个对象
箭头函数是否有this
箭头函数有this,就是定义该函数时所在的作用域指向的对象,而非使用时所在的作用域指向的对象
typeof null输出什么,typeof undefined输出什么
typeof null的值为object
typeof undefined的值为undefined
reduce怎么使用
reduce为数组的每一个元素依次执行回调函数,参数为:初始值、当前元素值、当前所有、原始数组
const array = [1, 2, 3, 4, 5];
const sum = array.reduce((pre, cur) => pre + cur);
forEach和for循环的区别
- forEach在循环次数未知或者计算起来较为复杂的情况下效率比for高
- forEach在循环进行中时循环对象被锁定,不能对其进行增删改操作
参考资料
Vue2官方文档
Vue3官方文档
Vue中computed和watch的区别
watch和computed的区别
vue常用基本指令和修饰符(面试题)
Vue2双向绑定和Vue3双向绑定原理及区别
vue中v-model和:value(即:v-bind:value)
手动实现一个v-model的不同做法(含封装组件用法)
vue中v-bind和v-model的区别
v-if和v-show的区别详解
【记录】【vue】自定义权限指令v-permission的简单创建及使用
vite+vue3项目批量注册自定义组件的方法
如何更好的注册全局组件
js中foreach和for循环的区别
JS数组reduce()方法详解及高级技巧
typeof使用以及null和undefined的判断区分
ES6箭头函数的this指向详解
箭头函数与普通函数的区别详解
面试题-null和undefined的区别?
JS基础篇1:数据类型(8种)
javascript中symbol类型的应用场景(意义)和使用方法
JavaScript日常开发中常用的Object操作方法
CSS垂直居中的七个方法
Vue组件间的通信方式(多种场景,通俗易懂,建议收藏)
Vue 组件间通信六种方式(完整版)
Vue3之状态管理:Vuex和Pinia,孰强孰弱?
新人创作,礼貌求关题目来源:[牛客](https://www.nowcoder.com/feed/main/detail/f80924fe8b95412cbfa1faf81d859c11?sourceSSR=users)
# Vue生命周期函数都有哪些
## Vue2
- beforeCreate: 组件初始化之后,进行数据侦听和事件/侦听器的配置之前执行
- created: 组件创建完成之后立即同步执行,已配置数据侦听、计算属性、方法等回调函数
- beforeMount: 挂载开始之前执行,相关的render函数首次被调用
- mounted: 组件挂载后执行,不能保证所有的子组件也都被挂载完毕
- beforeUpdate: 数据发生改变,DOM被更新之前执行
- updated: 数据更改导致虚拟DOM重新渲染和更新完毕之后调用
- activated: 被keep-alive缓存的组件激活时调用
- deactivated: 被keep-alive缓存的组件失活时调用
- beforeDestoryed: 组件销毁之前调用
- destoryed: 组件销毁之后调用
- errorCaptured: 捕获到后代组件的错误时调用
## Vue3
- onMounted: 组件挂载完毕后执行
- onUpdated: 组件因为响应式状态变更而更新其DOM树后执行
- onUnmounted: 组件卸载之后执行
- onBeforeMount: 组件挂载之前执行
- onBeforeUpdate: 组件因为响应式状态变更而更新其DOM树前执行
- onBeforeUnmount: 组件卸载之前执行
- onErrorCaptured: 捕获了后代组件传递的错误时执行
- onRenderTracked: 组件渲染过程中追踪到响应式依赖时调用
- onRenderTriggered: 组件响应式依赖的变更触发了组件渲染时调用
- onActivated: 若组件是keepAlice缓存树的一部分,当组件被插入到DOM中执行
- onDeactivated: 若组件是keepAlice缓存树的一部分,当组件被从DOM中移除执行
- onServerPrefetch: 组件实例在服务器上被渲染之前调用
# computed和watch的区别
## computed
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed是计算属性,也就是依赖某个值或者props通过计算得来的数据
- computed的值实在getter执行之后进行缓存的,只有在它依赖的数据发生改变时才会重新调用getter来计算
- 默认在第一次加载时就开始监听
- 适用于一条数据受多个数据影响
## watch
- 不支持缓存,依赖数据的改变会直接触发相应的操作
- 支持异步操作
- watch是监听器,可以监听某一个数据,然后执行相应的操作
- 监听的函数接收两个参数,第一个参数是最新的值,第二个参数是输入之前的值
- 默认在第一次加载时不监听,可以设置immediate为true
- 适用于一条数据影响多个数据
# v-系列有哪些
- v-if: 根据表达式的值的真假渲染元素,值为false时会直接销毁元素
- v-show: 根据表达式的值的真假显示/隐藏元素,值为false会把元素的display设置成hidden
- v-for: 循环指令,基于一个数组或者对象渲染一个列表,需配合key使用
- v-bind: 动态绑定一个或多个特性
- v-on: 用于监听指定元素的DOM事件,比如点击事件
- .stop: 禁止事件冒泡
- .prevent: 阻止事件默认行为
- .capture: 采用捕获模式
- .self: 只当事件是从侦听器绑定的元素本身触发时才执行
- .native: 监听组件根元素的原生事件
- .once: 只触发一次回调
- .left: 鼠标左键点击触发
- .right: 鼠标右键点击触发
- .middle: 鼠标中键点击触发
- v-model: 实现表单输入和应用状态之间的双向绑定
= .lazy: 取代监听input改为监听change事件
- .number: 输入字符串转为数字
- .trim: 过滤首位空格
- v-pre: 跳过这个元素和它的子元素的编译过程
- v-once: 只渲染元素和组件一次,随后的重新渲染会跳过组件及其子节点
# 双向绑定原理
## Vue2
当把一个普通的JS对象传入Vue实例作为data选项,Vue将遍历此对象所有的属性并通过Object.defineProperty为其设置getter和setter,从而让Vue能够追踪依赖的变化,在被访问和修改时通知变更。每个组件实例都有一个wacher实例,会把渲染过程中需要的数据记录为依赖,当依赖项的setter触发时,会通知watch,然后把它关联的组件重新渲染
- Vue无法检测对象属性的添加或移除,可以使用vm.$set(obj, property, value)为响应式对象添加响应式属性
- Vue无法检测直接使用索引值设置数组项或修改数组长度,可以使用vm.$set(array, index, newValue)来响应式按索引修改属性值或者使用splice
## Vue3
Vue3采用Proxy和Reflect的方法拦截对对象的交互
```js
const exam= {
name: "TOM"
};
const handler = {
get: function (target, property) {
// 检查当前运行的副作用,并将当前属性添加为副作用的依赖——订阅
track(target, property);
return Reflect.get(target.key);
},
set: function (target, property, value) {
// 触发以target.property为依赖的副作用进行更新——发布
trigger(target, property);
return Reflect.set(target, key, value);
}
};
const proxy = new Proxy(exam, handler);
proxy.name = "Jerry";
console.log(proxy.name);
v-model和:value的区别
v-model实现了视图和data中数据的双向绑定,两者其一改变均改变
v-bind:value只是将初始化时data中的数据绑定到input上,修改input中的值并不会改变data中的数据
<template>
<input type="text" v-model="name" />
<input type="text" :value="age" @input="name = $event.target.value">
</template>
v-bind和v-model的区别
同上
v-if和v-show的区别
- v-if: 是真正的条件渲染,会确保子组件被适当的销毁和重建,具有惰性
- v-show: 不管初始条件是什么,元素总会被渲染,并基于CSS进行切换
v-permission怎么用
v-permission是自定义权限控制指令,可以在指令的inserted周期中拿到绑定的value,并与拿到的用户信息作对比,从而选择是否展示组件
// 指令内容
export default {
inserted(el, binding) {
const perValue = binding.value;
if (binding.value) {
const privileges = ['add', 'delere'];
if (!privileges.some(item => item == perValue)) el.style.display = "none";
}
}
}
import permission from "premission";
const directives = { permission };
export default {
install(Vue) {
Object.keys(directives).forEach(key => {
Vue.directive(key, directives[key]);
});
}
}
Vue怎么注册组件
Vue2
import ZmTable from './table'
const components = [ZmTable]
const allGlobalComponents = {
install(Vue) {
try {
components.forEach(component => {
if (!component.name) {
// 跳出 forEach 的技巧
throw new Error('组件必须提供名字,并且使用大驼峰式命名')
} else {
Vue.component(component.name, component)
}
})
} catch (error) {
console.error(error)
}
}
}
export default allGlobalComponents
Vue3
import { App, defineAsyncComponent } from 'vue'
export default {
install(app: App, obtions: any) {
const requireModules = import.meta.glob('../components/common/*.vue')
for (const path in requireModules) {
const result: Array<any> = path.match(/.*/(.+).vue$/)!
const modulesConent: any = requireModules[path]
app.component(result[1], defineAsyncComponent(modulesConent))
}
}
}
状态管理
状态管理用于管理全局状态,通常用于大型项目
VueX
VueX的核心是State+Getter+Mutation+Action,其中State管理全局状态,Getter类似计算属性,Mutation是用于修改State的操作,Action是异步的Mutation,组件中通过this. s t o r e . s t a t e / g e t t e r e 访问状态, t h i s . store.state/gettere访问状态,this. store.state/gettere访问状态,this.store.commit/dispatch修改状态
Pinia
Pinia的核心是Data+Computed+Methods,使用defineStore创建仓库,为了从store中提取属性保持其响应式,需要使用storeToRefs进行包裹
组件通信
- props/$emit
- enevtBus
- VueX
- 本地/会话缓存
- provide/inject
CSS垂直居中
- 设定行高line-height
- 添加伪元素
div { display: inline-block, vertical-align: middle, } div::before { content: "", width: 0, height: 100%, display: inline-block, position: relative, vertical-align: middle }
- calc动态计算
- 使用表格
- transform
- 绝对定位
- flex布局
JS对象有哪些方法
- 增删改查对象或其属性
- 遍历枚举对象的键值
- Object.assign合并对象
- Object.keys遍历对象的键
- Object.values遍历对象的值
- Object.entities遍历对象的键值对数组
- Object.entities将键值对数组转成对象
- Object.prototype访问对象原型
- Object.hasOwnProperty检测对象本身的属性
- Object.freeze冻结对象
JS基本数据类型
- Number
- String
- Boolean
- Null
- Undefined
- Object
- Symbol
const PROP_NAME = Symbol(); const person = { [PROP_NAME]: "123" }; console.log(person[PROP_NAME]);
- Bigint
null和ubdefined的区别
- null表示没有,此处不应该有值,转数值等于0
- undefined表示缺少,此处本应该有值,转数值为NaN
箭头函数和普通函数指向有什么区别
箭头函数的this永远指向其创建时的上下文的this,任何方法都改变不了其指向
普通函数的this指向调用它的那个对象
箭头函数是否有this
箭头函数有this,就是定义该函数时所在的作用域指向的对象,而非使用时所在的作用域指向的对象
typeof null输出什么,typeof undefined输出什么
typeof null的值为object
typeof undefined的值为undefined
reduce怎么使用
reduce为数组的每一个元素依次执行回调函数,参数为:初始值、当前元素值、当前所有、原始数组
const array = [1, 2, 3, 4, 5];
const sum = array.reduce((pre, cur) => pre + cur);
forEach和for循环的区别
- forEach在循环次数未知或者计算起来较为复杂的情况下效率比for高
- forEach在循环进行中时循环对象被锁定,不能对其进行增删改操作
参考资料
Vue2官方文档
Vue3官方文档
Vue中computed和watch的区别
watch和computed的区别
vue常用基本指令和修饰符(面试题)
Vue2双向绑定和Vue3双向绑定原理及区别
vue中v-model和:value(即:v-bind:value)
手动实现一个v-model的不同做法(含封装组件用法)
vue中v-bind和v-model的区别
v-if和v-show的区别详解
【记录】【vue】自定义权限指令v-permission的简单创建及使用
vite+vue3项目批量注册自定义组件的方法
如何更好的注册全局组件
js中foreach和for循环的区别
JS数组reduce()方法详解及高级技巧
typeof使用以及null和undefined的判断区分
ES6箭头函数的this指向详解
箭头函数与普通函数的区别详解
面试题-null和undefined的区别?
JS基础篇1:数据类型(8种)
javascript中symbol类型的应用场景(意义)和使用方法
JavaScript日常开发中常用的Object操作方法
CSS垂直居中的七个方法
Vue组件间的通信方式(多种场景,通俗易懂,建议收藏)
Vue 组件间通信六种方式(完整版)
Vue3之状态管理:Vuex和Pinia,孰强孰弱?
新手发文,礼貌求关❤️