美文网首页Web前端之路让前端飞
亲手实现一个简单的类 Vue 框架(一) —— 数据的绑定

亲手实现一个简单的类 Vue 框架(一) —— 数据的绑定

作者: ac68882199a1 | 来源:发表于2017-04-16 21:56 被阅读244次

作者公司最近的几个项目全都选用了 Vue.js 作为基础框架,相信也有很多小伙伴已经接触过使用过尤大大的 Vue.js 了。相对来说,Vue 的 api 简洁明了,易于上手使用,效率也高,作者也已经开始在自己的项目中使用了

那么这次的主题就是亲手实现一个简单的类 Vue 框架,虽然是简单的,但是也是会分成好几篇来写哦。下面就进入这一篇的正题——数据的绑定与监听

Vue 中的数据是通过下面这种形式绑定到 Vue 实例中的:

    var v = new Vue({
         el: '#page',
         data: {
             name: 'xiaoming',
             age: 18
         },
         ready: function () {
             console.log(this.name)
             console.log(this.age)
         }
     })

    console.log(v.name)
    console.log(v.age)

向 Vue 中传入一个对象,这个对象需要包含一个 data 属性,data 属性的值可以是对象,也可以是一个函数,如果是函数的话,需要返回一个对象

之后 Vue 会将 data 内的数据绑定到它的实例v上,我们就可以通过v.property或者在实例v中通过this.property.访问到data上的属性

ready函数是一个 Vue 实例化完成后自动调用的函数

通过上面的思路,我们开始自己实现这个看上去很简单的功能

数据如何绑定到当前实例

首先给我们的类 Vue 框架去个名字,叫 Lue (like vue),Lue 的使用的方式与 Vue 相同

    var l = new Lue({
         data: {
             name: 'xiaohong',
             age: 17
         },
         ready: function () {
             console.log(this.name)
             console.log(this.age)
         }
     })

在实例化 Lue 之前首先定义 Lue,并且实现在实例化后自动执行ready函数

    function Lue(opts) {
           // 如果 ready 属性是一个函数的话 则执行
         if (typeof opts.ready === 'function') {
             opts.ready()
         }
     }

以上代码运行后控制台输出如下:

undefined
undefined

为什么在执行ready后,nameage两个属性都是undefined呢?要搞清楚这个问题,我们可以先在ready中把this打印出来

打印出来后,我们会发现,readythis指向的是我们实例化 Lue 时传入的这个对象,而这个对象上并没有nameage的属性

这就出现了一个需要解决的问题:

我们需要this指向当前的实例l,而不是传入的对象

看过之前那篇 前端面试题——call与apply方法的异同 的小伙伴应该知道这里要怎么做了

    function Lue(opts) {
           // 如果 ready 属性是一个函数的话 则执行
         if (typeof opts.ready === 'function') {
               // 将 ready 方法绑定到当前的 Lue 实例 l 上,即 this
             opts.ready.call(this)
         }
     }

运行更改过的代码,控制台打印如下:

undefined
undefined

诶?我都已经把 ready 的执行环境绑定到 l上了为什么还是两个undefined呢?

继续找原因,继续打印当前的this,我们会发现现在的this指向已经没问题了,但是l上并没有nameage,这两个属性也是需要我们手动绑定到l上的!

     function Lue(opts) {
         // 声明一个变量 $data 用来就收 opts.data
         // $data 并不是必须的 :)你高兴就好
         var $data, dataType = typeof opts.data

         // 简单校验 opts.data 的类型
         if (dataType === 'function') {
             $data = opts.data()
         } else if (dataType === 'object') {
             $data = opts.data
         }

         // 简单粗暴的将 $data 的属性绑定到 this 上
         for (var key in $data) {
             this[key] = $data[key]
         }

           // 如果 ready 属性是一个函数的话 则执行
         if (typeof opts.ready === 'function') {
               // 将 ready 方法绑定到当前的 Lue 实例 l 上,即 this
             opts.ready.call(this)
         }
     }

控制台打印内容:

"xiaohong"
17

到这里,我们就已经将data属性中的数据绑定到实例l上了,如果在控制台打印this的话,会将包含data中所有数据的l完整打印出来

嗯,细心地小伙伴看到这里一定会觉得上面的代码很不严谨,有很多问题:

如果 data的值不是一个对象或函数怎么办呢?
如果data中的某一个值是函数怎么办呢?

别急,这些问题我们在下一篇一起解决

嗯,先做个预告,下一篇的题目是数据的监听,感兴趣的小伙伴可以自己先了解下哦!(嗯,这篇有点短,小伙伴们不要介意啊,周末两天一直在考试,还请见谅!:)

扫码关注前端周记公众号

相关文章

网友评论

    本文标题:亲手实现一个简单的类 Vue 框架(一) —— 数据的绑定

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