前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript从初级往高级走系列————MVVM-Vue

JavaScript从初级往高级走系列————MVVM-Vue

作者头像
FinGet
修改2019-07-03 18:02:38
4880
修改2019-07-03 18:02:38
举报
文章被收录于专栏:FinGet前端之路FinGet前端之路

MVVM

  • 如何理解 MVVM
  • 如何实现 MVVM
  • 是否解读过 Vue 的源码

Jquery 与 框架的区别

jquery 实现 todo-list
代码语言:javascript
复制
<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://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
    var $txtTitle = $('#txt-title');
    var $btnSubmit = $('#btn-submit');
    var $ulList = $('#ul-list');
    $btnSubmit.click(function () {
        var title = $txtTitle.val();
        if (!title) {
            return
        }
        var $li = $('<li>' + title + '</li>');
        $ulList.append($li);
        $txtTitle.val('');
    })
</script>
vue 实现 todo-list
代码语言:javascript
复制
<div id="app">
  <div>
    <input v-model="title">
    <button v-on:click="add">submit</button>
  </div>
  <div>
    <ul>
      <li v-for="item in list">{{item}}</li>
    </ul>
  </div>
</div>

<script type="text/javascript">
  // data 独立
  var data = {
      title: '',
      list: []
  }
  // 初始化 Vue 实例
  var vm = new Vue({
      el: '#app',
      data: data,
      methods: {
          add: function () {
              this.list.push(this.title);
              this.title = '';
          }
      }
    })
</script>
两者的区别
  • 数据和视图的分离,解耦(开放封闭原则,对扩展开放,对修改封闭) 在jQuery中在jQuery代码中操作视图和数据,混在一块了
  • 以数据驱动视图,只关心数据变化,DOM操作被封装 只改数据,视图自动更新

MVVM的理解

  • MVC (Model View Controller)

  • MVVM (Model View ViewModel)

View 通过 事件绑定 (DOM Listeners) 操作Model; Model通过 数据绑定 (Data Bindings)操作View。

Vue 三要素

  • 响应式: Vue 如何监听到 data 的每个属性变化?
  • 模板引擎: Vue 的模板如何被解析,指令如何处理?
  • 渲染:Vue 的模板如何被渲染成Html?

Vue中如何实现响应式

什么是响应式
  • 修改 data 属性之后, Vue 立刻监听到
  • data 属性被代理到 vm上
代码语言:javascript
复制
var vm = new Vue({
  el: '#app',
  data: {
    name: 'zhangsan',
    age: 20
  }
})
// vm.name = 'zhangsan'
// vm.age = '20'
Object.defineProperty,Vue核心函数
代码语言:javascript
复制
var obj = {
  name: 'zhangsan',
  age: 25
}
console.log(obj.name); // 获取属性的时候,如何监听
obj.age = 26; // 赋值属性的时候,如何监听

上面是无法监听对象的属性的访问以及赋值操作的,直接就产生了操作的结果。

代码语言:javascript
复制
var obj = {}
var _name = 'shangsan'
Object.defineProperty(obj, 'name', {
  get: function () {
    console.log('get', _name) // 监听
    return _name
  },
  set: function (newVal) {
    console.log('set', newVal)  // 监听
    _name = newVal
  }
})
console.log(obj.name); // 可以监听到
obj.name = 'lisi'; // 可以监听到

Vue 中何如解析模板

模板是什么
代码语言:javascript
复制
<div id="app">
  <div>
    <input v-model="title">
    <button v-on:click="add">submit</button>
  </div>
  <div>
    <ul>
      <li v-for="item in list">{{item}}</li>
    </ul>
  </div>
</div>
  • 本质: 字符串
  • 有逻辑, 如v-if v-for
  • 与 html 标签格式很像,但有很大区别(html是静态的,模板是动态的)
  • 最终还要转换为 html 来显示
    • 模板最终必须转换成 JS 代码
    • 有逻辑(v-if v-for 等),必须用JS才能实现(图灵完备)
    • 因此,模板最重要转成一个JS函数(render函数)
render函数
with – 实际开发不推荐用
代码语言:javascript
复制
var obj = {
  name: 'zhangsan',
  age: 20,
  getAddress: function () {
    alert('beijing')
  }
}
// 不使用with
function fn() {
  alert(obj.name)
  alert(obj.age)
  obj.getAddress()
}
fn()

// 使用with
function fn1() {
  with(obj) {
    alert(age)
    alert(name)
    getAddress()
  }
}
fn1()
render
代码语言:javascript
复制
<div id="app">
  <p>{{price}}</p>
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
	  price: 100
    }
  })
</script>

模板将变成下面这个样子:

代码语言:javascript
复制
function render() {
  with(this) {  // this 就是 vm
	return _c(
	  'div',
	  {
	    attrs: {'id': 'app'}
	  },
	  [
	    _c('p', [_v(_s(price))])
	  ]
	)
  }
}

看todo-list的render

在vue源码里alert render 函数:

以上面vue实现的todolist为例:

代码语言:javascript
复制
with(this){  // this 就是 vm
    return _c( // _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('div',
               [
                _c(
                    'ul',
                    _l((list),function(item){return _c('li',[_v(_s(item))])}) // _l 解析 v-for 循环
                )
            ]
          )
        ]
    )
}
render 与 Vdom

可以先看一下virtualDom

  • vm._c 其实相当于 snabbdom 中的 h 函数
  • render 函数执行之后,返回的是 vnode

  • updateComponent 中实现了 vdom 的 patch
  • 页面首次渲染 执行updateComponent
  • data 中每次修改属性, 执行 updateComponent
vue 的整个实现流程
  • 第一步: 解析模板成render函数
    • with 的用法
    • 模板中的所有信息都被render函数包含
    • 模板中用到的data中的属性,都变成了js变量
    • 模板中的v-model v-if v-on 都变成了 js逻辑
    • render 函数返回 vnode

  • 第二部: 响应式开始监听
    • Object.defineProperty
    • 将 data 的属性代理到 vm 上

  • 第三步: 首次渲染,显示页面,且绑定依赖

  • 第四步: data 属性变化,触发 rerender
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-05-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MVVM
    • Jquery 与 框架的区别
      • jquery 实现 todo-list
      • vue 实现 todo-list
      • 两者的区别
    • MVVM的理解
    • Vue 三要素
      • Vue中如何实现响应式
        • 什么是响应式
        • Object.defineProperty,Vue核心函数
      • Vue 中何如解析模板
        • 模板是什么
        • render函数
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档