Vue のりアクティブシステム
以下を参考にしています。
effect.js
let activeEffect = null;
exports.effect = function (fn) {
activeEffect = fn;
}
// #############################################
// key : ref
// value: effectのリスト
const targetMap = new WeakMap();
exports.regist = function (target) {
let deps = targetMap.get(target);
if (deps === undefined) {
deps = new Set();
targetMap.set(target, deps);
}
if (activeEffect && deps.has(activeEffect) === false) {
deps.add(activeEffect);
}
}
exports.track = function (target, value = null) {
console.log(`track: ${value}`);
}
// #############################################
exports.trigger = function (target, newVal = null, value = null) {
const deps = targetMap.get(target);
if (deps === undefined) {
return;
}
deps.forEach(effect => {
effect(newVal, value);
});
}
ref.js
const { regist, track, trigger } = require('./effect');
exports.ref = function(value) {
const target = {
get value() {
// track(値が使用されていることを通知する処理)
track(target, value);
return value;
},
set value(newVal) {
// trigger(値が変更されたことを通知する処理)
trigger(target, newVal, value);
value = newVal;
},
};
regist(target);
return target;
}
main.js
const { ref } = require('./ref');
const { effect } = require('./effect');
effect((newVal, value) => {
console.log(`value changed: ${value} => ${newVal}`);
});
const str = ref("あいうえお");
console.log(str.value);
str.value = "hoge";
console.log(str.value);