← 返回首页
Vue高频面试题(一)
发表时间:2022-09-12 10:17:30
Vue高频面试题(一)

1.什么是SPA应用,它的优缺点分别是什么?

SPA:single page application,单页面应用。仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转,而页面的变化是利用路由机制实现HTML内容的动态更新,避免页面的重新加载。

优点:

缺点: - 首次加载比较慢 - SEO难度较大

SEO是“搜索引擎优化”。也就是通过某些特定规则来优化网站代码,从而使网站能更加容易的被搜索引擎抓取到,提高搜索结果的排名。

针对SPA应用的SEO优化方案有:

2.为什么说Vue是一个渐进式的javascript框架, 渐进式是什么意思?

Vue的渐进式体现在:代码侵入性低,既可以当库使用,也可以当框架使用。简而言之就是,没有多做职责之外的事。

3.谈谈你对MVVM的理解。

MVVM:Model-View-ViewModel。

MVVM的优点: - MVVM实现了视图与数据的双向绑定,而MVC只实现了数据到视图的单向绑定。 - MVVM实现了业务逻辑与页面渲染的解耦,数据与视图的解耦,可以组件化开发。

4.说说v-show和v-if的区别。

共同点:v-if和 v-show都是用来实现元素的显示隐藏的vue指令。

区别: - v-show 是条件隐藏,内部是通过display:none实现。v-if是条件渲染,只有条件为真时才渲染元素。 - v-show 有更高的首次渲染开销,而 v-if的首次渲染开销要小的多。 - v-show 的切换开销小,而v-if有更高的切换开销。 - v-if 可以搭配template使用,而v-show不行。

总结:如果需要非常频繁地切换,则使用v-show较好,如果在运行时条件很少改变,则使用v-if较好。

5.说说v-for为什么要用key,选择什么属性做key适合?

key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点。

实例:

<div id="app">
    <ul>
        <li v-for="(c,index) in citys" :key="index">
            <input type="checkbox" :value="c">{{c}}</input>
        </li>
    </ul>
    <input type="button" @click="removeFirst" value="删除第一个元素"/>
</div>
<script>

    let vm = new Vue({
        el: '#app',
        data() {
            return {
                citys: ['北京', '上海', '广州', '成都']
           }
        },
        mounted() {
        },
        methods: {
            //每次删除第一个元素
            removeFirst() {
                this.citys.shift();
            }
        }
    })
</script>

首先选中'北京',然后点击删除后:

我们发现此时'北京'已经删除了,但是'上海'默认选中,显然是不合理的。这是因为Vue,默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染,要选择适合的属性作为key。

代码改写如下:


<div id="app">
    <ul>
        <li v-for="(c,index) in citys" :key="c.code">
            <input type="checkbox" :value="c.name">{{c.name}}</input>
        </li>
    </ul>
    <input type="button" @click="removeFirst" value="删除第一个元素"/>

</div>
<script>

    let vm = new Vue({
        el: '#app',
        data() {
            return {
                citys: [
                    {
                        code: '010',
                        name: '北京'
                    },
                    {
                        code: '021',
                        name: '上海'
                    },
                    {
                        code: '020',
                        name: '广州'
                    },
                    {
                        code: '028',
                        name: '成都'
                    }
                ]
            }
        },
        mounted() {
        },
        methods: {
            removeFirst() {
                this.citys.shift();
            }
        }
    })
</script>

总结:v-for通常会指定一个key属性,这个key属性使用一些唯一索引或者主键更为合适。

6.说说computed和watch,methods的区别。

computed和watch都可以用来监听数据的变化,区别如下:

7.Vue子组件和父组件执行顺序。

vue2 中生命周期的执行顺序:

beforeCreate => created => beforeMount => mounted => beforeUpdate => updated => beforeDestroy => destroyed

vue3 中生命周期的执行顺序:

setup =>onBeforeMount => onMounted => onBeforeUpdate => onUpdated => onBeforeUnmount => onUnmounted

对应关系: vue2->vue3

beforeCreate -> setup
created -> setup
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted

父子组件执行顺序

挂载阶段的执行顺序为:

父beforeCreate => 父created => 父beforeMount => 子beforeCreate => 子created => 子beforeMount => 子mounted => 父mounted

更新阶段的执行顺序为: 父beforeUpdate => 子beforeUpdate => 子updated => 父updated

销毁阶段的执行顺序为: 父beforeDestroy => 子beforeDestroy => 子destroyed => 父destroyed

规律就是:父组件先开始执行,然后等到子组件执行完,父组件收尾。

8.Vue实现数据双向绑定的原理。

Vue实现数据双向绑定的原理:结合发布-订阅模式,通过ES5新增的Object.defineProperty()方法劫持各个属性的setter和getter,Observer监听数据的变动。

下面是一个极简数据双向绑定的实现。

<input type='text' id='test'>
<span id='spa'></span>
<script>
    let obj = {};
    Object.defineProperty(obj,'hello',{
        set:function(newVal){
            document.getElementById('test').value = newVal;
            document.getElementById('spa').innerHTML= newVal;
        }
    });
    document.addEventListener('keyup',function(e){
        obj.hello = e.target.value
    })
</script>

9.Vue的两种路由模式和实现原理

Vue有hash和history两种路由模式。

history和hash的的对比: - history比hash的url美观(没有’#'号) - history修改的url可以是同域的任意url,hash则只能是同文档的url - history模式往往需要后端支持,如果后端nginx没有覆盖路由地址,就会返回404,hash因为是同文档的url,即使后端没有覆盖路由地址,也不会返回404。 - hash模式下,如果把url作为参数传后端,那么后端会直接从’#‘号截断,只处理’#'号前的url,因此会存在#后的参数内容丢失的问题,不过这个问题hash模式下也有解决的方法。

10.谈谈你对keep-alive的了解。

keep-alive顾名思义,保持活跃。就是可以保持组件的状态。keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁。

keep-alive可以实现组件的缓存,当组件切换时不会对当前组件进行卸载,常用的2个属性include / exclude,2个生命周期 activated , deactivated LRU算法,缓存组件,不需要重复渲染时 如多个静态Tab页切换。

注意:使用了keep-alive后,生命周期会增加 activated 和 deactivated两个方法。 初次执行组件时:created > mounted > activated;退出后触发 deactivated。 再次执行组件时:会触发 activated;事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在activated中。