Vue面试知识点汇总

vue生命周期

什么是Vue生命周期?

        Vue实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模版、挂载Dom ——>渲染、更新——>渲染、卸载等一系列过程,我们称这是Vue的生命周期

 Vue生命周期的作用是什么?

       它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑

Vue生命周期总共有几个阶段?

      它可以总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/销毁后

第一次页面加载会触发哪几个钩子?

      第一次页面加载时会触发beforeCreate,created,beforeMount,mounted这几个钩子

DOM渲染在哪几个周期中就已经完成?

      DOM渲染在mounted中就已经完成了

每个生命周期适合哪些场景?

生命周期钩子的一些使用方法:

       beforecreate:可以在这加个loading事件,在加载实例时触发

       created:初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用

       mounted:挂载元素,获取到DOM节点

       updated:如果对数据统一处理,在这里写上相应函数

       beforeDestroy:可以做一个确认停止事件的确认框

       nextTick:更新数据后立即操作dom

v-show与v-if区别:

v-show是css切换,v-if是完整的销毁和重新创建

使用频繁切换时用v-show,运行时较少改变时用v-if

v-if = ‘false’

v-if是条件渲染,当false的时候不会渲染

开发中常用的指令有哪些?

v-model:一般用在表达输入,很轻松的实现表单控件和数据的双向绑定

v-html:更新元素的innerHTML

v-show与v-if:条件渲染,注意二者的区别

        使用了v-if的时候,如果值为false,那么页面将不会有这个html标签生成

        v-show则是不管值为true还是false,html元素都会存在,只是css中的display显示或隐藏

v-on:click:可以简写为@click,@绑定一个事件。如果事件触发了,就可以指定事件的处理函数v-for:基于源数据多次渲染元素或模板块v-bind:当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM

语法:v-bind:title=“msg”简写::title=“msg”

绑定class的数据用法

对象方法v-bind:class = “{‘orange’:isRipe,‘green’:isNotRipe}”

数组方法 v-bind:class= “[class1,class2]”

行内v-bind:style = “{color:color,fontSize:fontSize+‘px’}”

组件之间的传值通信

父组件给子组件传值

       使用props,父组件可以使用 props向子组件传递数据

//父组件vue模板father.vue:
<template>
    <child:msg = "message"></child>
</template>

<script>
    import child from './child.vue';
    export default {
        components: {
            child
        },
        data() {
            return {
                message:'father message';    
            }
        }
    }
</script>

//子组件vue模板child.vue:
<template>
    <div>{{msg}}</div>
</template>

<script>
    export default {
        props:{
            msg:{
                type:String,
                required:true
            }
        }
    }
</script>

子组件向父组件通信

       父组件向子组件传递事件方法,子组件通过$emit触发事件,回调给父组件

//父组件vue模板father.vue:
<template>
    <child @msgFunc="func"></child>
</template>

<script>
    import child from './child.vue';
    export default {
        components: {
            child
        },
        methods: {
            func(msg) {
                console.log(msg);
            }
        }
    }
</script>

//子组件vue模板child.vue:
<template>
    <button @click="handleClick">点我</button>
</template>

<script>
    export default {
        props: {
            msg: {
                type:String,
                required:true
            }
        },
        methods() {
            handleClick() {
                //......
                this.$emit('msgFunc');
            }
        }
    }
</script>

  非父子,兄弟组件之间通信

         可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发和监听来实现通信和参数传递 

//Bus.js可以是这样:
import Vue from ‘vue’
export default new Vue()

//在需要通信的组件都引入Bus.js:
<template>
    <button @click="toBus">子组件传给兄弟组件</button>
</template>

<script>
    import Bus from ‘../common/js/bus.js’
    export default {
        methods: {
            toBus() {
                Bus.$emit('on','来自兄弟组件')
            }
        }
    }
</script>

//另一个组件也import Bus.js在钩子函数中监听on事件
import Bus from '../common/js/bus.js'
export default {
    data() {
        return {
            message:''
        }
    },
    mounted() {
        Bus.$on('on',(msg) => {
            this.message = msg
        })
    }
}

路由跳转方式

1、<router-link to = 'home'>router - link标签会渲染为<a>标签,咋填template中的跳转都是这种:

2、另一种是编程是导航,也就是通过js跳转。比如:router.push('/home')

MVVM

M - Model,Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑

V - View,View代表UI组件,它负责将数据模型转化为UI展现出来

VM - ViewModel,ViewModel监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View和Model的对象,连接Model和View

computed和watch有什么区别?

computed:

1、computed是计算属性,也就是计算值,它更多用于计算值的场景

2、computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算

3、computed适用于计算比较消耗性能的计算场景

watch:

1、更多的是[观察]的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作

2、无缓存性,页面重新渲染时值不变化也会执行

小结:

1、当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed

2、如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化

key

key是为Vue中的vnode标记的唯一id,通过这个key,我们的diff操作可以更准确、更快速

准确:

如果不加key,那么vue会选择复用节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产生一系列的bug

快速:

key的唯一性可以被Map数据结构充分利用

组件中的data为什么是函数?

为什么组件中的data必须是一个函数,然后return一个对象,而new Vue实例里,data可以直接是一个对象?

//data
data() {
    return {
        message:"子组件",
        childName:this.name
    }
}

//new Vue
new Vue({
    el:'#app',
    router,
    template:'<App/>',
    components:{App}
})

因为组件是用来复用的,JS里对象是引用关系,这样作用域没有隔离,而new Vue的实例,是不会被复用的,因此不存在引用对象问题

Class与Style如何动态绑定?

Class 可以通过对象语法和数组语法进行动态绑定:

//对象语法
<div v-bind:class="{active:isActive,'text-danger':hasError}"></div>
data:{
    isActive:true,
    hasError:false
}

//数组语法
<div v-bind:class="[isActive ? activeClass:'',errorClass]"></div>
data:{
    activeClass:'active',
    errorClass:'text-danger'
}

Style也可以通过对象语法和数组语法进行动态绑定:

//对象语法
<div v-bind:style="{color:activeColor,fontSize:fontSize + 'px'}"></div>
data: {
    activeColor:'red',
    fontSize:30
}

//数组语法
<div v-bind:style="[styleColor,styleSize]"></div>
data:{
    styleColor:{
        color:'red'
    },
    styleSize:{
        fontSize:'23px'
    }
}

vue的单项数据流

所有的prop都使得其父子prop之间形成了一个单向下行绑定:父级prop的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解

额外的,每次父级组件发生更新时,子组件中所有的prop都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变prop。如果你这样做了,Vue会在浏览器的控制台中发出警告。子组件想修改时,只能通过$emit派发一个自定义事件,父组件接收到后,由父组件修改

有两种常见的试图改变一个prop的情形:

这个prop用来传递一个初始值;这个子组件接下来希望将其作为一个本地的prop数据来使用

在这种情况下,最好定义一个本地的data属性并将这个prop用作其初始值:

props:['initialCounter'],
data:function() {
    return {
        counter:this.initialCounter
    }
}

 

这个prop以一种原始的值传入且需要进行转换

在这种情况下,最好使用这个prop的值来定义一个计算属性

props:['size'],
computed: {
    normalizedSize:function() {
        return this.size.trim().toLowerCase()
    }
}

keep-alive

keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,避免重新渲染,其有以下特性:

1、一般结合路由和动态组件一起使用,用于缓存组件;

2、提供include和exclude属性,两者都支持字符串或正则表达式,include表示只有名称匹配的组件会被缓存,exclude表示任何名称匹配的组件都不会被缓存,其中exclude的优先级比include高;

3、对应两个钩子函数activated和deactivated,当组件被激活时,触发钩子函数activated,当组件被移除时,触发钩子函数deactivated。

v-model的原理

vue项目中主要使用v-model指令在表单input、textarea、select等元素上创建双向数据绑定,我们知道v-model本质上不过是语法糖,v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:

text和textarea元素使用value属性和input事件;

checkbox和radio使用checked属性和change事件;

select字段将value作为prop并将change作为事件;

以input表单元素为例:

<input v-model='something'>

// 相当于

<input v-bind:value="something" v-on:input="something=$event.target.value">

如果在自定义组件中,v-model默认会利用名为value的prop和名为input的事件,如下所示:

//父组件
<ModelChild v-model="message"></ModelChild>

//子组件
<div>{{value}}</div>
props:{
    value:String
},
methods:{
    test1() {
        this.$emit('input','小红')
    },
},

nextTick()

在下次DOM更新循环结束之后执行延迟回调。在修改数据之后,立即使用的这个回调函数,获取更新后的DOM

//修改数据
vm.msg = "Hello"

//DOM还未更新
Vue.nextTick(function() {
    //DOM更新
})

vue插槽

单个插槽:

当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的DOM位置,并替换掉插槽标签本身

命名插槽:

solt元素可以用一个特殊的特性name来进一步配置如何分发内容。

多个插槽可以有不同的名字。这样可以将父组件模板中slot位置和子组件slot元素产生关联,便于插槽内容对应传递

作用域插槽:

可以访问组件内部数据的可复用插槽(reusable slot)。在父级中,具有特殊特性slot-scope的<template>元素必须存在,表示它是作用域插槽的模板。slot-scope的值将被用作一个临时变量名,此变量接收从子组件传递过来的prop对象

vue-router有哪几种导航钩子

第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截

第二种:组件内的钩子

第三种:单独路由独享组件

vuex

vuex是什么?

vuex就是一个仓库,仓库里放了很多对象。其中state就是数据源存放地,对应于一般vue对象里面的data

state里面存放的数据是响应式的,vue组件从store读取数据,若是store中的数据发生改变,依赖这些数据的组件也会发生更新

它通过mapState把全局的state和getters映射到当前组件的computed计算属性

Vuex有5种属性:分别是state、getter、mutation、action、module;

state

Vuex使用单一状态树,即每个应用将仅仅包含一个store实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据

mutations

mutations定义的方法动态修改Vuex的store中的状态或数据

getters

类似vue的计算属性,主要用来过滤一些数据

action

actions可以理解为通过将mutations里面处理数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view层通过store.dispath来分发action

总结:

vuex一般用于中大型web单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用vuex的必要性不是很大,因为完全可以用组件prop属性或者事件来完成父子组件之间的通信,vuex更多地用于解决跨组件通信以及作为数据中心集中式存储数据。

对vue项目可以进行哪些优化?

代码层面的优化

v-if和v-show区分使用场景

computed和watch区分使用场景

v-for遍历必须为item添加key,且避免同时使用v-if

长列表性能优化

事件的销毁

图片资源懒加载

路由懒加载

第三方插件的按需引入

优化无限列表性能

服务端渲染SSR or 预渲染

Webpack层面的优化

Webpack对图片进行压缩

减少ES6转为ES5的冗余代码

提取公共代码

模板预编译

提取组件的CSS

优化SourceMap

构建结果输出分析

Vue项目的编译优化

基础的Web技术的优化

开启gzip压缩

浏览器缓存

CDN的使用

使用Chrome Performance查找性能瓶颈

 

 

 

 

 

 

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值