前端面试题[vue2]

一、vue2中为何组件的data必须是一个函数

在Vue2中,每个组件实例都可以有自己的状态,这些状态通常被定义在组件的data选项中。

但是,组件之间是可以复用的,如果data是一个普通对象,那么所有使用该组件的实例都将共享这个对象,一旦其中一个实例改变了这个对象,就会影响到所有其他实例,这种变化不可控

为了避免这种情况,Vue2要求在组件中声明的data必须是一个函数,每当组件实例化的时候,就会调用这个函数,返回一个新的对象,确保每个实例都有自己独立的data对象,这样就能够确保组件之间不会相互干扰。

二、vue常用的指令

Vue常用的指令有:

  1. v-bind:绑定HTML属性和Vue实例的属性,例如:v-bind:href、v-bind:class等。

  2. v-model:将表单元素和Vue实例中的数据双向绑定,例如:v-model:value。

  3. v-if、v-else-if、v-else:根据条件渲染元素或组件,例如:v-if="isShow"。

  4. v-for:循环渲染元素或组件,例如:v-for="(item, index) in list"。

  5. v-on:绑定元素事件,例如:v-on:click、v-on:keyup.enter等。

  6. v-show:根据条件显示或隐藏元素,与v-if不同的是,v-show只是简单的样式隐藏。

  7. v-html:将字符转换为HTML,例如:v-html="htmlContent"。

  8. v-pre:原样输出包含的所有内容,不编译指令和插值表达式。

  9. v-cloak:用于解决页面初次渲染时出现{{message}}的闪烁问题,将其与CSS配合使用。

  10. v-once:只渲染元素或组件一次,之后不再更新。

三、 v-if/v-show区别

v-if和v-show都是Vue.js中用于控制元素显隐的指令,但二者有以下区别:

  1. v-if是条件渲染指令,根据表达式的布尔值来决定是否渲染元素,若为false则不渲染且组件销毁;v-show是简单切换指令,根据表达式的布尔值来决定是否显示元素,若为false则不显示但组件并不销毁。

  2. v-if有更高的切换消耗,因为它是动态销毁和创建组件;而v-show只是根据样式控制显隐。

  3. v-if适用于频繁切换的场景,因为它有个很好的特性:懒加载,即该元素只有在条件为true时才会被渲染,因此可以优化性能和减少不必要的内存开销。而v-show适用于不频繁切换的场景,因为它只是用CSS来控制元素样式的显隐,可以高效地切换。

因此,一般来说,v-if更适合条件较少的场景,而v-show更适合条件较多的场景。

四、vue生命周期

Vue 生命周期被分为8个阶段:

  1. beforeCreate:在Vue实例被创建之初,即在数据观测和初始化事件之前被调用。该阶段主要是为了初始化一些自定义属性或添加一些插件。

  2. created:在Vue实例创建完成后被立即调用。在此阶段,可以访问到Vue实例,并可以在这里进行一些初始数据的设置和方法的定义。

  3. beforeMount:在Vue实例挂载到DOM节点前被调用。在此阶段,Vue会将模板编译成渲染函数,并将其挂载到虚拟DOM上。

  4. mounted:在Vue实例挂载到DOM节点后立即被调用。在此阶段,可以访问到DOM节点,并可以进行一些操作,如使用原生API操作DOM。

  5. beforeUpdate:在数据更新时被调用,但是界面尚未更新。在此阶段,可以进行一些数据的预处理或对比操作。

  6. updated:在数据更新后立即被调用。在此阶段,可以进行一些DOM的操作。

  7. beforeDestroy:在Vue实例销毁之前被调用。在此阶段,可以进行一些清理工作,如清除定时器或取消事件监听器。

  8. destroyed:在Vue实例销毁后立即被调用。在此阶段,Vue实例的所有指令、组件和监听器都已经被解除绑定,可以进行一些垃圾回收工作。

五、vue数据双向绑定原理

Vue实现双向数据绑定的原理主要是通过利用Object.defineProperty()方法监听数据的变化。具体实现过程如下:

  1. 首先,通过Vue实例中的data属性来存储数据,定义需要双向绑定的属性。

  2. 在Vue实例中定义一个变量Dep,作为数据依赖管理器。

  3. 当Vue实例渲染视图时,会触发所有需要双向绑定的属性的getter函数,将Dep与属性关联起来。

  4. 当数据发生变化时,setter函数会被触发,setter函数会通知有依赖关系的所有Watcher进行更新操作。

  5. 在Watcher中进行具体的更新操作,比如将新的数据渲染到视图中。

  6. 最后,当数据双向绑定时,用户更新视图时,也会触发setter函数。

综上所述,Vue实现双向数据绑定是通过getter和setter方法与依赖管理器实现的,使数据变化时自动通知相关依赖进行更新,保证视图和数据的实时同步。

六、 Vue 虚拟 Dom 

虚拟 DOM(Virtual DOM)是 Vue 的一项核心技术。它是基于 JavaScript 对象树来描述真实 DOM 的一种数据结构。在 Vue 中,每一个组件都有一个对应的虚拟 DOM,当组件的状态发生变化时,Vue 会通过比较新旧两棵虚拟 DOM 树的差异,然后只对需要更新的部分进行实际 DOM 操作,从而避免了全量重新渲染,提高了性能和效率。

由于 JavaScript 操作虚拟 DOM 的速度比操作真实 DOM 快得多,因此使用虚拟 DOM 可以大幅减少 DOM 操作带来的性能问题。同时,通过对虚拟 DOM 的操作,开发者也不必关心底层 DOM 操作的细节,更容易进行组件的拆分和复用。

以下是一个简单的 Vue2 虚拟 DOM 的例子:

// 定义一个组件
Vue.component('my-component', {
  template: `
    <div>
      <h1>{{ title }}</h1>
      <p>{{ message }}</p>
    </div>
  `,
  props: ['title', 'message']
})

// 创建一个 Vue 实例
new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue2!'
  },
  render: function(createElement) {
    return createElement('my-component', {
      props: {
        title: 'My Title',
        message: this.message
      }
    })
  }
})

在这个例子中,我们创建了一个 my-component 组件,它接收 titlemessage 两个属性,并使用这些属性渲染模板。然后我们创建了一个 Vue 实例,并使用 render 函数创建了虚拟 DOM 并将其渲染到指定的 DOM 节点上。

render 函数中,我们使用 createElement 函数创建了一个 my-component 组件的虚拟节点,并将其渲染到页面上。我们通过 props 属性传递了 titlemessage 属性,其中 message 属性是从 Vue 实例的 data 属性中获取的。

七、vue diff算法

Vue.js 中的 diff 算法又称为虚拟 DOM 算法,它主要是用来实现在 UI 更新时,尽量减少 DOM 操作的次数,提高页面渲染效率的一种技术。

Vue.js 的 diff 算法的具体实现过程如下:

  1. 首先得到新旧节点树,比较它们的根节点是否相同。
  2. 如果根节点相同,则递归比较它们的子节点,找出需要更新的节点。
  3. 如果根节点不同,就将旧节点树替换为新节点树,整棵树都需要重新渲染。
  4. 在比较过程中,还需要处理一些特殊情况,例如节点位置变化、节点的 key 值等。

以上就是 Vue.js 中 diff 算法的基本流程。为了提高 diff 算法的效率,Vue.js 还引入了一些优化技巧,例如只在同一父节点下比较子节点、给节点添加 key 值等。

八、vue组件通信

Vue组件通信指的是在一个Vue应用中,不同组件之间进行数据交换或传递消息的技术。Vue提供了多种组件通信方式,常用的包括:

  1. 父子组件通信:父组件通过props向子组件传递数据,子组件通过$emit触发事件向父组件传递消息。

  2. 兄弟组件通信:如果两个兄弟组件之间没有父子关系,则可以使用事件总线(Event Bus)或Vuex进行通信。事件总线是一个空的Vue实例,可以通过它实现任意组件之间的事件传递;Vuex是一个Vue状态管理库,用于管理全局状态,可以实现多个组件之间的共享数据。

  3. 跨级组件通信:如果两个组件之间存在多级父子关系,则可以使用provide/inject或$parent/$children进行跨级通信。provide/inject是一个高级特性,用于在父组件中提供数据,然后在子组件中注入使用;$parent/$children是Vue实例中内置的属性,可以访问父/子组件实例。

九、vuex

Vuex是一个状态管理模式,专门用于Vue.js应用程序的状态管理。它通过集中式存储管理应用程序的各种状态,并提供规则确保状态只能按照预期方式进行修改,来帮助简化应用程序的状态管理。

Vuex将应用程序的状态存储在一个单一的对象中,称为store。整个应用程序中的所有组件都可以访问该存储,并通过发送Action(操作)来修改其状态。Action是指对状态进行更改的请求,可以是同步或异步的,并提供一个可选的回调以响应状态更改。

当Action提交给Store时,Store会调用将状态更改

十、watch深度监听

深度监听通常是通过构建一个事件循环机制来实现的。该机制通过监听事件队列中的所有事件来实现对特定数据或对象的深度监听。

具体实现方式可以是:

  1. 对目标对象进行代理,在代理对象中添加监听器,对目标对象的属性或方法进行拦截,当目标对象发生变化时,通过回调函数通知监听器。

  2. 利用 ES6 特性中的 Proxy 对象。通过定义一个代理对象,使用 Proxy 对象处理所有对目标对象的读写操作,并在读写操作中添加监听器。

无论哪种实现方式,关键在于对目标对象的监听器的定义和绑定,以及对目标对象所存在的数据(包括属性和方法)的监听。这样,当目标对象发生变化时,监听器便能够通过回调函数捕捉到变化信息,并做出相应的响应。

十一、vue中Computed、Methods、Watch区别

在Vue中,Computed、Methods、Watch是三个不同的属性,用于处理不同的逻辑。

  1. Computed Computed是计算属性,它会根据依赖的数据动态计算出一个新的值,该值会被缓存,只有当依赖的数据发生改变时才会重新计算。所以,如果一个值是依赖于其他值的,我们可以使用Computed属性来处理。

例如:

<template>
  <div>
    <p>{{ fullName }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    firstName() {
      return this.user.firstName;
    },
    lastName() {
      return this.user.lastName;
    },
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    },
  },
};
</script>

  1. Methods Methods是方法,它是一个函数,可以在模板中调用。如果要执行一些操作,可以使用Methods属性来处理。

例如:

<template>
  <div>
    <button @click="sayHello">Say Hello</button>
  </div>
</template>

<script>
export default {
  methods: {
    sayHello() {
      alert('Hello!');
    },
  },
};
</script>

  1. Watch Watch是观察者,它可以监听某一个数据的变化,当数据发生变化时,就会执行对应的函数。所以,如果需要在某个值发生变化时执行一些操作,我们可以使用Watch属性来处理。

例如:

<template>
  <div>
    <input v-model="message" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '',
    };
  },
  watch: {
    message(newVal, oldVal) {
      console.log(`New value: ${newVal}, Old value: ${oldVal}`);
    },
  },
};
</script>

总结:

  • Computed属性主要用于计算属性值,有缓存机制,适合处理依赖数据的场景;
  • Methods属性主要用于定义一个函数,适合处理模板交互的场景;
  • Watch属性主要用于监听数据变化,适合处理异步操作、复杂逻辑的场景。

十二、mvvm和mvc

MVVM (Model-View-ViewModel) 和 MVC (Model-View-Controller) 都是常见的软件架构设计模式,它们之间的主要区别在于以下几点:

  1. 数据绑定方式不同:MVVM使用双向绑定,而MVC则是单向绑定。

  2. 视图模型与控制器的角色不同:MVVM中的视图模型(ViewModel)负责为视图(View)提供数据和处理逻辑,而控制器(Controller)则是MVC中的负责处理用户输入和响应输出的中介。

  3. 数据的处理方式不同:在MVVM中,视图模型(ViewModel)可以处理数据的业务逻辑,而在MVC中,业务逻辑通常位于控制器(Controller)中。

  4. 可测试性不同:由于MVVM中的视图模型(ViewModel)和视图(View)分离,因此可以更容易地进行单元测试,而MVC中的控制器(Controller)则需要更多的集成测试来测试。

  5. 代码复杂度不同:MVVM模式下的代码更为简洁,MVC模式下的代码相对较为复杂。

总之,MVVM和MVC都是优秀的软件架构模式,需要根据具体的业务场景来选择合适的模式。

十三、vue中的事件修饰符

Vue中的事件修饰符是为了方便开发者处理事件而设定的一些标识符,可以用来对事件进行特殊的处理。

可以在事件处理函数后面使用管道符(|)来使用修饰符,如下所示:

<button @click.prevent="submit">Submit</button>

Vue提供的事件修饰符有以下几种:

  • .stop:阻止事件向上冒泡。
  • .prevent:阻止事件的默认行为。
  • .capture:使用事件捕获模式。
  • .self:只有点击事件的目标元素自身时才触发事件。
  • .once:只触发一次事件。
  • .passive:告诉浏览器该事件的默认行为可以安全地被禁用。

除了上述事件修饰符,还可以通过键盘修饰符来处理键盘事件,如下所示:

<input @keyup.enter="submit">

Vue提供的键盘修饰符有以下几种:

  • .enter:按下回车键。
  • .tab:按下tab键。
  • .delete / .del:按下delete键。
  • .esc:按下esc键。
  • .space:按下空格键。
  • .up:按下上箭头键。
  • .down:按下下箭头键。
  • .left:按下左箭头键。
  • .right:按下右箭头键。

使用事件修饰符可以有效地提高开发效率,使代码更加简洁易懂。

十四、vue自定义组件

Vue.js是一个非常流行的JavaScript框架,它提供了大量的工具和功能,使得开发者能够轻松构建复杂的Web应用程序。

Vue.js提供了很多内置的组件,如v-model、v-if、v-for等,但有时候这些组件可能不能满足开发者的需求,这时我们就需要自定义组件。

自定义组件可以根据开发者的需求来创建,它可以是一个可复用的组件,也可以是一个解决特定问题的组件。

以下是创建Vue自定义组件的步骤:

  1. 创建Vue组件构造函数
Vue.component('my-component', {
  // 组件选项
})

  1. 定义组件模板

组件模板可以是HTML模板字符串、通过template选项定义的DOM元素、或通过render函数返回的虚拟DOM。

Vue.component('my-component', {
  template: '<div>My custom component</div>'
})

  1. 在Vue实例中使用组件

在Vue实例中使用自定义组件需要使用组件标签来调用它。

<div id="app">
  <my-component></my-component>
</div>

new Vue({
  el: '#app'
})

以上是创建Vue自定义组件的基本步骤,开发者可以根据需要进一步对组件进行配置和优化。

十五、vue自定义指令、自定义指令使用场景、vue自定义过滤器filter

Vue自定义指令是一种灵活的方式,可以在HTML元素上绑定自定义行为,从而使其获得更多的交互和可重用性。Vue中有两种指令:全局指令和局部指令。全局指令可以在整个应用程序中使用,而局部指令只能在其声明的组件中使用。

Vue自定义指令使用场景

  1. 操作DOM:自定义指令可以直接操作DOM,改变其样式、属性等。例如,可以创建一个自定义指令,使得当鼠标悬停在图像上时,此图像会放大。

  2. 表单处理:自定义指令可以使表单处理更加方便,例如,可以使用自定义指令验证表单中的数据。例如,可以创建一个自定义指令,检查用户输入的电子邮件地址是否符合规范。

  3. 与第三方库配合:自定义指令可以与第三方库配合使用,例如,可以创建一个自定义指令,将 echarts 图表处理绑定到一个元素上。

Vue自定义过滤器filter

Vue过滤器是一种格式化输出数据的技术,可以使数据更易读,更加有效。Vue提供了一组内置的过滤器,例如,用来格式化日期、格式化数字、大写、小写等等。同时,也可以自定义过滤器,满足自己的需求。

Vue自定义过滤器的使用场景

  1. 数据格式化:自定义过滤器可以格式化数据,使其在页面上更具可读性。例如,可以创建一个自定义过滤器,将时间戳格式化为日期时间格式。

  2. 数据处理:自定义过滤器可以对数据进行进一步处理。例如,可以创建一个自定义过滤器,将一个字符串反转。

  3. 条件过滤:自定义过滤器可以在特定条件下过滤数据。例如,可以创建一个自定义过滤器,将数组中的奇数或偶数过滤出来。

十六、vue-router、vue-router原理、vue脚手架本地开发跨域请求设置

  1. Vue Router:Vue Router是Vue.js官方的路由管理器,它可以与Vue.js无缝集成,提供了一种构建单页应用的方式。Vue Router能够通过URL路径来实现组件的切换与页面的跳转,让用户体验更加流畅。

  2. Vue Router原理:Vue Router的原理是通过监听URL变化来切换组件,它使用了HTML5的History API来实现URL的变化,而不是通过刷新整个页面来实现。Vue Router将不同的URL映射到不同的组件,并通过路由守卫来控制页面的访问权限。

  3. Vue脚手架本地开发跨域请求设置:在Vue脚手架的配置文件中,可以通过设置devServer.proxy来进行本地开发跨域请求的设置。具体方法如下:

  • 打开/config/index.js文件
  • 找到dev对象中的proxyTable属性
  • 在proxyTable属性中添加需要跨域请求的接口的代理配置,例如:
proxyTable: {
  '/api': {
    target: 'http://localhost:3000', // 接口的域名
    changeOrigin: true, // 是否跨域
    pathRewrite: {
      '^/api': '' // 重写接口
    }
  }
}

这样,在本地通过访问“/api”接口时,会自动将请求转发到指定的地址。

十七、keep-alive

在 Vue.js 2 中,keep-alive 是一个内置组件,用于缓存组件实例或动态组件。当组件在 keep-alive 中被切换时,它们的状态将被保留,不会重新渲染。

使用 keep-alive 组件,可以提高应用程序的性能,尤其是当组件切换频繁、初始化时间较长时,例如在 Tab 切换或路由切换场景中。

使用 keep-alive 的步骤如下:

  1. 在父组件中使用 keep-alive 包裹需要缓存的组件。

  2. 在需要缓存的组件中,添加 name 属性,确保它们有唯一的标识。

下面是一个示例:

<!-- 父组件 -->
<template>
  <div>
    <button @click="toggle">Toggle</button>
    <keep-alive>
      <component :is="currentComponent"></component>
    </keep-alive>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'

export default {
  components: {
    ComponentA,
    ComponentB
  },
  data() {
    return {
      currentComponent: 'ComponentA'
    }
  },
  methods: {
    toggle() {
      this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA'
    }
  }
}
</script>

<!-- ComponentA.vue -->
<template>
  <div>
    <h2>Component A</h2>
  </div>
</template>

<script>
export default {
  name: 'ComponentA'
}
</script>

<!-- ComponentB.vue -->
<template>
  <div>
    <h2>Component B</h2>
  </div>
</template>

<script>
export default {
  name: 'ComponentB'
}
</script>

在上述示例中,当点击 Toggle 按钮时,会切换 ComponentA 和 ComponentB。由于这两个组件被包裹在 keep-alive 中,它们的状态会被保留,不会重新渲染。同时,由于 name 属性的存在,Vue.js 可以根据组件的标识对它们进行缓存和复用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值