最新Vue常见基础面试题(看这一篇就够了)(一)

简介: 最新Vue常见基础面试题(看这一篇就够了)

vue 的两个核心🌟🌟

组件系统、数据驱动


什么是双向数据绑定?🌟🌟🌟

v-model,数据发生变化,同步视图,视图发生变化,同步数据


什么是单向数据流?🌟🌟🌟

在父向子传值的时候,如果改变父组件的值,子组件会跟着同步更新,反之不允许


MVVM 的设计思想的优势?🌟🌟🌟

  • 双向绑定技术,当 Model 变化时,View 也会自动变化,view 发生更新,model 也跟着同步
  • 我们减少了 dom 的操作,因为我们只需要关注数据就可以
  • mvvm 的设计思想大大提高了代码的耦合性


事件传参🌟🌟🌟🌟

  • 没有传递参数,事件函数的默认第一个参数是事件对象
  • 如果传递了参数,事件函数就没有了默认参数,全部变为对应位置的实参的形参,就没有了事件对象
  • 既有自己传的的参数,也有事件对象,通过$event 传递事件对象,在事件函数内部通过对应位置的形参来接收事件对象,传递 $event 没有强制性的位置,但是建议放在最后


自定义指令:directive🌟🌟🌟

为什么自定义指令?

vue 提供的系统指令满足不了我们的需求,那么我们就需要自定义指令

通过 Vue.directive 进行自定义指令的定义


  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。


计算属性:computed🌟🌟🌟🌟🌟

定义的时候是一个方法,使用的时候当作属性使用

只要 return 后面的数据发生变化,该计算属性就会重新计算

计算属性具有缓存特性


监听器:watch🌟🌟🌟🌟🌟

可以监听数据发生变化,可以监听的数据有(props、data、computed、$route) watch 侦听器如果监听的是一个对象,需要开启深度监听

watch:{
  num:{
    // 监听数据发生变化的处理函数
    handler(newNum) {
      console.log(newNum)
    },
    // 是否开启深度监听
    deep: true
  }
}

如果想实现首次监听配置 immediate 为 true


过滤器🌟🌟🌟🌟

可以对数据格式进行处理,例如常用的例如格式化时间 使用方式通过 数据名 |(管道符)后面跟过滤器的名字


生命周期函数🌟🌟🌟🌟🌟

生命周期:是指一个对象从创建到运行到销毁的整个过程,被称为生命周期

生命周函数:在不同的生命周期阶段会自动执行对应的函数,而这些函数则被成为生命周期函数

// 创建阶段
      beforeCreate() {
        // 这个生命周函数,代表开始创建实例了
        console.log('beforeCreate',this.num)
      },
      created () {
        // 代表数据和方法已经初始化成功了,此处dom还没有挂载到页面上
        console.log('created',this.num,this.$el)
      },
      beforeMount () {
        // 挂在之前
        console.log('beforeMount',this.$el)
      },
      mounted () {
        // dom已经挂载了
        console.log('mounted',this.$el)
      },
      // 运行更新阶段
      beforeUpdate () {
        // 数据更新,页面还没有同步
        console.log('beforeUpdated',this.num,document.getElementById('app').innerHTML)
      },
      updated () {
        // 数据更新,页面已经同步
        console.log('updated',this.num,document.getElementById('app').innerHTML)
      },
      // 销毁阶段
      beforeDestroy () {
        // 销毁之前
        console.log('beforeDestroy')
      },
      destroyed () {
        // 已经销毁了
        console.log('destroy')
      }


在 vue 中通过索引直接在修改数组中的某一项数据,页面是否更新?🌟🌟🌟

在 vue 中对 对象新添加属性,页面是否更新?

不更新,如果想解决这个问题,vm.$set(vm.list, 1, ‘or’)或者 Vue.set

但是 vm.list[3].a = 456,通过索引修改某一项的对象内部的属性是没问题的


vue 组件中的 data 为什么是一个函数,返回一个对象?🌟🌟

如果不是一个函数返回一个新的对象,组件如果多次使用,实际公用的是同一个数据

但是如果是通过函数 返回一个新的对象,这样的话,每个组件的使用数据是独立的


组件🌟🌟🌟🌟

如何创建一个全局组件🌟🌟🌟

通过 Vue.component 来创建一个全局组件,第一个参数是组件名字,第二个参数是组件的配置对象,可以通过 template 配置组件的结构,data 定义数据等等


如何创建一个局部组件🌟🌟🌟

在组件内部通过 components 来创建一个局部组件

全局组件和局部组件的区别

局部组件:只能在当前的父组件中使用

全局组件: 在任意地方使用


如何定义局部自定义指令🌟🌟🌟

在组件内部通过 directives 来创建一个局部指令

全局指令和局部指令的区别

局部指令:只能在当前的组件中使用

全局指令: 在任意地方使用


如何定义局部过滤器🌟🌟🌟

在组件内部通过 filters 来创建一个局部过滤器

全局过滤器和局部过滤器的区别

局部过滤器:只能在当前的组件中使用

全局过滤器: 在任意地方使用


组件传值🌟🌟🌟🌟🌟


Props

  • 父亲怎么传:通过属性绑定形式传
  • 儿子怎么接收:通过 props 来接收


Emit

  • 子怎么传:通过 this.$emit 触发一个自定义事件,并且发送一个值
  • 父怎么接收:通过定义自定义事件的事件函数的形参来接收


ref

  • 通过添加 ref 和 $refs 配合, 也可以很方便的获取子组件, 访问调用子组件的属性或方法
// 父组件中
<template>
  <div class="hello_world">
    <com-a ref="coma"></com-a> // this.$refs.coma.count = 200
    <com-b ref="comb"></com-b> // this.$refs.comb.addFn()
  </div>
</template>


$children

$parent

v-model

sync

兄弟组件传值🌟🌟🌟🌟

定义一个事件中心,或者是第三方

接收值的组件:通过该事件中心的$on 来定义自定义事件的事件函数来接收值

eventBus.$on('getTab1', data => {
  console.log('接收tab1传递的值', data)
})


另一个兄弟组件怎么传:通过事件中心的$emit 触发对应的 $on 的事件,并且把值传递过去

eventBus.$emit('getTab1', this.num)


跨组件传值🌟🌟🌟🌟

Vue.component('my-sub1', {
  template: '#my-sub1',
  data() {
    return {
      money: 10000000
    }
  },
  provide: {
    money: 1000
  },
  components: {
    'sub-a': {
      template: '<div>子组件<sub-b></sub-b></div>',
      components: {
        'sub-b': {
          template: '<div>子组件{{money}}</div>',
          inject: ['money']
        }
      }
    }
  }
})
new Vue({
  el: '#app'
})


vuex

provide inject

  • 成对出现:provide 和 inject 是成对出现的
  • 作用:用于父组件向子孙组件传递数据


使用方法:

  • provide 在父组件中, 返回要传给下级的数据
  • inject 在需要使用这个数据的子孙组件中注入数据。(不论组件层次有多深)


组件插槽🌟🌟🌟🌟

  • 默认插槽:
  • 在组件标签中间可以传递一些子节点
  • 组件内部利用 slot 标签进行接收


具名插槽

  • 在组件标签中间通过定义 slot 的名字传递子节点
<my-banner>
  <div slot="header">
    头部
  </div>
  <div slot="footer">
    底部
  </div>
</my-banner>


组件内部利用 slot 的 name 进行对应接收

<template id="banner">
  <div>
    <slot name="header"></slot>
    <slot name="footer"></slot>
  </div>
</template>


作用域插槽

  • 在组件内部定义数据,将数据传递给插槽的结构
  • 通过给 slot 动态绑定属性
<template id="my-li">
    <ul>
      <li v-for="item in arr">
        <slot :row="item"></slot>
      </li>
    </ul>
  </template>


插槽内部:通过 slot-scope=“scope”来接收

<my-li>
  <template slot-scope="scope">
    <p>{{scope.row}}</p>
  </template>
</my-li>
<my-li>
  <template slot-scope="scope">
    <a href="04-侦听器.html">{{scope.row}}</a>
  </template>
</my-li>


插槽内部:通过 slot-scope=“scope”来接收

<my-li>
  <template slot-scope="scope">
    <p>{{scope.row}}</p>
  </template>
</my-li>
<my-li>
  <template slot-scope="scope">
    <a href="04-侦听器.html">{{scope.row}}</a>
  </template>
</my-li>


Promise 的使用🌟🌟🌟🌟🌟

利用 Promise 处理异步解决回调地狱的问题

Promise 的 all 的方法

Promise 的 race 的方法

面试题:

现在有三个接口地址,需要三个接口地址请求完事之后进行下一步的逻辑处理(不一定按顺序请求完成)

// .then回调
axios.get('http://xxx').then(res => {
  console.log(res)
  axios.get('http://xxx').then(res => {
    console.log(res)
    axios.get('http://xxx').then(res => {
      console.log(res)
    })
  })
})
// .then返回新的Promise继续调用.then
axios
  .get('http://xxx')
  .then(res => {
    return axios.get('http://xxx')
  })
  .then(res => {
    return axios.get('http://xxx')
  })
  .then(res => {
    console.log('三个请求完事')
  })
// async await
const asyncHandle = async function() {
  const res1 = await axios.get('http://xxx1')
  const res2 = await axios.get('http://xxx')
  const res3 = await axios.get('http://xxx')
  console.log(res1, res2, res3)
}
asyncHandle()
// Promise all方法
const getComments = new Promise(() => {
  axios.get('http://xxx')
})
Promise.all([
  axios.get('http://xxx'),
  axios.get('http://xxx'),
  axios.get('http://xxx')
]).then(res => {
  console.log(res)
})


axios 拦截器🌟🌟🌟🌟

请求拦截

axios.interceptors.request.use

响应拦截

axios.interceptors.response.use


路由🌟🌟🌟🌟

什么是路由?

路由就是对应关系,组件和 url 地址,根据不同的地址显示不同的组件,路由也是实现 spa(单页面应用程序)的主要核心,因为单页面应用程序,就是只有一个 html,在这个 html 里面切换组件,根据 url,例如地址为/home,在这个页面中就显示 home 组件

前端路由:url 和组件

后端路由:根据不同的地址请求不同的接口

路由(opens new window)


在 vue 中路由传参

  • params 传参
  • 在跳转的时候可以通过/home/10
  • 路由规则:
new VueRouter({
  routes: [
    {
      path: '/home/:id',
      component: Home
    }
  ]
})


组件内部怎么来接收参数

this.$route.params.id


query 传参

  • 在跳转的时候可以通过/home?id=10
  • 组件内部怎么来接收参数
this.$route.query.id

路由 history 模式注意的问题


嵌套路由🌟🌟🌟


编程式导航🌟🌟🌟


路由钩子🌟🌟🌟🌟

全局钩子:都会对所有的路由进行拦截

beforeEach:进入之前

afterEach:已经进入了

路由独享钩子:可以针对某一个路由进行拦截,这个需要写在路由规则里

 {
    path: '/',
    name: 'home',
    beforeEnter: (to,from,next)=>{
      console.log('即将进入home')
    },
    component: Home
  }


组件内的守卫:

针对组件进行拦截

beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
    next()
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
    console.log('即将离开about')
    if(confirm('当前表单没有提交?确定要离开首页?')){
      next()
    }
  }


webpack 中 babel.loader.plugin 有什么区别?🌟🌟🌟

babel: 将高级语法转换成浏览器可以识别的语法

loader: 加载器, 结合 webpack 来处理非 js 资源文件 .css .less .sass .png

plugin: webpack 的各种各样的插件,能够增强 webpack 的功能


vue 脚手架的安装和使用🌟🌟

命令行方式

配置文档(opens new window)

利用 vue.config.js 关闭 esLint


ui 界面方式

文档(opens new window)


安装 element-ui

  • 安装 vue-cli-plugin-element 插件


使用 element 中 select 组件

  • 注册组件
import Vue from 'vue'
import { Button, Select } from 'element-ui'
Vue.use(Button)
Vue.use(Select)


使用组件

<el-select v-model="value" placeholder="请选择">
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value"
  ></el-option>
</el-select>


复制数据

 options: [{
          value: '选项1',
          label: '黄金糕'
        }, {
          value: '选项2',
          label: '双皮奶'
        }, {
          value: '选项3',
          label: '蚵仔煎'
        }, {
          value: '选项4',
          label: '龙须面'
        }, {
          value: '选项5',
          label: '北京烤鸭'
        }],
        value: ''



目录
相关文章
|
1月前
|
JavaScript 前端开发 API
vue面试题目汇总
vue面试题目汇总
37 4
|
1月前
|
缓存 JavaScript 前端开发
Vue常见面试题 标准答案汇总一
Vue常见面试题 标准答案汇总一
46 1
|
2月前
|
监控 JavaScript 前端开发
vue基础面试题10问
vue基础面试题10问
39 0
|
3月前
|
人工智能 缓存 JavaScript
【利用AI刷面试题】AI:十道Vue面试题巩固一下知识
【利用AI刷面试题】AI:十道Vue面试题巩固一下知识
|
3月前
|
存储 JavaScript 安全
Vue基础面试题题目一
Vue基础面试题题目一
27 0
|
3月前
|
JavaScript 数据安全/隐私保护 开发者
常见的vue面试中的proxy和object.defineProperty的区别
常见的vue面试中的proxy和object.defineProperty的区别
|
3月前
|
存储 JavaScript
面试题:扩展运算符(...)的优缺点(vue)
面试题:扩展运算符(...)的优缺点(vue)
36 0
|
3月前
|
缓存 JavaScript 前端开发
vue核心面试题汇总【查缺补漏】(二)
vue核心面试题汇总【查缺补漏】(二)
|
3月前
|
缓存 移动开发 JavaScript
vue核心面试题汇总【查缺补漏】(一)
vue核心面试题汇总【查缺补漏】(一)
108 0
|
1天前
|
JavaScript 前端开发
【vue】iview如何把input输入框和点击输入框之后的边框去掉
【vue】iview如何把input输入框和点击输入框之后的边框去掉
7 0