【每日前端面经】2023-02-22

题目来源:牛客

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,孰强孰弱?

新手发文,礼貌求关❤️
  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ByeByeWorld02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值