We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在微信小程序实现 watch 属性,监听 data 中的属性,当被监听属性的值改变时,执行我们指定的方法。
Vue 的 computed 和 watch 可以很方便的检测数据的变化,从而做出相应的改变,所以,模仿 vue 肯定是一个不错的选择。
与 Vue 一样,我们使用 ES5 的Object.defineProperty()方法,劫持对象的 getter/setter,从而实现给对象赋值时(调用 setter),执行 watch 对象中相对应的函数,达到监听效果。
Object.defineProperty()
不啰嗦,上代码,真实可用。
function observe(obj, key, watchFun, deep, page) { let val = obj[key]; if (val != null && typeof val === "object" && deep) { Object.keys(val).forEach((item) => { observe(val, item, watchFun, deep, page); }); } Object.defineProperty(obj, key, { configurable: true, enumerable: true, set: function(value) { watchFun.call(page, value, val); val = value; <span class="hljs-keyword">if</span> (deep) { observe(obj, key, watchFun, deep, page); } }, <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> val; } }); } export function setWatcher(page) { let data = page.data; let watch = page.watch; Object.keys(watch).forEach((item) => { let targetData = data; let keys = item.split("."); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < keys.length - <span class="hljs-number">1</span>; i++) { targetData = targetData[keys[i]]; } <span class="hljs-keyword">let</span> targetKey = keys[keys.length - <span class="hljs-number">1</span>]; <span class="hljs-keyword">let</span> watchFun = watch[item].handler || watch[item]; <span class="hljs-keyword">let</span> deep = watch[item].deep; observe(targetData, targetKey, watchFun, deep, page); }); } 复制代码
function observe(obj, key, watchFun, deep, page) { let val = obj[key]; if (val != null && typeof val === "object" && deep) { Object.keys(val).forEach((item) => { observe(val, item, watchFun, deep, page); }); } Object.defineProperty(obj, key, { configurable: true, enumerable: true, set: function(value) { watchFun.call(page, value, val); val = value; <span class="hljs-keyword">if</span> (deep) { observe(obj, key, watchFun, deep, page); } }, <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> val; } }); } export function setWatcher(page) { let data = page.data; let watch = page.watch; Object.keys(watch).forEach((item) => { let targetData = data; let keys = item.split("."); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < keys.length - <span class="hljs-number">1</span>; i++) { targetData = targetData[keys[i]]; } <span class="hljs-keyword">let</span> targetKey = keys[keys.length - <span class="hljs-number">1</span>]; <span class="hljs-keyword">let</span> watchFun = watch[item].handler || watch[item]; <span class="hljs-keyword">let</span> deep = watch[item].deep; observe(targetData, targetKey, watchFun, deep, page);
if (val != null && typeof val === "object" && deep) { Object.keys(val).forEach((item) => { observe(val, item, watchFun, deep, page); }); }
Object.defineProperty(obj, key, { configurable: true, enumerable: true, set: function(value) { watchFun.call(page, value, val); val = value;
<span class="hljs-keyword">if</span> (deep) { observe(obj, key, watchFun, deep, page); } }, <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> val; }
}); }
export function setWatcher(page) { let data = page.data; let watch = page.watch;
Object.keys(watch).forEach((item) => { let targetData = data; let keys = item.split(".");
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < keys.length - <span class="hljs-number">1</span>; i++) { targetData = targetData[keys[i]]; } <span class="hljs-keyword">let</span> targetKey = keys[keys.length - <span class="hljs-number">1</span>]; <span class="hljs-keyword">let</span> watchFun = watch[item].handler || watch[item]; <span class="hljs-keyword">let</span> deep = watch[item].deep; observe(targetData, targetKey, watchFun, deep, page);
}); } 复制代码
push()
pop()
import * as watch from "./watch.js"; Page({ data: { name: "二狗子" }, onLoad() { watch.setWatcher(this); }, watch: { name: function(newVal, oldVal) { console.log(newVal, oldVal); } } }); 复制代码
import * as watch from "./watch.js"; Page({ data: { name: "二狗子" }, onLoad() { watch.setWatcher(this); },
Page({ data: { name: "二狗子" },
onLoad() { watch.setWatcher(this); },
watch: { name: function(newVal, oldVal) { console.log(newVal, oldVal); } } }); 复制代码
onLoad
然后就可以愉快的使用了。
watch 会使代码更简洁,逻辑更清晰,在响应式数据处理上很方便。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
目标
在微信小程序实现 watch 属性,监听 data 中的属性,当被监听属性的值改变时,执行我们指定的方法。
思路
Vue 的 computed 和 watch 可以很方便的检测数据的变化,从而做出相应的改变,所以,模仿 vue 肯定是一个不错的选择。
与 Vue 一样,我们使用 ES5 的
Object.defineProperty()
方法,劫持对象的 getter/setter,从而实现给对象赋值时(调用 setter),执行 watch 对象中相对应的函数,达到监听效果。代码
不啰嗦,上代码,真实可用。
注意事项:
push()
,pop()
等方法并不会触发监听函数。使用
onLoad
钩子设置监听器然后就可以愉快的使用了。
总结
watch 会使代码更简洁,逻辑更清晰,在响应式数据处理上很方便。
The text was updated successfully, but these errors were encountered: