{"id":3223,"date":"2021-04-12T10:48:57","date_gmt":"2021-04-12T02:48:57","guid":{"rendered":"http:\/\/www.yuguoxy.com\/geekhome\/?p=3223"},"modified":"2021-04-12T10:48:57","modified_gmt":"2021-04-12T02:48:57","slug":"vue-%e5%93%8d%e5%ba%94%e5%bc%8f%e5%8e%9f%e7%90%86%e6%a8%a1%e6%8b%9f","status":"publish","type":"post","link":"https:\/\/ai.zhousir.top\/?p=3223","title":{"rendered":"Vue \u54cd\u5e94\u5f0f\u539f\u7406\u6a21\u62df"},"content":{"rendered":"<h2>\u4e00\u3001\u4e09\u4e2a\u6982\u5ff5<\/h2>\n<h3>1. \u6570\u636e\u9a71\u52a8<\/h3>\n<ul>\n<li><strong>\u6570\u636e\u54cd\u5e94\u5f0f<\/strong>\n<ul>\n<li>\u6570\u636e\u6a21\u578b\u4ec5\u4ec5\u662f\u666e\u901a\u7684 JavaScript \u5bf9\u8c61\uff0c\u800c\u5f53\u6211\u4eec\u4fee\u6539\u6570\u636e\u65f6\uff0c\u89c6\u56fe\u4f1a\u8fdb\u884c\u66f4\u65b0\uff0c\u907f\u514d\u4e86\u7e41\u7410\u7684 DOM \u64cd\u4f5c\uff0c\u63d0\u9ad8\u5f00\u53d1\u6548\u7387<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u53cc\u5411\u7ed1\u5b9a<\/strong>\n<ul>\n<li>\u6570\u636e\u6539\u53d8\uff0c\u89c6\u56fe\u6539\u53d8\uff1b\u89c6\u56fe\u6539\u53d8\uff0c\u6570\u636e\u4e5f\u968f\u4e4b\u6539\u53d8<\/li>\n<\/ul>\n<ul>\n<li>\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 v-model \u5728\u8868\u5355\u5143\u7d20\u4e0a\u521b\u5efa\u53cc\u5411\u6570\u636e\u7ed1\u5b9a<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u6570\u636e\u9a71\u52a8\u662f Vue \u6700\u72ec\u7279\u7684\u7279\u6027\u4e4b\u4e00<\/strong>\n<ul>\n<li>\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u4ec5\u9700\u8981\u5173\u6ce8\u6570\u636e\u672c\u8eab\uff0c\u4e0d\u9700\u8981\u5173\u5fc3\u6570\u636e\u662f\u5982\u4f55\u6e32\u67d3\u5230\u89c6\u56fe<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>2. \u6570\u636e\u54cd\u5e94\u5f0f\u6838\u5fc3\u539f\u7406<\/h3>\n<ul>\n<li><strong>Vue 2.x<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u6a21\u62df Vue \u4e2d\u7684 data \u9009\u9879\r\nlet data = {\r\n    msg: 'hello'\r\n}\r\n\/\/ \u6a21\u62df Vue \u7684\u5b9e\u4f8b\r\nlet vm = {}\r\n\/\/ \u6570\u636e\u52ab\u6301\uff1a\u5f53\u8bbf\u95ee\u6216\u8005\u8bbe\u7f6e vm \u4e2d\u7684\u6210\u5458\u7684\u65f6\u5019\uff0c\u505a\u4e00\u4e9b\u5e72\u9884\u64cd\u4f5c\r\nObject.defineProperty(vm, 'msg', {\r\n    \/\/ \u53ef\u679a\u4e3e\uff08\u53ef\u904d\u5386\uff09\r\n    enumerable: true,\r\n    \/\/ \u53ef\u914d\u7f6e\uff08\u53ef\u4ee5\u4f7f\u7528 delete \u5220\u9664\uff0c\u53ef\u4ee5\u901a\u8fc7 defineProperty \u91cd\u65b0\u5b9a\u4e49\uff09\r\n    configurable: true,\r\n    \/\/ \u5f53\u83b7\u53d6\u503c\u7684\u65f6\u5019\u6267\u884c\r\n    get () {\r\n        console.log('get: ', data.msg)\r\n        return data.msg\r\n    },\r\n    \/\/ \u5f53\u8bbe\u7f6e\u503c\u7684\u65f6\u5019\u6267\u884c\r\n    set (newValue) {\r\n        console.log('set: ', newValue)\r\n        if (newValue === data.msg) {\r\n            return\r\n        }\r\n        data.msg = newValue\r\n        \/\/ \u6570\u636e\u66f4\u6539\uff0c\u66f4\u65b0 DOM \u7684\u503c\r\n        document.querySelector('#app').textContent = data.msg\r\n    }\r\n})\r\n\/\/ \u6d4b\u8bd5\r\nvm.msg = 'Hello World'\r\nconsole.log(vm.msg)\r\n<\/code><\/pre>\n<ul>\n<li><strong>Vue 3.x<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u6a21\u62df Vue \u4e2d\u7684 data \u9009\u9879\r\nlet data = {\r\n    msg: 'hello',\r\n    count: 0\r\n}\r\n\/\/ \u6a21\u62df Vue \u5b9e\u4f8b\r\nlet vm = new Proxy(data, {\r\n    \/\/ \u5f53\u8bbf\u95ee vm \u7684\u6210\u5458\u4f1a\u6267\u884c\r\n    get (target, key) {\r\n        console.log('get, key: ', key, target[key])\r\n        return target[key]\r\n    },\r\n    \/\/ \u5f53\u8bbe\u7f6e vm \u7684\u6210\u5458\u4f1a\u6267\u884c\r\n    set (target, key, newValue) {\r\n        console.log('set, key: ', key, newValue)\r\n        if (target[key] === newValue) {\r\n            return\r\n        }\r\n        target[key] = newValue\r\n        document.querySelector('#app').textContent = target[key]\r\n    }\r\n})\r\n\/\/ \u6d4b\u8bd5\r\nvm.msg = 'Hello World'\r\nconsole.log(vm.msg)\r\n<\/code><\/pre>\n<h3>3. \u53d1\u5e03\u8ba2\u9605\u6a21\u5f0f\u548c\u89c2\u5bdf\u8005\u6a21\u5f0f<\/h3>\n<h4>\u2160. \u53d1\u5e03\u8ba2\u9605\u6a21\u5f0f<\/h4>\n<ul>\n<li><strong>\u53d1\u5e03\/\u8ba2\u9605\u6a21\u5f0f<\/strong>\n<ul>\n<li>\u8ba2\u9605\u8005<\/li>\n<\/ul>\n<ul>\n<li>\u53d1\u5e03\u8005<\/li>\n<li>\u4fe1\u53f7\u4e2d\u5fc3<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<blockquote><p>\u6211\u4eec\u5047\u5b9a\uff0c\u5b58\u5728\u4e00\u4e2a&#8221;\u4fe1\u53f7\u4e2d\u5fc3&#8221;\uff0c\u67d0\u4e2a\u4efb\u52a1\u6267\u884c\u5b8c\u6210\uff0c\u5c31\u5411\u4fe1\u53f7\u4e2d\u5fc3&#8221;\u53d1\u5e03&#8221;\uff08publish\uff09\u4e00\u4e2a\u4fe1\u53f7\uff0c\u5176\u4ed6\u4efb\u52a1\u53ef\u4ee5\u5411\u4fe1\u53f7\u4e2d\u5fc3&#8221;\u8ba2\u9605&#8221;\uff08subscribe\uff09\u8fd9\u4e2a\u4fe1\u53f7\uff0c\u4ece\u800c\u77e5\u9053\u4ec0\u4e48\u65f6\u5019\u81ea\u5df1\u53ef\u4ee5\u5f00\u59cb\u6267\u884c\u3002<strong>\u8fd9\u5c31\u53eb\u505a&#8221;\u53d1\u5e03\/\u8ba2\u9605\u6a21\u5f0f&#8221;\uff08publish-subscribe pattern\uff09<\/strong><\/p><\/blockquote>\n<ul>\n<li><strong>Vue \u7684\u81ea\u5b9a\u4e49\u4e8b\u4ef6<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">let vm = new Vue()\r\nvm.$on('dataChange', () =&gt; {\r\n    console.log('dataChange')\r\n})\r\nvm.$on('dataChange', () =&gt; {\r\n    console.log('dataChange1')\r\n})\r\nvm.$emit('dataChange')\r\n<\/code><\/pre>\n<ul>\n<li><strong>\u5144\u5f1f\u7ec4\u4ef6\u901a\u4fe1\u8fc7\u7a0b<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ eventBus.js\r\n\/\/ \u4e8b\u4ef6\u4e2d\u5fc3\r\nlet eventHub = new Vue()\r\n\/\/ ComponentA.vue\r\n\/\/ \u53d1\u5e03\u8005\r\naddTodo: function () {\r\n    \/\/ \u53d1\u5e03\u6d88\u606f(\u4e8b\u4ef6)\r\n    eventHub.$emit('add-todo', { text: this.newTodoText })\r\n    this.newTodoText = ''\r\n}\r\n\/\/ ComponentB.vue\r\n\/\/ \u8ba2\u9605\u8005\r\ncreated: function () {\r\n    \/\/ \u8ba2\u9605\u6d88\u606f(\u4e8b\u4ef6)\r\n    eventHub.$on('add-todo', this.addTodo)\r\n}\r\n<\/code><\/pre>\n<ul>\n<li><strong>\u6a21\u62df Vue \u81ea\u5b9a\u4e49\u4e8b\u4ef6\u7684\u5b9e\u73b0<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">class EventEmitter {\r\n    constructor () {\r\n        \/\/ { eventType: [ handler1, handler2 ] }\r\n        this.subs = {}\r\n    }\r\n    \/\/ \u8ba2\u9605\u901a\u77e5\r\n    $on (eventType, handler) {\r\n        this.subs[eventType] = this.subs[eventType] || []\r\n        this.subs[eventType].push(handler)\r\n    }\r\n    \/\/ \u53d1\u5e03\u901a\u77e5\r\n    $emit (eventType) {\r\n        if (this.subs[eventType]) {\r\n            this.subs[eventType].forEach(handler =&gt; {\r\n                handler()\r\n            })\r\n        }\r\n    }\r\n}\r\n\/\/ \u6d4b\u8bd5\r\nvar bus = new EventEmitter()\r\n\/\/ \u6ce8\u518c\u4e8b\u4ef6\r\nbus.$on('click', function () {\r\n    console.log('click')\r\n})\r\nbus.$on('click', function () {\r\n    console.log('click1')\r\n})\r\n\/\/ \u89e6\u53d1\u4e8b\u4ef6\r\nbus.$emit('click')\r\n<\/code><\/pre>\n<h4>\u2161. \u89c2\u5bdf\u8005\u6a21\u5f0f<\/h4>\n<ul>\n<li><strong>\u89c2\u5bdf\u8005(\u8ba2\u9605\u8005) &#8212; Watcher<\/strong><\/li>\n<li>update()\uff1a\u5f53\u4e8b\u4ef6\u53d1\u751f\u65f6\uff0c\u5177\u4f53\u8981\u505a\u7684\u4e8b\u60c5<\/li>\n<li><strong>\u76ee\u6807(\u53d1\u5e03\u8005) &#8212; Dep<\/strong><\/li>\n<li>subs \u6570\u7ec4\uff1a\u5b58\u50a8\u6240\u6709\u7684\u89c2\u5bdf\u8005<\/li>\n<li>addSub()\uff1a\u6dfb\u52a0\u89c2\u5bdf\u8005<\/li>\n<li>notify()\uff1a\u5f53\u4e8b\u4ef6\u53d1\u751f\uff0c\u8c03\u7528\u6240\u6709\u89c2\u5bdf\u8005\u7684 update() \u65b9\u6cd5<\/li>\n<li><strong>\u6ca1\u6709\u4e8b\u4ef6\u4e2d\u5fc3<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u76ee\u6807(\u53d1\u5e03\u8005)\r\n\/\/ Dependency\r\nclass Dep {\r\n    constructor () {\r\n        \/\/ \u5b58\u50a8\u6240\u6709\u7684\u89c2\u5bdf\u8005\r\n        this.subs = []\r\n    }\r\n    \/\/ \u6dfb\u52a0\u89c2\u5bdf\u8005\r\n    addSub (sub) {\r\n        if (sub &amp;&amp; sub.update) {\r\n        this.subs.push(sub)\r\n        }\r\n    }\r\n    \/\/ \u901a\u77e5\u6240\u6709\u89c2\u5bdf\u8005\r\n    notify () {\r\n        this.subs.forEach(sub =&gt; {\r\n            sub.update()\r\n        })\r\n    }\r\n}\r\n\/\/ \u89c2\u5bdf\u8005(\u8ba2\u9605\u8005)\r\nclass Watcher {\r\n    update () {\r\n        console.log('update')\r\n    }\r\n}\r\n\/\/ \u6d4b\u8bd5\r\nlet dep = new Dep()\r\nlet watcher = new Watcher()\r\ndep.addSub(watcher)\r\ndep.notify()\r\n<\/code><\/pre>\n<h4>\u2162. \u603b\u7ed3<\/h4>\n<ul>\n<li><strong>\u89c2\u5bdf\u8005\u6a21\u5f0f<\/strong>\u662f\u7531\u5177\u4f53\u76ee\u6807\u8c03\u5ea6\uff0c\u6bd4\u5982\u5f53\u4e8b\u4ef6\u89e6\u53d1\uff0cDep \u5c31\u4f1a\u53bb\u8c03\u7528\u89c2\u5bdf\u8005\u7684\u65b9\u6cd5\uff0c\u6240\u4ee5\u89c2\u5bdf\u8005\u6a21\u5f0f\u7684\u8ba2\u9605\u8005\u4e0e\u53d1\u5e03\u8005\u4e4b\u95f4\u662f\u5b58\u5728\u4f9d\u8d56\u7684\u3002<\/li>\n<li><strong>\u53d1\u5e03\/\u8ba2\u9605\u6a21\u5f0f<\/strong>\u7531\u7edf\u4e00\u8c03\u5ea6\u4e2d\u5fc3\u8c03\u7528\uff0c\u56e0\u6b64\u53d1\u5e03\u8005\u548c\u8ba2\u9605\u8005\u4e0d\u9700\u8981\u77e5\u9053\u5bf9\u65b9\u7684\u5b58\u5728\u3002<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\20210412102945.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/20210412102945.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3225\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/20210412102945.png\" alt=\"20210412102945\" width=\"794\" height=\"679\" \/><\/a><\/p>\n<h2>\u4e8c\u3001Vue \u54cd\u5e94\u5f0f\u539f\u7406\u6a21\u62df<\/h2>\n<h3>1. Vue<\/h3>\n<ul>\n<li><strong>\u529f\u80fd<\/strong><\/li>\n<li>\n<ul>\n<li>\u8d1f\u8d23\u63a5\u6536\u521d\u59cb\u5316\u7684\u53c2\u6570(\u9009\u9879)<\/li>\n<li>\u8d1f\u8d23\u628a data \u4e2d\u7684\u5c5e\u6027\u6ce8\u5165\u5230 Vue \u5b9e\u4f8b\uff0c\u8f6c\u6362\u6210 getter\/setter<\/li>\n<li>\u8d1f\u8d23\u8c03\u7528 observer \u76d1\u542c data \u4e2d\u6240\u6709\u5c5e\u6027\u7684\u53d8\u5316<\/li>\n<li>\u8d1f\u8d23\u8c03\u7528 compiler \u89e3\u6790\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u7ed3\u6784<\/strong><\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210412103108.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103108.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3226\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103108.png\" alt=\"\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103108\" width=\"224\" height=\"242\" \/><\/a><\/p>\n<ul>\n<li><strong>\u5b9e\u73b0<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">class Vue {\r\n    constructor (options) {\r\n        \/\/ 1. \u4fdd\u5b58\u9009\u9879\u7684\u6570\u636e\r\n        this.$options = options || {}\r\n        this.$data = options.data || {}\r\n        const el = options.el\r\n        this.$el = typeof options.el === 'string' ? document.querySelector(el) : el\r\n        \/\/ 2. \u8d1f\u8d23\u628a data \u6ce8\u5165\u5230 Vue \u5b9e\u4f8b\r\n        this._proxyData(this.$data)\r\n        \/\/ 3. \u8d1f\u8d23\u8c03\u7528 Observer \u5b9e\u73b0\u6570\u636e\u52ab\u6301\r\n        new Observer(this.$data)\r\n        \/\/ 4. \u8d1f\u8d23\u8c03\u7528 Compiler \u89e3\u6790\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f\u7b49\r\n        new Compiler(this)\r\n    }\r\n    _proxyData (data) {\r\n        \/\/ \u904d\u5386 data \u7684\u6240\u6709\u5c5e\u6027\r\n        Object.keys(data).forEach(key =&gt; {\r\n            Object.defineProperty(this, key, {\r\n                get () {\r\n                    return data[key]\r\n                },\r\n                set (newValue) {\r\n                    if (data[key] === newValue) {\r\n                        return\r\n                    }\r\n                    data[key] = newValue\r\n                }\r\n            })\r\n        })\r\n    }\r\n}\r\n<\/code><\/pre>\n<h3>2. Observer<\/h3>\n<ul>\n<li><strong>\u529f\u80fd<\/strong><\/li>\n<li>\n<ul>\n<li>\u8d1f\u8d23\u628a data \u9009\u9879\u4e2d\u7684\u5c5e\u6027\u8f6c\u6362\u6210\u54cd\u5e94\u5f0f\u6570\u636e<\/li>\n<li>data \u4e2d\u7684\u67d0\u4e2a\u5c5e\u6027\u4e5f\u662f\u5bf9\u8c61\uff0c\u628a\u8be5\u5c5e\u6027\u8f6c\u6362\u6210\u54cd\u5e94\u5f0f\u6570\u636e<\/li>\n<li>\u6570\u636e\u53d8\u5316\u53d1\u9001\u901a\u77e5<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u7ed3\u6784<\/strong><\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210412103145.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103145.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3227\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103145.png\" alt=\"\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103145\" width=\"262\" height=\"245\" \/><\/a><\/p>\n<ul>\n<li><strong>\u5b9e\u73b0<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u8d1f\u8d23\u6570\u636e\u52ab\u6301\r\n\/\/ \u628a $data \u4e2d\u7684\u6210\u5458\u8f6c\u6362\u6210 getter\/setter\r\nclass Observer {\r\n    constructor(data) {\r\n        this.walk(data)\r\n    }\r\n    \/\/ 1. \u5224\u65ad\u6570\u636e\u662f\u5426\u662f\u5bf9\u8c61\uff0c\u5982\u679c\u4e0d\u662f\u5bf9\u8c61\u8fd4\u56de\r\n    \/\/ 2. \u5982\u679c\u662f\u5bf9\u8c61\uff0c\u904d\u5386\u5bf9\u8c61\u7684\u6240\u6709\u5c5e\u6027\uff0c\u8bbe\u7f6e\u4e3a getter\/setter\r\n    walk(data) {\r\n        if (!data || typeof data !== 'object') {\r\n            return\r\n        }\r\n        \/\/ \u904d\u5386 data \u7684\u6240\u6709\u6210\u5458\r\n        Object.keys(data).forEach(key =&gt; {\r\n            this.defineReactive(data, key, data[key])\r\n        })\r\n    }\r\n    \/\/ \u5b9a\u4e49\u54cd\u5e94\u5f0f\u6210\u5458\r\n    defineReactive(data, key, val) {\r\n        const that = this\r\n        \/\/ \u5982\u679c val \u662f\u5bf9\u8c61\uff0c\u7ee7\u7eed\u8bbe\u7f6e\u5b83\u4e0b\u9762\u7684\u6210\u5458\u4e3a\u54cd\u5e94\u5f0f\u6570\u636e\r\n        this.walk(val)\r\n        Object.defineProperty(data, key, {\r\n            configurable: true,\r\n            enumerable: true,\r\n            get() {\r\n                return val\r\n            },\r\n            set(newValue) {\r\n                if (newValue === val) {\r\n                    return\r\n                }\r\n                \/\/ \u5982\u679c newValue \u662f\u5bf9\u8c61\uff0c\u8bbe\u7f6e newValue \u7684\u6210\u5458\u4e3a\u54cd\u5e94\u5f0f\r\n                that.walk(newValue)\r\n                val = newValue\r\n            }\r\n        })\r\n    }\r\n}\r\n<\/code><\/pre>\n<h3>3. Compiler<\/h3>\n<ul>\n<li><strong>\u529f\u80fd<\/strong><\/li>\n<li>\n<ul>\n<li>\u8d1f\u8d23\u7f16\u8bd1\u6a21\u677f\uff0c\u89e3\u6790\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f<\/li>\n<li>\u8d1f\u8d23\u9875\u9762\u7684\u9996\u6b21\u6e32\u67d3<\/li>\n<li>\u5f53\u6570\u636e\u53d8\u5316\u540e\u91cd\u65b0\u6e32\u67d3\u89c6\u56fe<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u7ed3\u6784<\/strong><\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210412103226.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103226.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3228\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103226.png\" alt=\"\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103226\" width=\"224\" height=\"245\" \/><\/a><\/p>\n<ul>\n<li><strong>\u5b9e\u73b0<\/strong><\/li>\n<\/ul>\n<p><strong>\u2460 compile()<\/strong><\/p>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u8d1f\u8d23\u89e3\u6790\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f\r\nclass Compiler {\r\n    constructor(vm) {\r\n        this.vm = vm\r\n        this.el = vm.$el\r\n        \/\/ \u7f16\u8bd1\u6a21\u677f\r\n        this.compile(this.el)\r\n    }\r\n    \/\/ \u7f16\u8bd1\u6a21\u677f\r\n    \/\/ \u5904\u7406\u6587\u672c\u8282\u70b9\u548c\u5143\u7d20\u8282\u70b9\r\n    compile(el) {\r\n        const nodes = el.childNodes\r\n        Array.from(nodes).forEach(node =&gt; {\r\n            \/\/ \u5224\u65ad\u662f\u6587\u672c\u8282\u70b9\u8fd8\u662f\u5143\u7d20\u8282\u70b9\r\n            if (this.isTextNode(node)) {\r\n                this.compileText(node)\r\n            } else if (this.isElementNode(node)) {\r\n                this.compileElement(node)\r\n            }\r\n            if (node.childNodes &amp;&amp; node.childNodes.length) {\r\n                \/\/ \u5982\u679c\u5f53\u524d\u8282\u70b9\u4e2d\u8fd8\u6709\u5b50\u8282\u70b9\uff0c\u9012\u5f52\u7f16\u8bd1\r\n                this.compile(node)\r\n            }\r\n        })\r\n    }\r\n    \/\/ \u5224\u65ad\u662f\u5426\u662f\u6587\u672c\u8282\u70b9\r\n    isTextNode(node) {\r\n        return node.nodeType === 3\r\n    }\r\n    \/\/ \u5224\u65ad\u662f\u5426\u662f\u5c5e\u6027\u8282\u70b9\r\n    isElementNode(node) {\r\n        return node.nodeType === 1\r\n    }\r\n    \/\/ \u5224\u65ad\u662f\u5426\u662f\u4ee5 v- \u5f00\u5934\u7684\u6307\u4ee4\r\n    isDirective(attrName) {\r\n        return attrName.startsWith('v-')\r\n    }\r\n    \/\/ \u7f16\u8bd1\u6587\u672c\u8282\u70b9\r\n    compileText(node) {\r\n    }\r\n    \/\/ \u7f16\u8bd1\u5c5e\u6027\u8282\u70b9\r\n    compileElement(node) {\r\n    }\r\n}\r\n<\/code><\/pre>\n<p><strong>\u2461 compileText()<\/strong><\/p>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u7f16\u8bd1\u6587\u672c\u8282\u70b9\r\ncompileText(node) {\r\n    const reg = \/\\{\\{(.+)\\}\\}\/\r\n    \/\/ \u83b7\u53d6\u6587\u672c\u8282\u70b9\u7684\u5185\u5bb9\r\n    const value = node.textContent\r\n    if (reg.test(value)) {\r\n        \/\/ \u63d2\u503c\u8868\u8fbe\u5f0f\u4e2d\u7684\u503c\u5c31\u662f\u6211\u4eec\u8981\u7684\u5c5e\u6027\u540d\u79f0\r\n        const key = RegExp.$1.trim()\r\n        \/\/ \u628a\u63d2\u503c\u8868\u8fbe\u5f0f\u66ff\u6362\u6210\u5177\u4f53\u7684\u503c\r\n        node.textContent = value.replace(reg, this.vm[key])\r\n    }\r\n}\r\n<\/code><\/pre>\n<p><strong>\u2462 compileElement()<\/strong><\/p>\n<ul>\n<li>\u8d1f\u8d23\u7f16\u8bd1\u5143\u7d20\u7684\u6307\u4ee4<\/li>\n<li>\u5904\u7406 v-text \u7684\u9996\u6b21\u6e32\u67d3<\/li>\n<li>\u5904\u7406 v-model \u7684\u9996\u6b21\u6e32\u67d3<\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">\/\/ \u7f16\u8bd1\u5c5e\u6027\u8282\u70b9\r\ncompileElement(node) {\r\n    \/\/ \u904d\u5386\u5143\u7d20\u8282\u70b9\u4e2d\u7684\u6240\u6709\u5c5e\u6027\uff0c\u627e\u5230\u6307\u4ee4\r\n    Array.from(node.attributes).forEach(attr =&gt; {\r\n        \/\/ \u83b7\u53d6\u5143\u7d20\u5c5e\u6027\u7684\u540d\u79f0\r\n        let attrName = attr.name\r\n        \/\/ \u5224\u65ad\u5f53\u524d\u7684\u5c5e\u6027\u540d\u79f0\u662f\u5426\u662f\u6307\u4ee4\r\n        if (this.isDirective(attrName)) {\r\n            \/\/ attrName \u7684\u5f62\u5f0f v-text v-model\r\n            \/\/ \u622a\u53d6\u5c5e\u6027\u7684\u540d\u79f0\uff0c\u83b7\u53d6 text model\r\n            attrName = attrName.substr(2)\r\n            \/\/ \u83b7\u53d6\u5c5e\u6027\u7684\u540d\u79f0\uff0c\u5c5e\u6027\u7684\u540d\u79f0\u5c31\u662f\u6211\u4eec\u6570\u636e\u5bf9\u8c61\u7684\u5c5e\u6027 v-text=\"name\"\uff0c\u83b7\u53d6\u7684\u662fname\r\n            const key = attr.value\r\n            \/\/ \u5904\u7406\u4e0d\u540c\u7684\u6307\u4ee4\r\n            this.update(node, key, attrName)\r\n        }\r\n    })\r\n}\r\n\/\/ \u8d1f\u8d23\u66f4\u65b0 DOM\r\n\/\/ \u521b\u5efa Watcher\r\nupdate(node, key, dir) {\r\n    \/\/ node \u8282\u70b9\uff0ckey \u6570\u636e\u7684\u5c5e\u6027\u540d\u79f0\uff0cdir \u6307\u4ee4\u7684\u540e\u534a\u90e8\u5206\r\n    const updaterFn = this[dir + 'Updater']\r\n    updaterFn &amp;&amp; updaterFn(node, this.vm[key])\r\n}\r\n\/\/ v-text \u6307\u4ee4\u7684\u66f4\u65b0\u65b9\u6cd5\r\ntextUpdater(node, value) {\r\n    node.textContent = value\r\n}\r\n\/\/ v-model \u6307\u4ee4\u7684\u66f4\u65b0\u65b9\u6cd5\r\nmodelUpdater(node, value) {\r\n    node.value = value\r\n}\r\n<\/code><\/pre>\n<h3>4. Dep<\/h3>\n<ul>\n<li><strong>\u529f\u80fd<\/strong><\/li>\n<li>\n<ul>\n<li>\u6536\u96c6\u4f9d\u8d56\uff0c\u6dfb\u52a0\u89c2\u5bdf\u8005(watcher)<\/li>\n<li>\u901a\u77e5\u6240\u6709\u89c2\u5bdf\u8005<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u7ed3\u6784<\/strong><\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210412103310.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103310.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3229\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103310.png\" alt=\"\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103310\" width=\"223\" height=\"237\" \/><\/a><\/p>\n<ul>\n<li><strong>\u5b9e\u73b0<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">class Dep {\r\n    constructor() {\r\n        \/\/ \u5b58\u50a8\u6240\u6709\u7684\u89c2\u5bdf\u8005\r\n        this.subs = []\r\n    }\r\n    \/\/ \u6dfb\u52a0\u89c2\u5bdf\u8005\r\n    addSub(sub) {\r\n        if (sub &amp;&amp; sub.update) {\r\n            this.subs.push(sub)\r\n        }\r\n    }\r\n    \/\/ \u901a\u77e5\u6240\u6709\u89c2\u5bdf\u8005\r\n    notify() {\r\n        this.subs.forEach(sub =&gt; {\r\n            sub.update()\r\n        })\r\n    }\r\n}\r\n\/\/ \u4ee5\u4e0b\u4ee3\u7801\u5728 Observer \u7c7b\u4e2d defineReactive \u65b9\u6cd5\u4e2d\u6dfb\u52a0\r\n\/\/ \u521b\u5efa dep \u5bf9\u8c61\u6536\u96c6\u4f9d\u8d56\r\nconst dep = new Dep()\r\n\/\/ getter \u4e2d\r\n\/\/ get \u7684\u8fc7\u7a0b\u4e2d\u6536\u96c6\u4f9d\u8d56\r\nDep.target &amp;&amp; dep.addSub(Dep.target)\r\n\/\/ setter \u4e2d\r\n\/\/ \u5f53\u6570\u636e\u53d8\u5316\u4e4b\u540e\uff0c\u53d1\u9001\u901a\u77e5\r\ndep.notify()\r\n<\/code><\/pre>\n<h3>5. Watcher<\/h3>\n<ul>\n<li><strong>\u529f\u80fd<\/strong><\/li>\n<li>\n<ul>\n<li>\u5f53\u6570\u636e\u53d8\u5316\u89e6\u53d1\u4f9d\u8d56\uff0c dep \u901a\u77e5\u6240\u6709\u7684 Watcher \u5b9e\u4f8b\u66f4\u65b0\u89c6\u56fe<\/li>\n<li>\u81ea\u8eab\u5b9e\u4f8b\u5316\u7684\u65f6\u5019\u5f80 dep \u5bf9\u8c61\u4e2d\u6dfb\u52a0\u81ea\u5df1<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u7ed3\u6784<\/strong><\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210412103341.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103341.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3230\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103341.png\" alt=\"\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103341\" width=\"222\" height=\"240\" \/><\/a><\/p>\n<ul>\n<li><strong>\u5b9e\u73b0<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-js\" lang=\"js\">class Watcher {\r\n    constructor(vm, key, cb) {\r\n        this.vm = vm\r\n        \/\/ data \u4e2d\u7684\u5c5e\u6027\u540d\u79f0\r\n        this.key = key\r\n        \/\/ \u5f53\u6570\u636e\u53d8\u5316\u7684\u65f6\u5019\uff0c\u8c03\u7528 cb \u66f4\u65b0\u89c6\u56fe\r\n        this.cb = cb\r\n        \/\/ \u5728 Dep \u7684\u9759\u6001\u5c5e\u6027\u4e0a\u8bb0\u5f55\u5f53\u524d watcher \u5bf9\u8c61\uff0c\u5f53\u8bbf\u95ee\u6570\u636e\u7684\u65f6\u5019\u628a watcher \u6dfb\u52a0\u5230dep \u7684 subs \u4e2d\r\n        Dep.target = this\r\n        \/\/ \u89e6\u53d1\u4e00\u6b21 getter\uff0c\u8ba9 dep \u4e3a\u5f53\u524d key \u8bb0\u5f55 watcher\r\n        this.oldValue = vm[key]\r\n        \/\/ \u6e05\u7a7a target\r\n        Dep.target = null\r\n    }\r\n    update() {\r\n        const newValue = this.vm[this.key]\r\n        if (this.oldValue === newValue) {\r\n            return\r\n        }\r\n        this.cb(newValue)\r\n    }\r\n}\r\n\r\n\/\/ \u5728 compiler.js(\u5373Compiler\u7c7b) \u4e2d\u4e3a\u6bcf\u4e00\u4e2a\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f\u521b\u5efa watcher \u5bf9\u8c61\uff0c\u76d1\u89c6\u6570\u636e\u7684\u53d8\u5316\r\ncompileText(node) {\r\n    const reg = \/\\{\\{(.+?)\\}\\}\/\r\n    const value = node.textContent\r\n    if (reg.test(value)) {\r\n        const key = RegExp.$1.trim()\r\n        node.textContent = value.replace(reg, this.vm[key])\r\n        \/\/ \u7f16\u8bd1\u5dee\u503c\u8868\u8fbe\u5f0f\u4e2d\u521b\u5efa\u4e00\u4e2a watcher\uff0c\u89c2\u5bdf\u6570\u636e\u7684\u53d8\u5316\r\n        new Watcher(this.vm, key, newValue =&gt; {\r\n            node.textContent = newValue\r\n        })\r\n    }\r\n}\r\n\/\/ \u56e0\u4e3a\u5728 textUpdater\u7b49\u4e2d\u8981\u4f7f\u7528 this\r\nupdaterFn &amp;&amp; updaterFn.call(this, node, this.vm[key], key)\r\n\/\/ v-text \u6307\u4ee4\u7684\u66f4\u65b0\u65b9\u6cd5\r\ntextUpdater(node, value, key) {\r\n    node.textContent = value\r\n    \/\/ \u6bcf\u4e00\u4e2a\u6307\u4ee4\u4e2d\u521b\u5efa\u4e00\u4e2a watcher\uff0c\u89c2\u5bdf\u6570\u636e\u7684\u53d8\u5316\r\n    new Watcher(this.vm, key, value =&gt; {\r\n        node.textContent = value\r\n    })\r\n}\r\n\r\n\/\/ \u89c6\u56fe\u53d8\u5316\u66f4\u65b0\u6570\u636e\r\n\/\/ v-model \u6307\u4ee4\u7684\u66f4\u65b0\u65b9\u6cd5\r\nmodelUpdater(node, value, key) {\r\n    node.value = value\r\n    \/\/ \u6bcf\u4e00\u4e2a\u6307\u4ee4\u4e2d\u521b\u5efa\u4e00\u4e2a watcher\uff0c\u89c2\u5bdf\u6570\u636e\u7684\u53d8\u5316\r\n    new Watcher(this.vm, key, value =&gt; {\r\n        node.value = value\r\n    })\r\n    \/\/ \u76d1\u542c\u89c6\u56fe\u7684\u53d8\u5316\r\n    node.addEventListener('input', () =&gt; {\r\n        this.vm[key] = node.value\r\n    })\r\n}\r\n<\/code><\/pre>\n<h2>\u4e09\u3001\u603b\u7ed3<\/h2>\n<h3>1. \u4e24\u4e2a\u95ee\u9898\u4f60\u4f1a\u4e86\u5417<\/h3>\n<ul>\n<li>\u7ed9\u5c5e\u6027\u91cd\u65b0\u8d4b\u503c\u6210\u5bf9\u8c61\uff0c\u662f\u5426\u662f\u54cd\u5e94\u5f0f\u7684\uff1f<\/li>\n<li>\u7ed9 Vue \u5b9e\u4f8b\u65b0\u589e\u4e00\u4e2a\u6210\u5458\u662f\u5426\u662f\u54cd\u5e94\u5f0f\u7684\uff1f<\/li>\n<\/ul>\n<h3>2. \u901a\u8fc7\u4e0b\u56fe\u56de\u987e\u6574\u4f53\u6d41\u7a0b<\/h3>\n<p><img decoding=\"async\" src=\"file:\/\/H:\\yuguoxy\\%E6%95%99%E5%AD%A6\\03web%E5%89%8D%E7%AB%AF\\%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0\\vue%E7%9B%B8%E5%85%B3\\media\\%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20210412103429.png\" alt=\"\" \/><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_202104121034291.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-3233\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2021\/04\/\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_202104121034291.png\" alt=\"\u256c\u0432\u2568\u253c\u255c\u256a\u2550\u255d_20210412103429\" width=\"1254\" height=\"541\" \/><\/a><\/p>\n<h3>3. Vue<\/h3>\n<ul>\n<li>\u8bb0\u5f55\u4f20\u5165\u7684\u9009\u9879\uff0c\u8bbe\u7f6e data\/data\/data\/el<\/li>\n<li>\u628a data \u7684\u6210\u5458\u6ce8\u5165\u5230 Vue \u5b9e\u4f8b<\/li>\n<li>\u8d1f\u8d23\u8c03\u7528 Observer \u5b9e\u73b0\u6570\u636e\u54cd\u5e94\u5f0f\u5904\u7406\uff08\u6570\u636e\u52ab\u6301\uff09<\/li>\n<li>\u8d1f\u8d23\u8c03\u7528 Compiler \u7f16\u8bd1\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f\u7b49<\/li>\n<\/ul>\n<h3>4. Observer<\/h3>\n<ul>\n<li>\u6570\u636e\u52ab\u6301\n<ul>\n<li>\u8d1f\u8d23\u628a data \u4e2d\u7684\u6210\u5458\u8f6c\u6362\u6210 getter\/setter<\/li>\n<\/ul>\n<ul>\n<li>\u8d1f\u8d23\u628a\u591a\u5c42\u5c5e\u6027\u8f6c\u6362\u6210 getter\/setter<\/li>\n<li>\u5982\u679c\u7ed9\u5c5e\u6027\u8d4b\u503c\u4e3a\u65b0\u5bf9\u8c61\uff0c\u628a\u65b0\u5bf9\u8c61\u7684\u6210\u5458\u8bbe\u7f6e\u4e3a getter\/setter<\/li>\n<\/ul>\n<\/li>\n<li>\u6dfb\u52a0 Dep \u548c Watcher \u7684\u4f9d\u8d56\u5173\u7cfb<\/li>\n<li>\u6570\u636e\u53d8\u5316\u53d1\u9001\u901a\u77e5<\/li>\n<\/ul>\n<h3>5. Compiler<\/h3>\n<ul>\n<li>\u8d1f\u8d23\u7f16\u8bd1\u6a21\u677f\uff0c\u89e3\u6790\u6307\u4ee4\/\u63d2\u503c\u8868\u8fbe\u5f0f<\/li>\n<li>\u8d1f\u8d23\u9875\u9762\u7684\u9996\u6b21\u6e32\u67d3\u8fc7\u7a0b<\/li>\n<li>\u5f53\u6570\u636e\u53d8\u5316\u540e\u91cd\u65b0\u6e32\u67d3<\/li>\n<\/ul>\n<h3>6. Dep<\/h3>\n<ul>\n<li>\u6536\u96c6\u4f9d\u8d56\uff0c\u6dfb\u52a0\u8ba2\u9605\u8005(watcher)<\/li>\n<li>\u901a\u77e5\u6240\u6709\u8ba2\u9605\u8005<\/li>\n<\/ul>\n<h3>7. Watcher<\/h3>\n<ul>\n<li>\u81ea\u8eab\u5b9e\u4f8b\u5316\u7684\u65f6\u5019\u5f80dep\u5bf9\u8c61\u4e2d\u6dfb\u52a0\u81ea\u5df1<\/li>\n<li>\u5f53\u6570\u636e\u53d8\u5316dep\u901a\u77e5\u6240\u6709\u7684 Watcher \u5b9e\u4f8b\u66f4\u65b0\u89c6\u56fe<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>\u539f\u6587\u5730\u5740: <a class=\"url\" href=\"https:\/\/juejin.cn\/post\/6946120511713705992\" target=\"_blank\">https:\/\/juejin.cn\/post\/6946120511713705992<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4e00\u3001\u4e09\u4e2a\u6982\u5ff5 1. \u6570\u636e\u9a71\u52a8 \u6570\u636e\u54cd\u5e94\u5f0f \u6570\u636e\u6a21\u578b\u4ec5\u4ec5\u662f\u666e\u901a\u7684 JavaScript \u5bf9\u8c61\uff0c\u800c\u5f53\u6211\u4eec\u4fee\u6539\u6570\u636e\u65f6 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[106,105],"tags":[],"_links":{"self":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/3223"}],"collection":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3223"}],"version-history":[{"count":3,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/3223\/revisions"}],"predecessor-version":[{"id":3234,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/3223\/revisions\/3234"}],"wp:attachment":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}