vue面试题一之什么是vue-loader?、什么是 mixin?、Vue:Prop验证如何使用?、怎样理解虚拟DOM?、vue渲染函数怎么用?、Vue中的nextTick用法和原理详解等

2023年1月29日08:25:18

1. 什么是vue-loader?

背景:
1.首先,webpack干嘛的? 打包。
2 webpack 中的各种loader干啥用的? webpack只认识Js,loader帮忙转化其他模块(HTML\CSS),把其他模块转化为webpack所能打包的模块,方便打包。

什么是vue-loader?
作用:解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template,再分别把它们交给对应的 Loader 去处理。

2.什么是 mixin?

混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>mixin入门</title>
        <!-- 引入vue.js -->
        <script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
    </head>
    <body>
        <div id='app'>
          
        </div>
    
    </body>
    <script>
        let vm = new Vue({
           // 用法:导入mymixins , 在当前vue文件中使用mixin选项即可
            mixin:[mymixins],
            el:'#app',
            data:{ 
              num :2  
            },
            methods:{ 
            }
        })


        const mymixins= {
            data:{ 
               num :1 
            },
            methods:{ 
            }
        }
    </script>
</html>

mixins的特点:
1 方法和参数在各组件中不共享
2 值为对象的选项,如methods,components等,选项会被合并,键冲突的组件会覆盖混入对象的
3 值为函数的选项,如created,mounted等,就会被合并调用,混合对象里的钩子函数在组件里的钩子函数之前调用

3. Vue:Prop验证如何使用?

<template>
  <div style="margin-top:100px">
    <my-component 
    :propA="100" 
    :propB="'sdf'" 
    :propC="'propC11'" 
    :propD="100" 
    :propE="{a:'a'}" 
    :propF="'warning'">
    </my-component>
  </div>
</template>
 
<script type="text/javascript">
import Vue from 'vue'
 
Vue.component('my-component', {
  props: {
    //必须是数字类型
    propA: Number,
    //必须是字符串或数字类型
    propB: [String, Number],
     //布尔值,如果没有定义,默认值就是true
    propC: {
      type: String,
      required: true
    },
     //数字,如果没有定义,默认值就是100
    propD: {
      type: Number,
      default: 100
    },
     **//对象,默认值必须是一个函数来返回,且返回 { message: 'hello' }  (如果是数组,默认值也需要函数返回)**
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    //自定义一个验证函数
    propF: {
      validator: function (value) {
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  },
  template: `
  <div>
    <p>{{ propA }}</p>
    <p>{{ propB }}</p>
    <p>{{ propC }}</p>
    <p>{{ propD }}</p>
    <p>{{ propE }}</p>
    <p>{{ propF }}</p>
  </div>`
})
 
export default {
  name: 'main',
  data(){
  },
  method(){
  }
}
</script>

type 可以是下面原生构造器:
String
Number
Boolean
Function
Object (默认值函数形式)
Array (默认值函数形式)
也可以自定义验证规则(函数形式)

4. 怎样理解虚拟DOM?

虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。这句话,也许过于抽象,却基本概况了虚拟DOM的设计思想

具体是怎么操作的?
(1).用JS表示DOM结构
(2).比较两棵虚拟DOM树的差异
(3).对真实DOM进行最小化修改

5. vue渲染函数怎么用?

渲染函数的作用:VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数。

如何写一个render函数,都有哪些常见的api?

关键点一:理解createElement:

createElement 参数
 
// @return {VNode}
createElement(
  // {String | Object | Function}
 
  // 1.一个HTML标签字符串,组件选项对象,或者一个返回值类型为String/Object的函数。该参数是必须的
  'div',
 
  // {Object}
  // 2.一个包含模板相关属性的数据对象,这样我们可以在template中使用这些属性,该参数是可选的。
  { },
 
  // {String | Array}
  // 3.子节点(VNodes),由 createElement() 构建而成。或简单的使用字符串来生成的 "文本节点"。可选参数
 
)

关键点二:模板相关属性的数据对象

{
  // 和`v-bind:class`一样的 API
  'class': {
    foo: true,
    bar: false
  },
  // 和`v-bind:style`一样的 API
  style: {
    color: 'red',
    fontSize: '14px'
  },
  // 正常的 HTML 特性  - 属性
  attrs: {
    id: 'foo'
  },
  // 组件 props
  props: {
    myProp: 'bar'
  },
  // DOM 属性
  domProps: {
    innerHTML: 'baz'
  },
  // 事件监听器基于 `on`
  // 所以不再支持如 `v-on:keyup.enter` 修饰器
  // 需要手动匹配 keyCode。
  on: {
    click: this.clickHandler
  },
  // 仅对于组件,用于监听原生事件,而不是组件内部使用 `vm.$emit` 触发的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定义指令。注意事项:不能对绑定的旧值设值
  // Vue 会为您持续追踪
  directives: [
    {
      name: 'my-custom-directive',
      value: '2',
      expression: '1 + 1',
      arg: 'foo',
      modifiers: {
        bar: true
      }
    }
  ],
  // Scoped slots in the form of
  // { name: props => VNode | Array<VNode> }
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
  // 如果组件是其他组件的子组件,需为插槽指定名称
  slot: 'name-of-slot',
  // 其他特殊顶层属性
  key: 'myKey',
  ref: 'myRef'
}

写一个代码实例:

render: (h,params)=>
{    
    //  可以组织一些下面需要使用的参数
    return createElement(
           //参数一:标签字符串-必选
          'h' + this.level,
           //参数三:子节点(VNodes)由 createElement() 构建而成-可选参数
          [
            createElement(
             //参数一:标签字符串-必选
             'a', 
             //参数二:模板相关属性的数据对象-可选
             {
              attrs: {
                name: headingId,
                href: '#' + headingId
              },
              style: {
                color: 'red',
                fontSize: '20px'
              },
              'class': {
                foo: true,
                bar: false
              },
              // DOM属性
              domProps: {
                innerHTML: 'baz'
              },
              // 组件props
              props: {
                myProp: 'bar'
              },
              // 事件监听基于 'on'
              // 所以不再支持如 'v-on:keyup.enter' 修饰语
              // 需要手动匹配 KeyCode  
              on: {
                click: function(event) {
                  event.preventDefault();
                  console.log(111);
                }
              }
            }, this.$slots.default)
          ]
        )
}

6. Vue中的nextTick用法和原理详解

背景:
Vue实现响应式并不是数据发生变化之后DOM立即变化,而是异步执行DOM更新的。

异步执行的运行机制是什么样的?阮一峰老师是这样总结的:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

带着阮一峰老师的讲解,理解一下vue异步更新的原理:
1.修改 Vue 中的 Data 时,就会触发所有和这个 Data 相关的 Watcher 进行更新。
2.首先,会将所有的 Watcher 加入队列 Queue。
3.然后,调用 nextTick 方法,执行异步任务。
4.在异步任务的回调中,对 Queue 中的 Watcher 进行排序,然后执行对应的 DOM 更新。

this.$nextTick()的使用场景:看一个例子

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app" @click="handleClick" ref="test">{{message}}</div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            message: 'Zeke'
        },
        methods: {
            handleClick() {
                this.message = 'Hello'
                console.log(this.$refs.test.innerText)  // Zeke
                this.$nextTick(function () {
                    console.log(this.$refs.test.innerText) // Hello
                })
            }
        }
    })
</script>

</html>

n

e

x

t

T

i

c

k

n

e

x

t

T

i

c

k

1

t

h

i

s

.

m

e

s

s

a

g

e

=

H

e

l

l

o

2

n

e

x

t

T

i

c

k

n

e

x

t

T

i

c

k

i

n

n

e

r

T

e

x

t

原理:当执行到nextTick的时候,他也会把nextTick里面的代码放到一个队列当中, 按照队列的顺序优先级等一个个按次序执行, 新添加的事件都会放在队列末尾。也就是这段代码执行流程为:1 this.message = 'Hello' 先放到队列中,先执行。2 nextTick中的代码也放到队列中,依次执行。如果不用 nextTick 直接获取innerText是获取不到的,因为并不是理解渲染,而是异步渲染

nextTicknextTick1this.message=Hello2nextTicknextTickinnerText

vue操作DOM节点的时候,一般在mounted钩子函数中,因为在这个时候DOM已经全部渲染完毕,但在实际的开发过程中,如果我们在刚更新完数据之后,就要操作这个相关节点,我们是拿不到更新以后的DOM的,因为vue中DOM节点的更新是异步的。
所以如果我们要想在刚更新完数据之后就要操作DOM,我们可以通过nextTick函数,将要在视图更新完毕之后执行的代码放在回调函数中执行。

7. 什么时候使用keep-alive元素?

keep-alive是Vue.js的一个内置组件。它能够把不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。

在创建时从 API 调用中引入数据的组件。你可能不希望每次动态切换这个组件进行渲染时都调用此 API。这时你可以将组件包含在 keep-alive 元素中。keep-alive 元素缓存该组件并从那里获取它,而不是每次都重新渲染它。

  • 作者:Dormiveglia-flx
  • 原文链接:https://feilx.blog.csdn.net/article/details/119701641
    更新时间:2023年1月29日08:25:18 ,共 5677 字。