美文网首页
前端面试之MVVM 和 Vue

前端面试之MVVM 和 Vue

作者: 小雪狸 | 来源:发表于2020-09-11 16:04 被阅读0次

++本文系慕课网学习笔记++

如何理解 MVVM

如何实现 MVVM

是否解读过 vue 的源码(vue 中的 xx 功能是怎么实现的,重点是流程)

说一下使用 jquery 和使用框架的区别?

  1. 数据和视图的分离,解耦(开放封闭原则)
  2. 以数据驱动视图,只关心数据变化,DOM 操作被封装
// jQuery 实现 todoList
<div>
  <input type="text" name="" id="txt-title">
  <button id="btn-submit">submit</button>
</div>
<div>
  <ul id="ul-list"></ul>
</div>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
var $txtTitle = $('#txt-title');
var $ulList = $('#ul-list');
var $btnSubmit = $('#btn-submit');
$btnSubmit.click(function() {
  var title = $txtTitle.val();
  if (!title) {
      return;
  }
  var $li = $('<li>' + title + '</li>');
  $ulList.append($li);
  $txtTitle.val('');
})
</script>
  // vue 实现 todo-list
  <div id="app">
    <div>
      <input v-model="title">
      <button @click="add">submit</button>
    </div>
    <ul>
      <li v-for="(item, index) in list" :key="index">{{ item }}</li>
    </ul>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.0.0/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        title: '',
        list: []
      },
      methods: {
        add: function() {
          if (this.title) {
            this.list.push(this.title);
          }
          this.title = '';
        }
      }
    })
  </script>

说一下对 MVVM 的理解?

解答思路

  1. MVVM - Model View ViewModel(View 通过 事件绑定 影响 Model, Model 通过 数据绑定 影响 View)
  2. 三者之间的联系,以及如何对应到各段代码
  3. ViewModel 的理解, 联系 View 和 Model

Vue 三要素

  1. 响应式:vue 如何监听到 data 的每个属性的变化
  2. 模板引擎:vue 的模板如何被解析,指令如何处理
  3. vue 的模板如何被渲染成 html,以及渲染过程

vue 中如何实现响应式?

解答思路:

  1. 关键是理解 Object.defineProperty
  2. 将 data 的属性代理到 vm 上

什么是响应式

  1. 修改 data 属性后,vue 立刻监听到
  2. data 属性被代理到 vm 上

Object.defineProperty

var obj = {
    name: 'zhangsan',
    age: 25
}
console.log(obj.name)  // 获取属性的时候如何监听到?
obj.age = 26           // 赋值属性的时候如何监听到?
var obj = {}
var name = 'zhangsan'
Object.defineProperty(obj, 'name', {
    get: function() {
        console.log('get')
        return name
    },
    set: function(newVal) {
        console.log('set')
        name = newVal
    }
})
console.log(obj.name)
obj.name = 'lisi'

模拟

// var vm = new Vue({
//     el: '#app',
//     data: {
//        price: 100,
//        name: 'zhangsan'
//     }
// })

var vm = {}
var data = {
    price: 100,
    name: 'zhangsan'
}

var key, value
for (key in data) {
    // 闭包,保证 key 的独立作用域
    (function(key) {
        Object.defineProperty(vm, key, {
            get: function() {
                return data[key]
            },
            set: functioon(newVal) {
                data[key] = newVal
            }
        })
    })(key)
}

vue 如何解析模板?

解答思路:

  1. 模板:字符串。有逻辑,嵌入 JS 变量
  2. 模板必须转换为 JS 代码(有逻辑,渲染 html, JS 变量)
  3. render 函数是什么样子的
  4. render 函数执行返回 vnode
  5. updateComponent

模板是什么

  1. 本质:字符串
  2. 有逻辑,如 v-if v-for 等
  3. 与 html 格式很像,但有很大区别

==模板最终必须转换成 JS 代码;因为有逻辑,必须用 JS 才能实现;转换为 html 渲染页面,必须用 JS 才能实现;模板最终要转换成一个 JS 函数(render 函数)==

<div id="app">
<div>
  <input v-model="title">
  <button @click="add">submit</button>
</div>
<ul>
  <li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
</div>

render 函数

  1. 模板中所有信息都包含在了 render 函数中
  2. this 即 vm
  3. price 即 this.price,即 vm.price,即 data.price
  • with 的用法
// 不用 with
function fn() {
    alert(obj.name)
    alert(obj.age)
    obj.add()
}

// 使用 with
function fn1() {
    with(obj) {
        alert(name)
        alert(age)
        add()
    }
}




<div id="app">
    <p>{{ price }}</p>
</div>
// this 就是 vm 实例
function render() {
    with(this) {
        return _c(
            'div',
            {
                attrs: {'id': app''}
            },
            [
                _c('p', [_v(_s(price))])
            ]
        )
    }
}

  • 从哪里可以看懂 render 函数?
    • 搜索 code.render
  • 复杂一点的例子,render 函数是什么样子的?
with(this){
    return _c(
        'div',
        {attrs:{"id":"app"}},
        [_c(
                'div',
                [_c(
                    'input',
                    {
                        directives:[{name:"model",
                            rawName:"v-model",
                            value:(title),
                            expression:"title"
                            
                        }],
                        domProps:{
                        "value":(title)
                            
                        },
                        on:{
                            "input":function($event){
                                if($event.target.composing)
                                return;title=$event.target.value
                                
                            }
                            
                        }
                        
                    }),
                    _v(" "),
                    _c(
                        'button',
                        {
                            on:{"click":add}
                            
                        },
                        [_v("submit")]
                    )
                ]),
                _v(" "),
                _c(
                    'ul',
                    _l((list),function(item,index){
                        return _c(
                            'li',
                            {
                                key:index
                                
                            },
                            [
                                _v(_s(item))
                            ]
                        )            
                    }
                )
            )
        ]
    )    
}
  • v-if v-for v-on 都是怎么处理的?

render 函数与 vdom

  • updateComponent 中实现了 vdom 的patch
  • 页面首次渲染执行 updateComponent
  • data 每次修改属性,执行 updateComponent
vm._update(vnode) {
    const preVnode = vm._vnode
    vm._vnode = vnode
    if (!perVnode) {
        vm.$el = vm.__patch__(vm.$el, vnode)
    } else {
        vm.$el = vm.__patch__(preVnode, vnode)
    }
}

function updateComponent() {
    // vm._render 即上面的 render 函数, 返回 vnode
    vm._update(vm._render())
}

vue 的整个实现流程?(几个核心的部分,和他们之间的关系)

  • 第一步:解析模板成 render 函数

    • with 的用法
    • 模板中的所有信息都被 render 函数包含
    • 模板中用到的 data 中的属性,都变成了 JS 变量
    • 模板中的 v-model v-for v-on 都变成了 JS 逻辑
    • render 函数返回 vnode
  • 第二步:响应式开始监听

    • Object.defineProperty
    • 将 data 的属性代理到 vm 上
  • 第三步:首次渲染,显示页面,且绑定依赖

    • 初次渲染,执行 updateComponent,执行 vm_render()
    • 执行 render 函数,会访问到 vm.list 和 vm.title
    • 会被响应式的 get 方法监听到
    • 执行 updateComponent,会走到 vdom 的 patch 方法
    • patch 将 vnode 渲染成 DOM,初次渲染完成

为什么要监听 get,直接监听 set 不行吗?

  1. data中有很多属性,有些被用到,有些可能不被用到
  2. 被用到的会走 get,不被用到的不会走 get
  3. 未走到 get 的属性,set 的时候我们也无需关心
  • 第四步:data 属性变化,触发 rerender
    • 修改属性,会被 set 监听到
    • set 中执行 updateComponent
    • updateComponent 重新执行vm_render()
    • 生成的 vnode 和 prevVnode,通过 patch 进行对比
    • 渲染到 html 中

相关文章

  • 前端面试资料收集

    vue相关知识 前端面试题+前端学习+面试指南 剖析Vue原理&实现双向绑定MVVM 详解 JavaScript的...

  • 前端面试之MVVM 和 Vue

    ++本文系慕课网学习笔记++ 如何理解 MVVM 如何实现 MVVM 是否解读过 vue 的源码(vue 中的 x...

  • MVVM在前端(web)使用

    前端框架vue,MVVM模式 今天咱们不谈iOS,说说web(MVVM模式)。MVVM模式在前端开发应该还是挺多的...

  • VueKotlin 轻量框架

    VueKotlin 简单,高效,迅速。借鉴前端框架Vue API,面向协议编程,MVVM模式,对Activity和...

  • 初识Vue2.* - 与PhpSpreadsheet的小demo

    Vue.js 一个流行的MVVM前端框架,数据驱动思想使得前端开发易于理解和维护。PHPSpreadsheet 提...

  • VUE阶段性总结

    Vue是一个MVVM框架,这里的MVVM指的仅仅是前端,和后端无关。在MVVM框架中,视图和数据不能直接通信,而是...

  • 无标题文章

    说明 整体技术架构 采用了MVVM前端框架 vue.js vue.js + vue-router + vue-re...

  • Vue面试题(第一版)

    Vue面试题(第一版) vue设计模式(MVVM) MVVM是 Model-View-ViewModel的缩写。m...

  • MVVM及Vue渲染机制探索

    MVVM - Model View ViewModel 总所周知,Vue是目前比较流行的MVVM前端框架,其核心在...

  • vue面试题之二:路由 vue-router 面试题

    2. vue路由面试题 1. mvvm框架是什么? mvvm即Model-View-ViewModel,mvvm的...

网友评论

      本文标题:前端面试之MVVM 和 Vue

      本文链接:https://www.haomeiwen.com/subject/bckbektx.html