1/* eslint-disable */ 2import Watcher from './watcher'; 3import Dep from './dep'; 4import { 5 observe, 6 proxy 7} from './observer'; 8import { 9 isPlainObject, 10 hasOwn 11} from '../../utils/index.ts'; 12 13export function initState (vm) { 14 vm._watchers = []; 15 initData(vm); 16 initComputed(vm); 17 initMethods(vm); 18} 19 20export function initData (vm) { 21 let data = vm.__data; 22 initDataSegment(vm, data); 23 let shareData = vm.__shareData; 24 initDataSegment(vm, shareData); 25} 26 27export function initDataSegment (vm, data) { 28 if (!isPlainObject(data)) { 29 data = {}; 30 } 31 32 // Proxy data on page. 33 const keys = Object.keys(data); 34 let i = keys.length; 35 while (i--) { 36 proxy(vm, keys[i], data); 37 } 38 // Observe data. 39 observe(data, vm); 40} 41 42export function initBases(vm) { 43 const options = vm.__vmOptions 44 // mixins exist? 45 if(hasOwn(options, 'mixins')) { 46 options['mixins'].forEach(mixin => { 47 if(typeof mixin == 'object') { 48 Object.keys(mixin).forEach(key => { 49 vm[key] = mixin[key] 50 }) 51 } 52 else if (typeof mixin == 'function') { 53 vm[mixin.name] = mixin.bind(vm) 54 } 55 else { 56 aceConsole.error("[JS Framework] mixin must be plain object or function") 57 } 58 }) 59 } 60} 61 62function noop () { 63} 64 65export function initComputed (vm) { 66 const computed = vm.__computed; 67 if (computed) { 68 for (let key in computed) { 69 const userDef = computed[key]; 70 const def = { 71 enumerable: true, 72 configurable: true 73 }; 74 if (typeof userDef === 'function') { 75 def.get = makeComputedGetter(userDef, vm); 76 def.set = noop; 77 } else { 78 def.get = userDef.get 79 ? userDef.cache !== false 80 ? makeComputedGetter(userDef.get, vm) 81 : userDef.get.bind(vm) 82 : noop; 83 def.set = userDef.set 84 ? userDef.set.bind(vm) 85 : noop; 86 } 87 Object.defineProperty(vm, key, def); 88 } 89 } 90} 91 92function makeComputedGetter (getter, owner) { 93 const watcher = new Watcher(owner, getter, null, { 94 lazy: true 95 }); 96 return function computedGetter () { 97 if (watcher.dirty) { 98 watcher.evaluate(); 99 } 100 if (Dep.target) { 101 watcher.depend(); 102 } 103 return watcher.value; 104 } 105} 106 107export function initMethods (vm) { 108 const options = vm.__vmOptions; 109 for (let key in options) { 110 if (typeof options[key] === 'function' && key !== 'data') { 111 vm._methods[key] = options[key].bind(vm); 112 proxyMethods(vm, key); 113 } 114 } 115} 116 117function proxyMethods(vm, key) { 118 Object.defineProperty(vm, key, { 119 configurable: true, 120 enumerable: true, 121 get: function proxyGetter () { 122 return vm.__methods[key]; 123 }, 124 set: function proxySetter(newValue) { 125 vm.__methods[key] = typeof newValue === 'function' && key !== 'data' ? 126 newValue.bind(vm) : newValue; 127 } 128 }) 129} 130