首发于Debug

面试题2 vue核心知识点

1、对于Vue是一套渐进式框架的理解

在我看来,渐进式代表的含义是:主张最少。
每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。
比如说,Angular,它两个版本都是强主张的,如果你用它,必须接受以下东西:
- 必须使用它的模块机制- 必须使用它的依赖注入- 必须使用它的特殊形式定义组件(这一点每个视图框架都有,难以避免)

所以Angular是带有比较强的排它性的,如果你的应用不是从头开始,而是要不断考虑是否跟其他东西集成,这些主张会带来一些困扰。

比如React,它也有一定程度的主张,它的主张主要是函数式编程的理念,比如说,你需要知道什么是副作用,什么是纯函数,如何隔离副作用。它的侵入性看似没有Angular那么强,主要因为它是软性侵入。

Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
渐进式的含义,我的理解是:没有多做职责之外的事

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

1、数据驱动,也叫双向数据绑定。
Vue.js数据观测原理在技术实现上,利用的是ES5Object.defineProperty和存储器属性: getter和setter(所以只兼容IE9及以上版本),可称为基于依赖收集的观测机制。核心是VM,即ViewModel,保证数据和视图的一致性。
2、组件系统。
.vue组件的核心选项:
1、模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。
2、初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。
3、接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。
4、方法(methods):对数据的改动操作一般都在组件的方法内进行。
5、生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。
6、私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。
等等。

3、请问v-ifv-show有什么区别

共同点:
v-if和v-show都是通过判断绑定数据的true\false来展示的
不同点:
v-if只有在判断为true的时候才会对数据进行渲染,false的时候把包含的代码进行删除。除非再次进行数据渲染,v-if才会重新判断。可以说是用法比较倾向于对数据一次操作。
v-show是无论判断是什么都会先对数据进行渲染,只是false的时候对节点进行display:none;的操作。所以再不重新渲染数据的情况下,改变数据的值可以使数据展示或隐藏。
用法推荐:
v-if更适合于带有权限的操作,渲染时判断权限数据,有则展示该功能,没有则删除。
v-show更适合于日常使用,可以减少数据的渲染,减少不必要的操作。
综上,v-if 有更高的切换消耗,而 v-show 有更高的初始渲染消耗。
因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变,更倾向功能权限性的话 v-if 较好。

作者:腹黑De狼
链接:https://www.jianshu.com/p/4128c399d32c
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

4、vue常用的修饰符

vue提供了如下修饰符:

1.事件修饰符
vue为v-on提供了事件修饰符,通过点(.)表示的指令后缀来调用修饰符。

.stop
阻止点击事件冒泡。等同于JavaScript中的event.stopPropagation()
例如:

<a v-on:click.stop="doThis"></a>
<a @click.stop="doThis"></a>

实例1,防止冒泡:

<div id="app"> 
  <div class="outeer" @click.stop="outer"> 
    <div class="middle" @click.stop="middle"> 
      <button @click.stop="inner">点击我(^_^)</button>
     </div>
   </div> 
</div>

使用了.stop后,点击子节点不会捕获到父节点的事件

2.prevent
防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播),等同于JavaScript中的event.preventDefault(),prevent等同于JavaScript的event.preventDefault(),用于取消默认事件。比如我们页面的标签,当用户点击时,通常在浏览器的网址列出#:
例如:

<a v-on:submit.prevent="doThis"></a>

.capture
与事件冒泡的方向相反,事件捕获由外到内,捕获事件:嵌套两三层父子关系,然后所有都有点击事件,点击子节点,就会触发从外至内 父节点-》子节点的点击事件

<a v-on:click.capture="doThis"></a>

<div id="app"> 
  <div class="outeer" @click.capture="outer"> 
    <div class="middle" @click.capture="middle"> 
      <button @click.capture="inner">点击我(^_^)</button>
     </div>
   </div> 
</div>

.self
只会触发自己范围内的事件,不包含子元素

<a v-on:click.self="doThat"></a>

<div id="app"> 
  <div class="outeer" @click.self="outer"> 
    <div class="middle" @click.self="middle"> 
      <button @click.stop="inner">点击我(^_^)</button>
     </div>
   </div> 
</div>
.once
只执行一次,如果我们在@click事件上添加.once修饰符,只要点击按钮只会执行一次。

<a @click.once="doThis"></a>
1
.passive
Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

这个 .passive 修饰符尤其能够提升移动端的性能。不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

事件修饰符还可以串联
例如:

<a v-on:click.stop.prevent="doThis"></a>

注:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

2.键盘修饰符
在JavaScript事件中除了前面所说的事件,还有键盘事件,也经常需要监测常见的键值。在Vue中允许v-on在监听键盘事件时添加关键修饰符。记住所有的keyCode比较困难,所以Vue为最常用的键盘事件提供了别名:
.enter:回车键
.tab:制表键
.delete:含delete和backspace键
.esc:返回键
.space: 空格键
.up:向上键
.down:向下键
.left:向左键
.right:向右键

例如:

<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">

可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

3.系统修饰键
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta

注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”。

例如:

<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

注意:

请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。

.exact修饰符
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

鼠标按钮修饰符
鼠标修饰符用来限制处理程序监听特定的滑鼠按键。常见的有:
.left
.right
.middle
这些修饰符会限制处理函数仅响应特定的鼠标按钮。

自定义按键修饰符别名
在Vue中可以通过config.keyCodes自定义按键修饰符别名。例如,由于预先定义了keycode 116(即F5)的别名为f5,因此在文字输入框中按下F5,会触发prompt方法,出现alert。

<template>
  <div class="main">
      <input type="text" @keyup.f5="prompt()" />
  </div>
</template>
<script>
export default {
  data() {
    return {
    };
  },
  methods:{
      prompt(){
          alert("aaaaa")
      }
  }

};
</script>

当点击f5时立马调用prompt方法。

4.修饰符
(1).lazy
在改变后才触发(也就是说只有光标离开input输入框的时候值才会改变)

<input v-model.lazy="msg" />
1
(2).number
将输出字符串转为Number类型·(虽然type类型定义了是number类型,但是如果输入字符串,输出的是string)

<input v-model.number="msg" />
1
(3).trim
自动过滤用户输入的首尾空格

<input v-model.trim="msg" />

5、v-on可以监听多个方法吗?

 v-on可以监听多个方法,例如:
 <input type=“text” :value=“name” @input=“onInput” @focus=“onFocus” @blur=“onBlur” />
 但是同一种事件类型的方法,vue-cli工程会报错,例如:
 <a href=“javascript:;” @click=“methodsOne” @click=“methodsTwo”></a>

6、vue中 key 值的作用

问题二:vue中 key 值的作用
    key值:用于 管理可复用的元素。因为Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做使 Vue 变得非常快,但是这样也不总是符合实际需求。
    2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。
    例如,如果你允许用户在不同的登录方式之间切换:
    <template v-if=“loginType === 'username‘”>
    <label>Username</label>
    <input placeholder=“Enter your username”>
    </template>
    <template v-else>
    <label>Email</label>
    <input placeholder=“Enter your email address”>
    </template>
    那么在上面的代码中切换loginTypeloginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,</span>不会被替换掉,仅仅是替换了它的 placeholder`.
    这样也不总是符合实际需求,所以Vue为你提供了一种方式来表达这两个元素是完全独立的,不要复用它们。只需添加一个具有唯一值的 key 属性即可:
    <template v-if=“loginType === 'username’”>
    <label>Username</label>
    <input placeholder=“Enter your username” key=“username-input”>
    </template>
    <template v-else>
    <label>Email</label>
    <input placeholder=“Enter your email address” key=“email-input”>
    </template>

7、vue-cli工程升级vue版本

npm update vue --save

8、$nextTick的使用

Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM。this.$nextTick()官方介绍:将回调延迟到下次 DOM 更新循环之后执行。
在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
 new Vue({
        el: "#app",
        data: {
            message: 'Hello Vue.js',
            showMe: false
        },
        methods: {
            getMyWidth() {
                this.showMe = true;
                //this.message = this.$refs.myWidth.offsetWidth;//报错 TypeError: this.$refs.myWidth is undefined
                this.$nextTick(()=>{
                    //dom元素更新后执行,此时能拿到p元素的属性
                    this.message = this.$refs.myWidth.offsetWidth;
                })
            }
        }
    })

9、v-for 与 v-if 的优先级

v-for和v-if不应该一起使用,必要情况下应该替换成computed属性。

原因:v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。

10、vue中子组件调用父组件的方法

Vue子组件调用父组件的方法 - 靳哲 - 博客园www.cnblogs.com

11、vue中keep-alive组件的作用


vue项目使用keep-alive的作用 - 林子lxl - 博客园www.cnblogs.com

12、vue生命周期钩子函数有哪些

beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed

13、vue如何监听键盘事件中的按键?

<input @keyup.enter="function">

另外,Vue中还支持组合写法:

组合写法	按键组合

@keyup.alt.67=”function”	Alt + C
@click.ctrl=”function”	Ctrl + Click

14、vue数组操作不更新视图问题

vue 观察数组的变异方法 更新视图
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
pop()  如何使用 pop() 来删除并返回数组的最后一个元素。
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
splice(i,n,arr)  方法向/从数组中添加/删除项目,然后返回被删除的项目。
sort(xx)
reverse()

15、v-for产生的列表,实现active的切换

 <ul>
     <li @click="cliFun(index)" v-for="(item,index) in checkboxList"  :class="{addClass:index===currentIndex}" :key="index">{{item.product_inf}}</li>
 </ul>

data(){
 currentIndex:0,
 checkboxList: [
        {
          id: "1",
          product_inf: "女士银手链"
        },
        {
          id: "2",
          product_inf: "女士银手镯"
        },
        {
          id: "3",
          product_inf: "女士银耳环"
        }
      ],
},
methods:{
 cliFun(index){
      this.currentIndex=index
    },
}

16、十个常用的自定义过滤器

https://blog.csdn.net/qq_36111804/article/details/80812403
在src 文件夹下新建filters文件夹,在filters下面新建index.js
文件如下
const normalTime = time => {
    if (time) {
      var oDate = new Date();
      oDate.setTime(time);
   
      var y = oDate.getFullYear();
      var m = oDate.getMonth() + 1;
      var d = oDate.getDate();
   
      var h = oDate.getHours();
      var m = oDate.getMinutes();
      var s = oDate.getSeconds();
   
      return y + "-" + m + "-" + d + " " + h + ":" + m + ":" + s;
    }
  };
  //补零
  const fillZero = num => {
    return num < 10 ? "0" + num : num;
  };
  //带参数
  //货币形式
  const currency = (value, unit, decimal) => {
    let reg = /^[0-9]+.?[0-9]*$/;
    if (!reg.test(value)) return "";
    value = decimal == undefined ? value : value.toFixed(decimal);
    return `${unit}${value}`;
  };
  //首字母大写
  const capitalize = value => {
    if (!value) return "";
    value = value.toString();
    return value.charAt(0).toUpperCase() + value.slice(1);
  };
  //时间戳转换为指定格式时间
  const timeFormat = (value, format) => {
    let date = new Date(value);
    let y = date.getFullYear();
    let m = date.getMonth() + 1;
    let d = date.getDate();
    let h = date.getHours();
    let min = date.getMinutes();
    let s = date.getSeconds();
    let result = "";
    if (format == undefined) {
      result = `${y}-${m < 10 ? "0" + m : m}-${d < 10 ? "0" + d : d} ${
        h < 10 ? "0" + h : h
      }:${min < 10 ? "0" + min : min}:${s < 10 ? "0" + s : s}`;
    }
    if (format == "yyyy-mm-dd") {
      result = `${y}-${m < 10 ? "0" + m : m}-${d < 10 ? "0" + d : d}`;
    }
    if (format == "yyyy-mm") {
      result = `${y}-${m < 10 ? "0" + m : m}`;
    }
    if (format == "mm-dd") {
      result = ` ${mm < 10 ? "0" + mm : mm}:${ddmin < 10 ? "0" + dd : dd}`;
    }
    if (format == "hh:mm") {
      result = ` ${h < 10 ? "0" + h : h}:${min < 10 ? "0" + min : min}`;
    }
    return result;
  };
  export default {
    normalTime,
    fillZero,
    currency,
    capitalize,
    timeFormat
  };

在main.js
import filters from '@/filters/index.js'

Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key]);
});

用法:
{{num|fillZero}}
{{num|currency("$")}}

17、vue等单页面应用及其优缺点

优点:1用户体验好,流畅。

    2因为单页面,所以对服务器的压力较小。

    3可以在页面切换的时候加一些酷炫的动画效果。

    4代码的复用度大。有利于后期的维护。

  缺点:1页面复杂度变大,开发难度较大。

     2不利于SEO

     3初次加载的时候用时较长。

18、什么是vue的计算属性? computed

 <button @click="add()">补充货物1</button>
  <div>总价为:{{price}}</div>

data(){
 package1: {
           count: 5,
           price: 5
       },
       package2: {
           count: 10,
           price: 10
       },
} 

computed:{
    price(){
      let val=this.package1.count*this.package1.price+this.package2.count*this.package2.price;
      return val;
    }
  },
methods:{
 add(){
      this.package1.count++
    },
}

19、vue-cli开发环境使用全局常量


https://blog.csdn.net/just_for_your_smile/article/details/78815783blog.csdn.net

20、Vue自定义指令

1.创建局部指令
var app = new Vue({
    el: '#app',
    data: {    
    },
    // 创建指令(可以多个)
    directives: {
        // 指令名称
        dir1: {
            inserted(el) {
                // 指令中第一个参数是当前使用指令的DOM
                console.log(el);
                console.log(arguments);
                // 对DOM进行操作
                el.style.width = '200px';
                el.style.height = '200px';
                el.style.background = '#000';
            }
        }
    }
})

2.全局指令
Vue.directive('dir2', {
    inserted(el) {
        console.log(el);
    }
})

3.指令的使用
<div id="app">
    <div v-dir1></div>
    <div v-dir2></div>
</div>

编辑于 2019-05-08

文章被以下专栏收录