Vue常见面试题目

56 篇文章 2 订阅
45 篇文章 1 订阅

computed与watch区别

computed(计算属性)watch(侦听器)
定义与用途计算属性(computed)用于声明式地描述一些依赖响应式属性的计算值。当依赖的响应式属性值发生变化时,计算属性会重新求值。侦听器(watch)允许你执行异步操作或开销较大的操作,以响应数据的变化。它更专注于数据变化后的响应,而不是数据本身。
返回值有返回值,计算属性会基于其依赖的属性返回一个新的值。监听函数不需要返回值,它主要执行一些操作,如发送请求、更新其他数据等。
缓存机制支持缓存。只有当计算属性所依赖的响应式属性发生变化时,它才会重新计算。如果依赖没有变化,则直接使用缓存中的值。不支持缓存。每次侦听的数据变化时,都会触发相应的操作,不论该操作是否已执行过。
异步支持不支持异步操作。如果计算属性内部包含异步操作,则无法正确监听数据变化。支持异步操作。你可以在侦听函数中执行异步操作,如发送网络请求。
触发时机默认情况下,计算属性在组件实例化时立即计算一次(如果有依赖),并在其依赖的响应式属性变化时重新计算。默认情况下,侦听器在组件实例化时不立即执行,除非设置了immediate: true。当侦听的数据变化时,执行相应的操作。
深度监听不支持深度监听(虽然可以通过getter函数内部逻辑实现复杂依赖的监听),但计算属性通常用于简单的依赖关系。支持深度监听(通过deep: true),可以监听对象内部属性的变化。但请注意,深度监听可能会带来性能问题。
适用场景当一个值依赖于其他多个值时,使用计算属性可以简化模板中的表达式,并提高性能(通过缓存)。当需要在数据变化时执行异步操作或复杂逻辑时,使用侦听器更为合适。

为什么Vue3性能比Vue2好

1. 响应式系统改进

  • Proxy替代Object.defineProperty:Vue3使用ES6的Proxy对象替代了Vue2中的Object.defineProperty方法来实现响应式系统。Proxy可以拦截对象属性的读取、赋值等操作,无需像Object.defineProperty那样递归地对每个属性进行劫持,从而提高了性能。同时,Proxy还能监听属性的新增和删除,使得响应式系统更加完整和高效。

2. 模板编译优化

  • 更高效的编译算法:Vue3对模板编译过程进行了优化,使得生成的渲染函数更加高效。这有助于减少在渲染过程中的计算量,提高渲染性能。

3. Diff算法优化

  • 静态提升:Vue3在Diff算法中引入了静态提升技术。它会在初次渲染时,将不会变化的DOM节点标记为静态节点,并在后续的渲染过程中直接复用这些静态节点,避免了不必要的DOM操作。
  • 更高效的Diff算法:Vue3采用了更Diff高效的算法来比较虚拟DOM之间的差异,并只更新**有:差异Vue的部分3,采用了而不是更加重新模块渲染整个组件。这种优化可以大大减少不必要的DOM操作,提高渲染性能。

4. 体积减小

  • **模块化设计化的设计,将Vue的核心功能拆分成多个独立的模块。这使得开发者可以根据项目的实际需求,只引入需要的模块,从而减少最终打包体积。
  • Tree Shaking:Vue3支持Tree Shaking,可以在打包过程中移除未使用的代码,进一步减小打包体积。

5. 更好的性能优化策略

  • 事件侦听缓存:Vue3使用了事件侦听缓存机制,将侦听器缓存到指令实例中,减少了创建和销毁侦听器的次数,从而提高了性能。
  • 减少不必要的计算:Vue3在内部实现上进行了大量的优化,减少了不必要的计算量,提高了整体性能。

6. 自定义渲染API

  • 更灵活的渲染方式:Vue3引入了一个新的自定义渲染API,允许开发者更加灵活地控制组件的渲染方式。这有助于开发者根据项目需求,优化渲染过程,提高性能。

http VS https

HTTP?HTTPS?HTTP2.0-CSDN博客

数据发生变化,视图没更新

  1. 使用this.$set
    this.$set是Vue实例的一个方法,用于向响应式对象中添加一个属性,并确保新属性也是响应式的,同时触发视图更新。这个方法接受三个参数:目标对象、属性名(或索引)和新值。

    this.$set(this.someObject, 'newProperty', 'newValue'); 
    this.$set(this.someArray, indexOfItem, newValue);
  2. 使用Vue.set(Vue 2.x)
    在Vue 2.x中,如果你不在组件的方法中,而是需要在一个全局或混合的上下文中添加响应式属性,你可以使用Vue.set。Vue 3.x移除了这个全局方法,但this.$set仍然可用。

  3. this.forceUpdate()
    this.forceUpdate()强制Vue实例重新渲染。它仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。虽然这可以解决更新问题,但它是一个比较粗暴的方法,因为它会忽略组件的所有条件渲染和watcher等,可能会导致不必要的性能开销。通常,应该避免使用此方法,除非确实没有其他办法。

  4. 深拷贝
    深拷贝对象或数组可能会解决某些更新问题,因为它创建了一个全新的对象或数组,然后Vue可以追踪这个新对象的变化。但是,这种方法通常不推荐用于解决响应式问题,因为它会破坏原有的响应式引用,并可能导致其他不可预见的问题(如失去对原始数据的引用)。此外,深拷贝也会带来性能开销。

  5. 确保数据在组件的data函数中返回
    确保你修改的数据是在Vue组件的data函数中返回的对象或数组的一部分。如果数据是在data函数外部定义的,那么Vue无法追踪其变化。

  6. 使用Vue 3的reactiveref
    如果你使用的是Vue 3,可以使用Composition API中的reactiveref来确保你的数据是响应式的。reactive用于对象,而ref可以用于任何类型的值(包括对象和数组),但会返回一个响应式且可变的ref对象,你需要通过.value来访问或修改其值。

封装的自定义指令

一、自定义指令的基本概念

Vue除了提供内置的指令(如v-modelv-showv-if等)外,还允许开发者注册自定义指令。自定义指令提供了一种机制,通过它可以封装一些DOM操作,以扩展Vue的功能。自定义指令以v-为前缀(在注册时不需要前缀,但在使用时需要),后跟自定义的指令名。

二、注册自定义指令

自定义指令可以通过两种方式注册:全局注册和局部注册。

  1. 全局注册
    使用Vue.directive(id, [definition])方法注册一个全局自定义指令。这个指令将在所有Vue实例中可用。

Vue.directive('my-directive', {  
  // 钩子函数  
  inserted: function (el) {  
    // 指令的逻辑  
    el.style.color = 'blue';  
  }  
});

 局部注册
在Vue组件的directives选项中注册一个局部自定义指令。这个指令仅在该组件及其子组件中可用。

export default {  
  directives: {  
    myDirective: {  
      inserted: function (el) {  
        el.style.color = 'red';  
      }  
    }  
  }  
}

三、自定义指令的钩子函数

自定义指令可以包含几个可选的钩子函数,这些函数会在不同的时间点被调用:

  • bind:只调用一次,指令绑定到第一次元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
  • update:当指令的绑定值发生变化时调用,但不论绑定值是否变化都会调用。
  • componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  • unbind:只调用一次,指令与元素解绑时调用。

四、自定义指令的参数和修饰符

自定义指令可以接受参数和修饰符,这些都可以在指令的钩子函数中以特殊的方式访问:

  • 参数:通过:传递给指令,在钩子函数中可以通过binding.arg访问。
  • 修饰符:以.表示的特殊后缀,在钩子函数中通过binding.modifiers访问,它是一个对象,包含了所有修饰符及其布尔值。 

五、使用自定义指令

注册自定义指令后,可以在Vue模板中通过v-前缀和指令名来使用它,同时可以传递参数和修饰符。

<div v-my-directive:arg.modifier="value"></div>

六、实际应用

自定义指令在Vue应用中有着广泛的应用场景,如:

  • 聚焦元素:在页面加载或特定事件触发时,自动聚焦到某个元素。
  • 动态样式:根据绑定值动态改变元素的样式。
  • 权限控制:根据用户的权限动态显示或隐藏元素。
  • 复杂DOM操作:封装一些复杂的DOM操作逻辑,提高代码的复用性和可维护性。

Vue的代理和环境变量

在Vue项目中,处理跨域请求和根据不同环境(如开发环境、测试环境、生产环境)使用不同的配置是常见的需求。Vue CLI 提供了便捷的方式来处理这些问题,主要通过配置代理(Proxy)和环境变量(Environment Variables)来实现。

代理(Proxy)

在开发模式下,Vue CLI 提供了一个基于 http-proxy-middleware 的开发服务器,它可以帮助你解决开发过程中的跨域问题。你可以在 vue.config.js 文件中配置代理规则。

  1. 创建或编辑 vue.config.js 文件
    在项目根目录下,如果没有 vue.config.js 文件,则创建一个。这个文件是可选的,但如果你需要自定义Vue CLI的内部webpack配置,就需要这个文件。

  2. 配置代理
    在 vue.config.js 文件中,你可以通过 devServer.proxy 选项来设置代理规则。

// vue.config.js  
module.exports = {  
  devServer: {  
    proxy: {  
      '/api': {  
        target: 'http://example.com', // 目标API地址  
        changeOrigin: true, // 是否跨域  
        pathRewrite: {'^/api': ''} // 路径重写  
      }  
    }  
  }  
}
  1. 这样配置后,当你访问 /api/some/path 时,实际上会请求到 http://example.com/ some/path

环境变量

Vue CLI 项目支持两种环境变量:

  • 客户端环境变量:以 VUE_APP_ 开头的变量,会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中。你可以在 public/index.html、组件的 .vue 文件或JavaScript文件中通过 process.env.VUE_APP_XXX 访问它们。

  • Node.js 环境变量:在 vue.config.js、插件选项、加载器选项等仅运行在构建过程中的代码中通过 process.env.XXX 访问。

  1. 设置环境变量
    在 .env.env.local.env.[mode] 和 .env.[mode].local 文件中设置环境变量。其中,[mode] 是你运行Vue CLI命令时通过 --mode 参数指定的模式,默认为 developmentproduction 和 test

    例如,在 .env.production 文件中设置:

VUE_APP_API_BASE_URL=https://api.example.com

在代码中访问环境变量
在客户端代码中,你可以通过 process.env.VUE_APP_API_BASE_URL 访问上面设置的环境变量

axios.get(`${process.env.VUE_APP_API_BASE_URL}/some/path`)  
  .then(response => {  
    // 处理响应  
  })  
  .catch(error => {  
    // 处理错误  
  });

底层原理

  1. Webpack的DefinePlugin插件
    • Webpack的DefinePlugin允许你在编译时创建一些全局常量。这些常量在编译时会被静态地替换到你的代码中,因此它们可以作为编译时的环境变量来使用。
    • 在Vue CLI项目中,当你设置以VUE_APP_开头的环境变量时,Vue CLI会自动利用Webpack的DefinePlugin将这些变量注入到项目的构建过程中。
  2. Vue CLI对环境变量的处理
    • Vue CLI在构建项目时,会读取项目根目录下的.env.env.local.env.[mode].env.[mode].local等文件(其中[mode]是构建模式,如developmentproduction等)。
    • 这些文件中以VUE_APP_开头的变量会被识别为客户端环境变量,并通过Webpack的DefinePlugin注入到项目的构建配置中。
    • 在构建过程中,Webpack会替换掉代码中所有对process.env.VUE_APP_XXX的引用,将其替换为相应的环境变量值。

为什么能访问到配置的VUE_APP_BASE_URL

  • 编译时替换:由于Webpack的DefinePlugin在编译时就已经将process.env.VUE_APP_XXX替换为了具体的值,因此在运行时的代码中,process.env.VUE_APP_BASE_URL等环境变量实际上已经被替换为了字符串常量。
  • 客户端可用:这些替换后的字符串常量会包含在最终打包的JavaScript文件中,因此它们可以在客户端代码中直接访问和使用。
  • 安全性:只有以VUE_APP_开头的变量才会被注入到客户端代码中,这是为了防止敏感信息(如数据库密码、API密钥等)被意外地暴露给客户端。

综上所述,Vue CLI通过结合Webpack的DefinePlugin插件和自身的环境变量处理机制,实现了在Vue项目中配置和使用环境变量的功能。这使得开发者能够根据不同的构建模式(如开发模式、生产模式等)来使用不同的环境变量值,从而提高了项目的灵活性和可维护性

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值