VUE的面试总结(一)

1,808 阅读2分钟

总览

  1. v-if和v-for哪个优先级更高?如果两个同时出现,应该怎么优化得到更高的性能?
  2. vue组件data为什么必须是个函数而Vue的根实例则没有此限制?
  3. 你知道vue中key的作用和工作原理吗
  4. 怎么理解vue中diff算法
  5. 谈一谈对vue组件化的理解
  6. 谈一谈对vue设计原则的理解
  7. 探探对MVC、MVP和MVVM的理解

开始

  • v-if和v-for哪个优先级更高?如果两个同时出现,应该怎么优化得到更高的性能?

    源码:compiler/codegen/index.js

    <p v-for="item in items" v-if="condition">
    
    <!DOCTYPE html> 
    <html>
      <head> 
       <title>Vue事件处理</title> 
      </head> 
    <body> 
    <div id="demo">
    <h1>v-if和v-for哪个优先级更高应该如何正确使用避免性能问题</h1>
    <!-- <p v-for="child in children" v-if="isFolder">{{child.title}}</p> --> 
    <template v-if="isFolder">
    	<p v-for="child in children">{{child.title}}</p>
    </template>
    </div>
    <script src="../../dist/vue.js">		</script> 
    <script>
     const app = new Vue({ 
     	el: '#demo', 
        data(){
        	return{
            	children:[
                	{title:'foo'},
                    {title:'bar'}
                ]
            }
        },
        computed:{
        	isFplder(){
            	return this.children && this.children.length;
            }
        }
        console.log(app.$options.render)
    </script>
    </body>
    </html>
    

    两者同级时,渲染函数如下

    	(function anonymous() { 
      with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("v-for和v-if谁的优先 级高?应该如何正确使用避免性能问题?")]),_v(" "), _l((children),function(child){return (isFolder)?_c('p',[_v(_s(child.title))]):_e()})],2)}}) 
    

    两者不同级时,渲染函数如下

    (function anonymous( ) { with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("v-for和v-if谁的优先 级高?应该如何正确使用避免性能问题?")]),_v(" "), (isFolder)?_l((children),function(child){return _c('p', [_v(_s(child.title))])}):_e()],2)}}) 
    

    结论

    • 显然v-for优先于v-if被解析(把你是怎么知道的告诉面试官)
    • 如果同时出现,每次渲染都会先执行循环再判断条件,无论如何循环都不可避免,浪费了性能
    • 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判断,然后在内部进行v-for循环
    • 如果条件出现在循环内部,可通过计算属性提前过滤掉那些不需要显示的项

  • Vue组件data为什么必须是个函数而Vue的根实例则没有此限制?

    源码:src\core\instance\state.js - initData() 函数每次执行都会返回全新data对象实例

    	<!DOCTYPE html>
        	<html>
            <head> 
                <title>Vue事件处理</title>
            </head>
            <body>
            
    	 <div id="demo">
               <h1>vue组件data为什么必须是个函数? </h1> 
               <comp></comp>
               <comp></comp>
    	</div>
        <script src="../../dist/vue.js"></script>
        <script>
          Vue.component('comp', {
              template:'<div @click="counter++">{{counter}}</div>',
              data: {counter: 0}
           })
           // 创建实例
           const app = new Vue({
            el: '#demo',
        	});
    </script>
    </body>
    </html>
    

    程序甚至无法通过vue检测

    • 结论

      Vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们共用一个data对象,那么状态 变更将会影响所有组件实例,这是不合理的;采用函数形式定义,在initData时会将其作为工厂函数返 回全新data对象,有效规避多实例之间状态污染问题。而在Vue根实例创建过程中则不存在该限制,也是因为根实例只能有一个,不需要担心这种情况。

    后续持续更新中....