实现简单的数据绑定和渲染

目标

指定一个Vue实例,可以渲染出对应的HTML,并且当数据变动时重新渲染。
例如:

let app = new Vue({
  el: '#app',
  data: {
    user: {
      name: 'youngwind',
      age: 25,
      location: {
        province: 'GD',
        city: 'GZ'
      },
      school: 'bupt',
      major: 'computer'
    }
  }
})
  

姓名:{{user.name}}

年龄:{{user.age}}

省份:{{user.location.province}}

城市:{{user.location.city}}

结果如下:

实现简单的数据绑定和渲染_第1张图片
结果

思路

  1. 根据el属性找到对应的根元素
  2. 记录原HTML。
  3. 使用正则表达式找到需要替换的部分,然后根据data属性对{{}}内的字符串进行求值。把修改后的HTML赋值回去。
  4. 监视数据的变动,如果数据有改变,就重复上一步。

其中前几步实现都不难,最主要的部分就是第四步。
这里需要实现一个Observer类,它接受一个对象作为监视的值。然后当对象产生变化时,需要发出消息。

怎么发出消息?

  • 实现一个EventHandler类,有一个属性$listeners,2个函数$on$emit,前者对于某个事件把指定的函数存入对应的监听器中,后者对于某个事件调用其对应的所有监听器。(发布-订阅模式)

怎么监视属性的修改?

  • 遍历对象的每个属性,使用Object.defineProperty设置属性的getter,如果值改变了就调用$emit方法。

如果对象内还嵌套对象怎么办?

  • 使用递归的方法,遍历每个对象的每个属性(实际做的时候没考虑继承的),如果属性是一个对象则继续new Observer

如果属性修改后的值是对象怎么办?

  • 检测属性修改后的类型,如果是对象则也要new Observer

内层属性的修改如何传递到上层?

  • 例如user.location是一个对象,为location的每个属性$on一个函数,内容是在user$emit location,这样就实现了层层上传。

样例地址

https://github.com/huhk-sysu/ife-study/blob/master/vue/hw5/hw5.js

你可能感兴趣的:(实现简单的数据绑定和渲染)