根据Object.defineProperty 获取对象中属性值与属性值改变时的触发时机
let obj = {};let userName = "rock"Object.defineProperty(obj, 'userName', {get() {// 添加依赖return userName;},set(newVal) {// 更新依赖console.log(newVal, 'setter')userName = newVal;}})obj.userName"rock"obj.userName = '12'12 setter"12"
极简版的Vue
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div class="app"><h3>极简版vue</h3><div class="userName">{{userName}}</div><div class="description">{{description}}</div><input type="text" v-modal="userName" /><input type="text" v-modal="description" /></div></body><script src="./1.js"></script><script>window.onload = function () {let app = new Vue({el: '.app',data: {userName: '我是rock++',description: '前端技术学习',},});};</script></html>
let targetNodes = [];let target = null;function defineReactive(data) {Object.keys(data).forEach(key => {let val = data[key];let dep = new Dependence();Object.defineProperty(data, key, {get() {// 添加依赖dep.push();targetNodes.push(val)return val},set(newVal) {dep.notify(newVal)val = newVal;}})})return data}class Dependence {static target = null;targetNodes = [];push() {if (Dependence.target) {this.targetNodes.push(Dependence.target)}}notify(value) {console.log(value, this)this.targetNodes.forEach(node => {node.textContent = value})}}function compile(data, template) {let children = template.children;for (let i = 0; i < children.length; i++) {let childEl = children[i];if (childEl.matches("[v-modal]")) {let attr = childEl.getAttribute("v-modal");childEl.value = data[attr];childEl.addEventListener("input", function (ev) {data[attr] = ev.target.value})} else {const content = childEl.textContent;const regexp = /{{(.+?)\}\}/;const match = content?.match(regexp);if (match) {const key = match[1];Dependence.target = childEl;childEl.innerText = data[key]Dependence.target = null}}}}class Vue {constructor({ el, data }) {let templateNode = document.querySelector(el);const observeableData = defineReactive(data);console.log(observeableData, 'observeableData')compile(observeableData, templateNode);console.log(Dependence.targetNodes, '>targetNodes>')}}
