123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- //-----------------数据挟持Observer--------
- //-----------------数据渲染Compile---------
- //-----------------数据订阅Pubsub----------
-
-
-
-
- class Observer{
- constructor(data, sub) {
- this.sub = sub
- this.data = data
- for(let key in data) {
- this._listen(data, key, data[key])
- }
- }
- _listen(obj, key, val) {
- this.dataProxy = new Proxy(obj, {
- get: (t, name) => {
- console.log("get===>", name, ":", t[name])
- return t[name]
- },
- set: (t, name, newVal) => {
- console.log("set===>", name, ":", newVal)
- t[name] = newVal
- this.sub.public(name, newVal)
- return true
- },
- })
- }
- }
-
- class MyVue {
- constructor(options) {
- const {el, data} = options;
- this.el = document.querySelector(el)
- // 订阅者注册
- this.sub = new Pubsub()
-
- // 数据挟持
- const vm = new Observer(data, this.sub)
- this.vm = vm.dataProxy
-
- // 数据渲染
- this.compile = new Compile(this.el, this.vm, this.sub)
- this.flag = this.compile.createFlag()
- this.el.appendChild(this.flag)
- }
- }
-
- class Compile {
- constructor(el, vm, sub) {
- this.el = el
- this.vm = vm
- this.sub = sub
- }
- createFlag() {
- let flag = document.createDocumentFragment()
- let child;
- while(child = this.el.firstChild) {
- this.compile(child)
- flag.appendChild(child)
- }
- return flag
- }
- compile(node) {
- switch(node.nodeType){
- case 1: // element
- const reg = /\{\{(.*)\}\}/;
- if(reg.test(node.textContent)) {
- let name = RegExp.$1;
- node.textContent = this.vm[name]
- this.sub.subscribe(name, (newVal) => {
- node.textContent = newVal
- })
- }
- let attr = node.attributes
- if(attr.hasOwnProperty('x-model')){
- let name = attr['x-model'].nodeValue
- node.value = this.vm[name]
- const self = this
- node.addEventListener('input', (e) => {
- self.vm[name] = e.target.value
- })
- this.sub.subscribe(name, (newVal) => {
- if(node.value !== newVal)
- node.value = newVal
- })
- }
- break;
- case 3: // text
- break;
- default:
- console.log("no nodetype")
- }
- }
- }
-
- class Pubsub{
- constructor(){
- this.subs = {}
- }
- // 订阅者注册
- subscribe(name, func) {
- this.subs[name] = this.subs[name] ? this.subs[name] : []
- this.subs[name].push(func)
- }
- // 发布
- public(name, args) {
- console.log(this.subs[name])
- if(!this.subs[name]) return;
- this.subs[name].map(func => func(args))
- }
- }
|