前端面试题(vue篇)

前端面试题(vue篇持续更新ing)

1.v-if和v-show的区别?

v-ifv-show 是 Vue.js 中用于条件渲染的指令,它们的作用是根据表达式的值来控制元素的显示与隐藏。它们的区别在于:

  1. v-if

    • 指令用法v-if 是一个指令,它通过计算绑定的表达式的值来决定是否渲染元素。
    • 渲染方式:如果表达式的值为 true,则渲染对应的元素;如果为 false,则不渲染(从 DOM 中移除)。
    • 性能特点:当 v-if 的条件为 false 时,元素及其内部的 Vue 组件会被销毁并重建,每次切换时都会触发销毁和重新渲染的过程。

    示例:

    <div v-if="isVisible">这是通过v-if条件渲染的元素</div>
    
  2. v-show

    • 指令用法v-show 是一个指令,它同样通过计算绑定的表达式的值来决定元素的显示与隐藏。
    • 渲染方式:如果表达式的值为 true,则显示元素(通过 CSS 的 display 属性控制);如果为 false,则隐藏元素(通过 display: none)。
    • 性能特点:当 v-show 的条件为 false 时,元素并未从 DOM 中移除,而是通过 CSS 控制隐藏,不会触发销毁和重新渲染的过程。

    示例:

    <div v-show="isVisible">这是通过v-show条件渲染的元素</div>
    

选择使用

  • 如果需要频繁切换元素的显示与隐藏,并且对性能要求较高,可以使用 v-show,因为它不会频繁触发 DOM 的销毁和重建。
  • 如果元素的显示与隐藏不频繁,或者希望在条件为 false 时完全从 DOM 中移除元素以节省资源,可以考虑使用 v-if

2.如何理解MVVM的?

MVVM(Model-View-ViewModel)是一种软件架构模式,旨在分离用户界面(UI)的开发与业务逻辑的开发,以提高代码的可维护性、可测试性和复用性。MVVM 架构包含三个主要部分:

  1. Model(模型)
    • 模型代表应用程序的数据和业务逻辑。模型通常是指应用程序的数据结构、数据库连接、业务规则等。在前端开发中,模型可以是应用程序的数据模型,用于管理数据的获取、存储和处理。
  2. View(视图)
    • 视图是用户界面的可视化部分,负责展示数据给用户,并接收用户的输入操作。视图通常是由 HTML、CSS 和 UI 组件组成。在 MVVM 中,视图通过数据绑定与 ViewModel 进行交互,根据 ViewModel 中的数据和状态来动态更新视图。
  3. ViewModel(视图模型)
    • 视图模型是连接视图和模型之间的中间层。它负责从模型中获取数据,并对视图中显示的数据进行处理和准备。视图模型通常包含了视图所需的数据、命令(用于处理用户交互)和其他业务逻辑。在前端开发中,ViewModel 通常由 JavaScript 或其他前端框架中的组件来实现。

MVVM 的工作原理如下:

  • 数据绑定:视图通过数据绑定与 ViewModel 中的数据进行绑定。当 ViewModel 中的数据发生变化时,视图会自动更新,反之亦然。
  • 命令绑定:视图中的用户交互操作(比如按钮点击、输入框输入等)通过命令绑定绑定到 ViewModel 中的命令。ViewModel 接收并处理这些命令,执行相应的业务逻辑或数据操作。
  • 解耦:MVVM 的核心思想是将视图与业务逻辑解耦,使得视图的开发和维护更加简单。通过视图模型将视图与模型分离,可以使开发团队更好地进行并行开发,提高开发效率和代码质量。

3.v-for中的key值的作用是什么?

  1. 唯一标识子元素key 属性提供了一种唯一标识列表中每个子元素的方式。Vue 使用这些 key 来识别每个子元素,并在更新 DOM 时使用它们来确定哪些元素是新增的、删除的或重新排序的。
  2. 优化列表渲染: 使用 key 属性能够帮助 Vue 优化列表的渲染性能。当列表中的数据发生变化时,Vue 可以根据 key 属性识别出哪些元素是已知的,从而避免不必要的 DOM 操作,提高渲染效率。
  3. 配合 v-for 使用: 在使用 v-for 指令渲染列表时,为每个列表项添加 key 属性是推荐的做法。这样可以确保 Vue 能够正确地跟踪和管理列表中的每个子元素,确保 DOM 的正确更新和重用。

例如,在您的 Vue 模板中的 v-for 循环中,您可以将每个列表项的 id 作为 key 属性,以确保每个列表项都有一个唯一的标识:

<ul>
  <li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>

在这里,假设 item.id 是列表项的唯一标识符,将其用作 key 属性能够帮助 Vue 在列表项发生变化时更有效地管理和更新 DOM。

4.说一下你对vue生命周期的理解。

Vue.js 的生命周期钩子函数是一组可以让我们在 Vue 实例中的特定阶段添加自定义逻辑的方法。这些钩子函数可以帮助我们在组件的不同生命周期阶段执行任务,从而实现对应用状态的管理和控制。

Vue.js 的生命周期包括以下阶段:

  1. beforeCreate: 在 Vue 实例被创建之初,实例的数据观测和事件系统都尚未初始化。此时无法访问 datamethodscomputed 等属性和方法。
  2. created: 在实例被创建后,完成数据观测、属性和方法的运算,但尚未挂载到 DOM 上。此时可以访问实例的数据,也可以进行 Ajax 请求等操作。
  3. beforeMount: 在 Vue 实例挂载到 DOM 之前调用。此时 Vue 实例的模板编译完成,但尚未将其渲染到页面上。
  4. mounted: 在 Vue 实例挂载到 DOM 后调用。此时 Vue 实例已经被挂载,并且可以访问到 DOM 元素。通常在这个阶段进行 DOM 相关的操作和初始化工作。
  5. beforeUpdate: 数据更新导致重新渲染之前调用。在这个阶段,虚拟 DOM 已经更新,但尚未应用到页面上的 DOM 中。
  6. updated: 数据更新导致重新渲染之后调用。在这个阶段,Vue 实例已经更新,DOM 也已经重新渲染。通常在这里可以进行一些依赖于 DOM 的操作。
  7. beforeDestroy: 在 Vue 实例销毁之前调用。在这个阶段,Vue 实例仍然完全可用,可以执行一些清理工作,如清除定时器、解绑事件等。
  8. destroyed: Vue 实例销毁后调用。在这个阶段,Vue 实例的所有事件监听器和子实例都已经被销毁,不再可用。

除了这些主要的生命周期钩子函数外,Vue 还提供了一些其它的钩子函数,用于处理特定场景下的逻辑,例如 activateddeactivated 用于 keep-alive 组件,errorCaptured 用于捕获子孙组件的错误等。

5.在created和mounted去请求数据,有什么区别?

在 Vue.js 中,createdmounted 都是生命周期钩子函数,用于在 Vue 实例的不同阶段执行任务。虽然它们看起来有些类似,但在请求数据时有一些重要的区别:

  1. created 钩子

    • created 钩子函数在 Vue 实例被创建之后立即执行,此时 Vue 实例的数据观测 (data observer) 已经完成,但是挂载阶段还未开始,因此实例还没有被挂载到 DOM 上。
    • created 钩子中进行数据请求时,一般适合初始化实例数据、设置计算属性或监听事件,因为此时实例已经创建,但 DOM 和模板还未渲染完成,无法操作页面上的元素。
    created() {
      axios.get('https://api.example.com/data')
        .then(response => {
          this.data = response.data;
        })
        .catch(error => {
          console.error('Error fetching data:', error);
        });
    }
    
  2. mounted 钩子

    • mounted 钩子函数在 Vue 实例被挂载到 DOM 后执行,此时 Vue 实例已经完成了挂载,可以访问到 DOM 元素。
    • mounted 钩子中进行数据请求时,适合执行需要操作 DOM 元素的任务,例如初始化第三方库、调用 DOM API、绑定事件等。
    mounted() {
      axios.get('https://api.example.com/data')
        .then(response => {
          this.data = response.data;
        })
        .catch(error => {
          console.error('Error fetching data:', error);
        });
    }
    

区别总结

  • 如果数据请求不需要依赖 DOM 元素,可以在 created 钩子中发起请求,这样可以更早地获取数据并初始化组件状态。
  • 如果数据请求需要依赖 DOM 元素,或者需要操作 DOM 元素后再进行请求,应该在 mounted 钩子中执行,以确保能够访问到已挂载的 DOM 元素。
  • 在大多数情况下,推荐将数据请求放在 mounted 钩子中,因为这样可以避免一些由于数据获取过早而导致的问题,例如初始化数据可能在实例完全创建前就被访问。

6.vue中的修饰符有哪些?

在 Vue.js 中,修饰符是用于对指令或事件进行额外控制或修改行为的特殊标记。以下是常见的 Vue.js 指令和事件修饰符:

指令修饰符

  1. .prevent

    • 阻止默认事件行为,等同于调用 event.preventDefault()
    <form @submit.prevent="handleSubmit"></form>
    
  2. .stop

    • 阻止事件继续传播,等同于调用 event.stopPropagation()
    <div @click.stop="handleClick"></div>
    
  3. .capture

    • 添加事件监听器时使用事件捕获模式
    <div @click.capture="handleClick"></div>
    
  4. .self

    • 只在事件是从事件目标自身触发时才触发回调
    <div @click.self="handleClick"></div>
    
  5. .once

    • 只触发一次事件,等同于使用 vm.$once 方法
    <button @click.once="handleClick">Click Me</button>
    
  6. .passive

    • 指示浏览器不要等待 preventDefault 完成,可以加快页面滚动的性能
    <div @touchstart.passive="handleTouchStart"></div>
    

事件修饰符

  1. .stop

    • 阻止事件继续传播,等同于在事件处理函数中调用 event.stopPropagation()
    <button @click.stop="handleClick"></button>
    
  2. .prevent

    • 阻止默认事件行为,等同于在事件处理函数中调用 event.preventDefault()
    <form @submit.prevent="handleSubmit"></form>
    
  3. .capture

    • 添加事件监听器时使用事件捕获模式
    <div @click.capture="handleClick"></div>
    
  4. .self

    • 只在事件是从事件目标自身触发时才触发回调
    <div @click.self="handleClick"></div>
    
  5. .once

    • 只触发一次事件,等同于使用 vm.$once 方法
    <button @click.once="handleClick"></button>
    
  6. .passive

    • 指示浏览器不要等待 preventDefault 完成,可以加快页面滚动的性能
    <div @touchstart.passive="handleTouchStart"></div>
    

7.elementui是怎么做表单验证的?

Element UI 是一个基于 Vue.js 的组件库,提供了丰富的 UI 组件和功能,包括表单验证。Element UI 中的表单验证是通过使用 el-formel-form-item 组件结合内置的验证规则和方法来实现的。

下面是 Element UI 表单验证的基本步骤和示例:

  1. 使用 el-form 组件包裹表单内容

    <template>
      <el-form :model="formData" :rules="formRules" ref="form" label-width="100px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="formData.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="formData.password"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm">提交</el-button>
        </el-form-item>
      </el-form>
    </template>
    
    <script>
    export default {
      data() {
        return {
          formData: {
            username: '',
            password: ''
          },
          formRules: {
            username: [
              { required: true, message: '请输入用户名', trigger: 'blur' }
            ],
            password: [
              { required: true, message: '请输入密码', trigger: 'blur' }
            ]
          }
        };
      },
      methods: {
        submitForm() {
          this.$refs.form.validate(valid => {
            if (valid) {
              // 表单验证通过,执行提交操作
              // 可以在这里调用接口等操作
              console.log('表单验证通过');
            } else {
              // 表单验证不通过
              console.log('表单验证未通过');
              return false;
            }
          });
        }
      }
    };
    </script>
    
  2. el-form 中设置 :model:rules

    • :model 绑定表单数据对象,用于收集表单数据。
    • :rules 绑定表单验证规则,定义每个字段的验证规则。
  3. 使用 el-form-item 包裹表单项

    • 每个表单项都需要用 el-form-item 组件包裹,设置 label 属性为表单项的标签名,设置 prop 属性为表单项数据对象中的字段名。
  4. 定义表单验证规则

    • data 中定义 formRules 对象,为每个表单字段设置验证规则数组。
  5. 提交表单

    • 在提交按钮的点击事件中,通过调用 this.$refs.form.validate(callback) 方法进行表单验证。
    • callback 回调函数接收一个 valid 参数,表示表单验证结果是否通过。

通过以上步骤,可以实现基于 Element UI 的表单验证功能。验证规则中的 trigger 属性指定了触发验证的时机,常见的值有 'blur'(失去焦点时触发)和 'change'(数据变化时触发)。 Element UI 提供了丰富的验证规则和验证方法,可以满足常见的表单验证需求。

8.vue如何进行组件通信?

Vue.js 中有多种方法用于组件之间的通信,其中包括 props、事件、vuex 状态管理以及 provide/inject 等。这些方法可以根据不同的场景和需求来选择和组合使用。

  1. Props/Events

    • 父组件通过 props 向子组件传递数据,子组件通过事件 $emit 向父组件发送消息。

    • 父组件向子组件传递数据:

      <!-- ParentComponent.vue -->
      <template>
       <!-- 使用 ChildComponent 组件,并通过 :message 属性传递 parentMessage 数据 -->
       <ChildComponent :message="parentMessage" @notify="handleNotify" />
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
       components: {
          ChildComponent
       },
       data() {
          return {
            // 定义一个数据属性 parentMessage,用于传递给子组件
            parentMessage: 'Hello from parent'
          };
       },
       methods: {
          // 定义一个方法 handleNotify,用于处理子组件发出的 notify 事件
          handleNotify(message) {
            console.log('Received message from child:', message);
          }
       }
      };
       //输出结果:Received message from child: Hello from child
      </script>
      
      
    • 子组件接收 props 并发送事件:

      <template>
       <!-- 一个按钮,点击时触发 notifyParent 方法 -->
       <button @click="notifyParent">Send Message to Parent</button>
      </template>
      
      <script>
      export default {
       props: ['message'],
       methods: {
          // 定义一个方法 notifyParent,用于向父组件发送消息
          notifyParent() {
            // 使用 $emit 方法发出一个名为 notify 的事件,并传递消息 'Hello from child'
            this.$emit('notify', 'Hello from child');
          }
       }
      };
      </script>
      
  2. Event Bus

    • 使用 Vue 实例作为事件总线,用于任意组件之间的通信。

      // main.js
      import Vue from 'vue';
      export const bus = new Vue();
      

      在组件中使用:

      // ComponentA.vue
      import { bus } from './main.js';
      
      bus.$emit('event-name', data);
      
      // ComponentB.vue
      import { bus } from './main.js';
      
      bus.$on('event-name', (data) => {
        console.log('Received data:', data);
      });
      
  3. Vuex

    • 用于管理应用程序的状态,可以在任何组件中访问共享状态。
  4. Provide/Inject

    • 父组件使用 provide 来提供数据,子组件使用 inject 来注入数据。

      <!-- ParentComponent.vue -->
      <template>
        <child-component />
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent
        },
        provide() {
          return {
            sharedData: 'Data from parent'
          };
        }
      };
      </script>
      
      <!-- ChildComponent.vue -->
      <template>
        <div>{{ sharedData }}</div>
      </template>
      
      <script>
      export default {
        inject: ['sharedData']
      };
          //显示的结果为Data from parent
      </script>
      

9.keep-alive是什么?怎么使用?

keep-alive 是 Vue.js 中的一个内置组件,用于将包含的组件保留状态,或避免重新渲染。这意味着当组件被切换出去时,它的状态和 DOM 结构不会被销毁,而是被缓存起来,当再次切换回该组件时,可以直接使用缓存的状态和 DOM,而不需要重新初始化组件。这对于需要保持状态或避免不必要的重新渲染的组件非常有用。比如当我们从首页–>列表页–>商详页–>再返回,这时候列表页应该是需要keep-alive,从首页–>列表页–>商详页–>返回到列表页(需要缓存)–>返回到首页(需要缓存)–>再次进入列表页(不需要缓存),这时候可以按需来控制页面的keep-alive

<template>
 <div id="app">
    <router-view v-if="shouldKeepAlive"></router-view>
    <keep-alive v-else>
      <router-view></router-view>
    </keep-alive>
 </div>
</template>

<script>
export default {
 data() {
    return {
      shouldKeepAlive: false,
    };
 },
 watch: {
    '$route'(to, from) {
      // 当从列表页返回到首页时,需要缓存
      if (from.name === 'ListPage' && to.name === 'HomePage') {
        this.shouldKeepAlive = true;
      }
      // 当从首页返回到列表页时,不需要缓存
      else if (from.name === 'HomePage' && to.name === 'ListPage') {
        this.shouldKeepAlive = false;
      }
      // 当再次进入列表页时,不需要缓存
      else if (from.name === 'ListPage' && to.name === 'ListPage') {
        this.shouldKeepAlive = false;
      }
    },
 },
};
</script>

10.axios是怎么做封装的?

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 node.js。它提供了一种简单的方式来发送异步 HTTP 请求到 REST endpoints 并且处理响应。封装 Axios 主要是为了提高代码的可维护性和重用性,以及为了简化 HTTP 请求的使用。

封装 Axios 的一种常见方法是创建一个单独的服务文件或模块,这个文件或模块包含了一些预设的配置和方法,用于处理常见的 HTTP 请求。这样,当你需要发送 HTTP 请求时,你可以直接调用这些预设的方法,而不是每次都需要手动配置 Axios 实例。

以下是一个简单的 Axios 封装示例:

// api.js
import axios from 'axios';

// 创建 axios 实例
const instance = axios.create({
 baseURL: 'https://api.example.com', // 基础 URL
 timeout: 1000, // 请求超时时间
 headers: {
    'Content-Type': 'application/json',
 },
});

// 请求拦截器
instance.interceptors.request.use((config) => {
 // 在发送请求之前做些什么
 return config;
}, (error) => {
 // 对请求错误做些什么
 return Promise.reject(error);
});

// 响应拦截器
instance.interceptors.response.use((response) => {
 // 对响应数据做点什么
 return response;
}, (error) => {
 // 对响应错误做点什么
 return Promise.reject(error);
});

// 导出实例
export default instance;

在这个示例中,创建了一个 Axios 实例,并设置了基础 URL、超时时间和默认的请求头。还添加了请求和响应拦截器,以便在发送请求或接收响应时进行一些预处理或后处理。最后,导出了这个实例,以便在其他文件中使用。

使用这个封装后,可以在其他文件中这样使用:

import api from './api';

// 使用封装后的 axios 实例发送 GET 请求
api.get('/user')
 .then(response => {
    console.log(response.data);
 })
 .catch(error => {
    console.error(error);
 });
  • 49
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爪洼守门员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值