• Vue的面试题库


    一. Vue核心小知识点

    1、vue中 key 值的作用

    key的特殊性主要用在Vue的虚拟DOM算法,再新旧nodes对比时辨别VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。

    有相同父元素的子元素必须有独特的key。重复的key会造成渲染错误。

    最常见的用例是结合 v-for:

     
    1 <ul>  
    2      <li v-for="item in items" :key="item.id">...
    3      </li>
    4  </ul>

    它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用:

    完整地触发组件的生命周期钩子 触发过渡

    1  <transition> 
    2      <span :key="text">{{ text }}</span>
    3  </transition>

    当 text 发生改变时,<span> 会随时被更新,因此会触发过渡。

    2.vue中子组件调用父组件的方法

    子组件调用父组件的方法可以使用this.$emit()

    第一种方法是在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

    $emit
    父组件

     1 <template>
     2   <div>
     3     <child @fatherMethod="fatherMethodOther"></child>
     4   </div>
     5 </template>
     6 <script>
     7   import child from './child';
     8   export default {
     9     components: {
    10       child
    11     },
    12     methods: {
    13       fatherMethodOther(str) {
    14         console.log(str);
    15       }
    16     }
    17   };
    18 </script>

    子组件

     1 <template>
     2   <div>
     3     <button @click="childMethod">点击</button>
     4   </div>
     5 </template>
     6 <script>
     7   export default {
     8     methods: {
     9       childMethod() {
    10         this.$emit('fatherMethod', 'hello');
    11       }
    12     }
    13   };
    14 </script>

    第二种方法是直接在子组件中通过this.$parent.event来调用父组件的方法

    $parent
    父组件

     1 <template>
     2   <div>
     3     <child></child>
     4   </div>
     5 </template>
     6 <script>
     7   import child from './child';
     8   export default {
     9     components: {
    10       child
    11     },
    12     methods: {
    13       fatherMethod(str) {
    14         console.log(str);
    15       }
    16     }
    17   };
    18 </script>

    子组件

     1 <template>
     2   <div>
     3     <button @click="childMethod">点击</button>
     4   </div>
     5 </template>
     6 <script>
     7   export default {
     8     methods: {
     9       childMethod() {
    10         this.$parent.fatherMethod('hello');
    11       }
    12     }
    13   };
    14 </script>
    1. vue等单页面应用及其优点

      优点:

           1.具有桌面应用的及时性,网站的可移植性和可访问性。
        2.用户体验好,块,内容改变不需要重新加载整个页面
        3.基于上面一点,SPA相对对服务器压力小。
        4.良好的前后端分离。SPA和RESTful架构一起使用,后端不再负责模板渲染、
        输出页面工作,web前端和各种移动终端地位对等,后端API通用化。
        5.同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端;

      缺点:

       1、不利于SEO。(如果你看中SEO,那就不应该在页面上使用JavaScript,
       你应该使用网站而不是Web应用)
       2、初次加载耗时相对增多。
       3、导航不可用,如果一定要导航需要自行实现前进、后退。

      4.vue.js的两个核心是什么?

      数据驱动和组件化。

      5.vue的双向绑定的原理是什么?

      vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。具体实现过程:

      我们已经知道实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。因此接下去我们执行以下3个步骤,实现数据的双向绑定:

      1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

      2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。

      3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。

      流程图如下:

    二. v-show和v-if指令的共同点和不同点?

    1. v-show指令是通过修改元素的display的css属性达到让其显示或者隐藏

    2. v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

    3. (注意:v-if 可以实现组件的重新渲染)

       

    三. 如何让CSS只在当前组件中起作用?

    将当前组件<style>修改为<style scoped>

    四. <keep-alive></keep-alive>的作用是什么?

    <keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。

    对列表组件使用<keep-alive></keep-alive>进行缓存, 这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染

    五. Vue中引入组件的步骤?

    六.请列举出3个Vue中常用的生命周期钩子函数?

    vue的生命周期分为8个阶段,创建前/后,载入前/后,更新前/后,销毁前/后。

    第一次页面加载需要beforeCreate,created,beforeMount,mounted四个钩子函数。

    1) beforeCreate---创建前

    组件实例被创建,组件属性计算之前,数据对象data都为undefined,未初始化。

    2)created---创建后

    组件实例创建完成,属性已经绑定数据对象data已存在,但DOM未生成,$el未存在。

    3)beforeMount---挂载前

    vue实例的$el和data都已初始化,挂载之前为虚拟的dom节点,data.message未替换。

    4)mounted---挂载后

    vue实例挂载完成,data.message替换,ajax请求等一系列操作。

    5)beforeUpdate---更新前

    当data发生变化,会触发此方法。

    6)updated---更新后l

    当data发生变化,会触发此方法。

    7)beforeDestory--销毁前

    组件销毁前调用。

    8)destoryed---销毁后

    组件销毁后调用,对data的改变不会再触发周期函数,vue实例已解除事件监听和dom绑定,但dom结构依然存在。

    七.请简述下Vuex的原理和使用方法

     数据单向流动
     
     一个应用可以看作是由上面三部分组成: View, Actions,State,
     数据的流动也是从View => Actions => State =>View 以此达到数据的单向流动.
     
     但是项目较大的, 组件嵌套过多的时候, 多组件共享同一个State会在数据传递时出现很多问题
     .Vuex就是为了解决这些问题而产生的.
     
     Vuex可以被看作项目中所有组件的数据中心,我们将所有组件中共享的State抽离出来,
     任何组件都可以访问和操作我们的数据中心
     
     Vuex的组成:一个实例化的Vuex.Store由state, mutations和actions三个属性组成:
      1. state中保存着共有数据
      2. 改变state中的数据有且只有通过mutations中的方法,且mutations中的方法必须是同步的
      3. 如果要写异步的方法,需要些在actions中, 并通过commit到mutations中进行state中数据的更改.

    八.为什么v-if和v-for不能连用?

    • v-for优先级高于v-if,如果连在一起使用的话会把v-if给每一个元素都添加上,

      重复运行于每一个v-for循环中,会造成性能浪费

    • 可以将v-if写在v-for的外层


    九.定义vue-router的动态路由?怎么获取传过来的动态参数?

    设置:在router目录下的index.js文件中,对path属性加上/:id

    获取:使用router对象的params.id

    十.v-for中为什么要用key

    因为vue组件高度复用,增加Key可以标识组件的唯一性,key的作用主要是为了高效的更新虚拟DOM,

    1. 无key时,会存在“就地复用”的问题。(同一组件标签相同,key相同就会复用)

    2. 有key时,只需移动无需重新创建dom。

    十一.Vue中v-html会导致那些问题?

    1. V-html更新的是元素的 innerHTML 。内容按普通 HTML 插入, 不会作为 Vue 模板进行编译 。

    2. 但是有的时候我们需要渲染的html片段中有插值表达式,或者按照Vue模板语法给dom元素绑定了事件。

    3. 在单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被 Vue 的模板编译器处理。如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局 <style>元素手动设置类似 BEM 的作用域策略。

    4. 后台返回的html片段,以及css样式和js,但是返回的js是不执行的,因为浏览器在渲染的时候并没有将js渲染,这时要在$nextTick中动态创建script标签并插入

    十二.Vue组件如何通信?

    https://www.cnblogs.com/fundebug/p/10884896.html


    十三.什么是作用域插槽?

    插槽可以控制html模板的显示与不显示。作用域插槽其实就是带数据的插槽。

    原来父组件可以通过绑定数据传递给子组件。作用域插槽就可以通过子组件绑定数据传递给父组件。

    十四.vue-router有哪几种路由守卫?

    路由守卫为: 全局守卫:beforeEach 后置守卫:afterEach 全局解析守卫:beforeResolve 路由独享守卫:beforeEnter

    十五.组件中的data为什么是一个函数?

    new Vue() 中,data 是可以作为一个对象进行操作的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。

    当data选项是一个函数的时候,每个实例可以维护一份被返回对象的独立的拷贝,这样各个实例中的data不会相互影响,是独立的。


    vue核心知识——vuex

    十六.不用Vuex会带来什么问题?

    一、可维护性会下降,你要想修改数据,你得维护三个地方

    二、可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的

    三、增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,

    现在这么用,和组件化的初衷相背。

    1.vuex有哪几种属性?

    有五种,分别是 State、 Getter、Mutation 、Action、 Module。

    2、vuex的State特性是?

    一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data 二、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新 三、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中

    3、vuex的Getter特性是?

    一、getters 可以对State进行计算操作,它就是Store的计算属性 二、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用 三、 如果一个状态只在一个组件内使用,是可以不用getters

    4、vuex的Mutation特性是?

    一、Action 类似于 mutation,不同在于: 二、Action 提交的是 mutation,而不是直接变更状态。 三、Action 可以包含任意异步操作

    5、Vue.js中ajax请求代码写在组件的methods中还是vuex的actions中?

    一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。 二、如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。


    十七.Ajax请求放在那个生命周期中?

    答案:mounted

    vue本身不支持发送AJAX请求,需要使用vue-resource、axios等插件实现

    等到异步渲染开启的时候,created 就可能被中途打断,中断之后渲染又要重做一遍,想一想,在 created 中做ajax调用,代码里看到只有调用一次,但是实际上可能调用 N 多次,这明显不合适。 相反,若把发ajax 放在 mounted,因为 mounted 在第二阶段,所以绝对不会多次重复调用,这才是ajax合适的位置.

    十八.v-model中的实现原理级如何自定义v-model?

    VUE中的v-model可以实现双向绑定,但是原理是什么呢?往下看看吧

    根据官方文档的解释,v-model其实是一个语法糖,它会自动的在元素或者组件上面解析为 :value="" 和 @input="", 就像下面这样

    1 // 标准写法
    2 <input v-model="name">
    3 
    4 // 等价于
    5 <input :value="name" @input="name = $event.target.value">
    6 
    7 // 在组件上面时
    8 <div :value="name" @input="name = $event"></div>

    1.当在input输入框输入内容时,会自动的触发input事件,更新绑定的name值。

    2.当name的值通过JavaScript改变时,会更新input的value值

    根据上面的原理,vue就通过v-model实现双向数据绑定

    看了前面的解释,对于v-model有了一定的理解。下面我们就来实现自己组件上面的v-model吧

    需求:实现一个简单的点击按钮,每次点击都自动的给绑定值price加100。 组件名为 AddPrice.vue

     1 // AddPrice.vue
     2 // 通过props接受绑定的value参数
     3 <template>
     4   <div @click="$emit('input',value + 100 )">点击加钱<div>
     5 </template>
     6 
     7 <script>
     8   export default {
     9     props: ['value']
    10   }
    11     
    12 </script>
    13 
    14 // 在父组件中调用
    15 <add-price v-model="price"></add-price>

    组件中使用props接受传入的参数值value, 组件点击事件触发并 使用$emit调用父组件上的input事件,实现了自定义的双向绑定

    十九.响应式数据的原理是什么?

    1、声明式

      只需要声明在哪里where,做什么what,而无需关系如何实现how

    1  //此map方法就是,声明式的,只告诉map要实现获取2倍,然后map具体怎么实现不关心
    2  var  arr = [1,2,3,4];
    3  var newArr = arr.map((item,index)=>{
    4      return item*2;
    5  })

    2、命令式

      需要以具体的代码表达在哪里where,做什么what,以及如何实现how

    1  //forEach就是命令式,会具体操作数组,还有如何得到结果push
    2  var  arr = [1,2,3,4];
    3  var newArr = [];
    4  arr.forEach((item,index)=>{
    5      newArr.push(item*2);
    6  })

    声明式的理解:

      1)DOM状态只是数据状态的一种映射

      2)所有的逻辑尽可能在状态的层面去进行

      3)当状态变化了,View会被框架自动更新到合理的状态

     

    3、响应式数据原理

    vue响应式的核心就是Object.defindProperty

    作用:直接在一个对象上定义一个新的属性,或者修改一个对象的现有属性

    语法:Object.definProperty(obj,prop,descriptor)

    参数:obj要在其上定义属性的对象,prop要定义的或要修改的属性的名称,descriptor将被定义或修改的属性描述符

        数据描述

          configurable:是否可以删除属性,默认false

          enumberable:此属性是否可以被枚举,默认false

          value:   该属性对应的值,默认undefined

          writable:  属性的值是否可以被重写,默认false

        访问器描述

          getter:是一种获得属性值的方法

          setter:是一种设置属性值的方法

     1  //数据劫持,转成getter和setter
     2  function observer(obj){
     3      Object.keys(obj).forEach((item)=>{
     4            defineReactive(obj,item,obj[item])
     5      })
     6  }
     7  8  function defineReactive(obj,key,value){
     9      Object.defineProperty(obj,key,{
    10          enumerable:true,
    11          configurable:true,
    12          get(){
    13               return value;
    14          },
    15          set(newValue){
    16               if(value == newValue){return}       
    17              //value相当于是一个公用的存储空间,把最新的值存进去;访问也是访问这里面的最新的值
    18               value=newValue;       
    19              //此处还会放一些其他复杂的操作,收集依赖,通知变化等
    20          }
    21      })
    22  }

    vue响应式原理理解:

      1、把一个普通的js对象传给Vue实例的data选项对象

      2、Vue将遍历此对象的所有的属性,并使用Object.defineProperty把这些属性全部转换为getter/setter

      3、Vue内部会对数据进行劫持操作,进而追踪依赖,在属性被访问和修改时通知变化


    二十.Vue中是如何检查数组变化?

    1.使用函数劫持的方式,重写了数组的方法 2.vue 将 data 中的数据,进行了原型链重写,指向了自己定义的数组原型方法,这样当调用数组 api 的时候,可以通知依赖更新,如果数组中包含着引用类型,则会对数组中的引用类型再次进行监控。

    二十一.Vue中Computed的特点?

    在computed中,可以定义一些属性,这些属性,叫做计算属性。计算属性的本质就是一个方法,只不过,我们在使用这些计算属性的时候,是把它们的名称,直接当做属性来使用,并不会把计算属性当做方法来使用。

    三个注意事项:

    一、计算属性在引用的时候,一定不要加()去调用,直接把它当作普通的属性去使用就好了;

    二、只要计算属性这个function内部所用到的data中的数据发生了变化,就会立即重新计算这个计算属性的值;

    三、计算属性的求值结果,会被缓存起来,方便下次继续使用;如果计算属性方法中,所依赖的任何数据,都没有发生过变化,则不会重新对计算属性求值。

     

    已有的事,后必在有,已行的事,后必在行。
  • 相关阅读:
    ASP.NET Core Web API 帮助页
    SQL SERVER 被锁住的表,以及解锁。
    关键字查找相关存储过程,函数和视图
    MsSql 生成数据文档
    WebApiTestClient 接口测试页
    sql日期
    为什么同样的Sql语句在SqlServer RDS 查询得到的和自己本机SqlServer 查询的不一样呢?
    VS 无法在web服务器上启动调试。您没有调试web服务器进程的权限
    ROS学习之创建工作空间
    QT学习之forward declaration of 'struct Ui::xxx';invalid use of incomplete struct "Ui::Widget"
  • 原文地址:https://www.cnblogs.com/feilongkenguokui/p/13507928.html
Copyright © 2020-2023  润新知