ã¢ããããŒãïŒ
誰ãããã®æ©èœãå¿
èŠãšããããšã«ãªã£ãå Žåãç§ã¯ãããvueãšããŠãªãªãŒã¹ããŸããåå¿ããŸããã
Vueã®èŠ³å¯ãšæ©è¡ãç¡å¹ã«ããå¿ èŠãããéãã¬ãŒã³ã¢ãã«ãããã€ããããŸãã äŸãšããŠãé¢é£ãããªãœãŒã¹ãæ€çŽ¢ã§ããããã«ãã£ãã·ã¥ã«ã¢ã¯ã»ã¹ã§ãããªãœãŒã¹ã¢ãã«ããããŸãã ããã«ããããã£ãã·ã¥å ã®ãã¹ãŠã®ãªããžã§ã¯ããç£èŠãããããã«ãªãïŒããããéå¹ççïŒãä»ã®ã³ãŒããšã®è¿œå ã®çžäºäœçšãçºçããŸãã çŸåšããã£ãã·ã¥ã«ãããŒã®ãªãã¶ãŒããŒãèšå®ããããšã§ãããåé¿ããŠããŸãã 䌌ããããªãã®...
import get from 'http';
import Resource from 'resource';
new Vue({
data: { instance: {}, },
ready() { this.fetch(); },
methods: {
fetch() {
const Observer = Object.getPrototypeOf(this.instance.__ob__).constructor;
get('/api/frobs')
.then(function(data) {
// initialize Resource w/ JSON document
const resource = new Resource(data);
// Protect cache with dummy observer
resource.cache.__ob__ = new Observer({});
this.instance = resource;
});
},
},
});
ããã¯æ©èœããŸããã
Observer
ã¯ã©ã¹ãçŽæ¥ã€ã³ããŒãã§ããªãããããã§ã«ç£èŠãããŠãããªããžã§ã¯ããå¿
èŠã§ããææ¡ïŒ
Vueã®èŠ³å¯/æ©è¡ãæ瀺çã«ç¡å¹ã«ããå
¬åŒã®æ¹æ³ãè¿œå ããŸãã äŸïŒ..ââ.
const someThing = {
nestedThing: {},
};
// make entire object non-reactive
Vue.nonreactive(someThing);
// make nested object non-reactive
Vue.nonreactive(someThing.nestedThing);
vm.$set('key.path', someThing);
èæ ®äºé ïŒ
`` `js
vmã$ setïŒ 'a'ãVue.nonreactiveïŒ{}ïŒ;
// ãšéã..
vmã$ setïŒ 'a'ã{
someKeyïŒVue.nonreactiveïŒ{}ïŒã
}ïŒ;
`` `
`` `js
// ãšã©ãŒ
Vue.nonreactiveïŒvmã$ data.aïŒ
// æå¹
Vue.nonreactiveïŒ_ãcloneïŒvmã$ data.aïŒïŒ;
`` `
ããªãã®å Žåã Object.freeze()
ã¯æ©èœããŸãããïŒ v1.0.18以éã§ãµããŒããããŠããŸã
data
å
ã®ãªããžã§ã¯ã/é
åã®ç£èŠãã¹ãããããå¿
èŠãããå Žåã¯ã Object.freeze()
ã䜿çšããŸããdata
ã§ããã«ã¢ã¯ã»ã¹ããããã«ã this
ã created()
ããã¯ã®this
ã«æ¥ç¶ããã ãã§ã¯ããŸã£ãã芳å¯ãããŸãããObject.freeze
ã¯ããã§ã¯æ©èœããŸããã ãã£ãã·ã¥ã¯æéã®çµéãšãšãã«æŽæ°ãããŸãã次ã«ãã¢ãã«ã®èšèšãåèããæãæ¥ãã®ãããããŸããã ãªããããã芳å¯ãã¹ããã®ã®äžã«å ¥ãåã«ããã®ã§ããïŒ
ãã£ãã·ã¥ã¯é¢é£ãããªãœãŒã¹ãåçã«æ€çŽ¢ããããã«äœ¿çšãããããã§ãã
ããšãã°ã Author
Post
ã¢ãã«ãšposts
ãšåŒã°ããå€å¯Ÿå€ã®é¢ä¿ãå®çŸ©ããŸãã ãã®ãã£ãã·ã¥ã«ã¯ãé¢ä¿ããŒã¿ãšé¢é£ããã³ã¬ã¯ã·ã§ã³ãå«ãŸããŠããŸãã
author.postsãåŒã³åºããšããã£ãã·ã¥ããæçš¿ãååŸãããŸãã
èšèšäžãVueã¯ãç¬èªã®ç¶æ
å€æŽã¡ã«ããºã ãåããè€éãªãªããžã§ã¯ããVueã€ã³ã¹ã¿ã³ã¹ã®data
ããããšãæšå¥šããŠããŸããã 芳å¯ãããããŒã¿ãšããŠçŽç²ãªç¶æ
ã®ã¿ãVueã€ã³ã¹ã¿ã³ã¹ã«å
¥ããå¿
èŠããããŸãã ãããã®ç¶æ
ã¯ä»»æã®æ¹æ³ã§æäœã§ããŸããããã®ãããªæäœãè¡ããªããžã§ã¯ãã¯Vueã€ã³ã¹ã¿ã³ã¹ã®ç¶æ
ã®äžéšã§ãã£ãŠã¯ãªããŸããã
ãŸãã質åãæ確ã«ããŸã-çŽç²ãªç¶æ ãšã¯æ£ç¢ºã«ã¯ã©ãããæå³ã§ããïŒ ç¶æ ã«ã¯2ã€ã®ã¿ã€ãããããŸãã
ãšã«ããïŒ
ããã¯å
¬æ£ã§ãã ã¢ãã«ã¯ééããªããè€éãã§ããããããã®èŠæ±ã¯çŸåšã®ãã¹ããã©ã¯ãã£ã¹ã«åããŸãã ãŸããç§ã®æåã®äŸã¯ããŸãè¯ããããŸãã-ããã¯èŠ³å¯ãç¡å¹ã«ããããã«åãããã®ã§ãã ããã¯ãçŸåšã®ã»ããã¢ãããšå¯èœãªäœ¿çšæ³ãããããè¡šããŠããŸãã
<!-- layout -->
<post :post="post"></post>
<author :author="author" ><author>
<comments :comments="comments"></comments>
import post from 'components/post';
import author from 'components/author';
import comments from 'components/comments';
/* post = {
* template: '...'
* props: ['post'],
* data: () => {collapsed: false},
* ...
* }; */
new Vue({
el: 'body',
data() {
instance = postStore.fetch({include: ['author', 'comments.author']})
Vue.nonreactive(instance.cache)
return {post: instance, },
},
components: {
post,
author,
comments,
},
...
});
åºæ¬çã«ãåå©çšå¯èœãªã³ã³ããŒãã³ããã¬ã€ã¢ãŠãã«é 眮ããé¢é£ããã³ã³ããŒãã³ãã«ããŒã¿ããã§ãã/ãã€ã³ããã責任ãè² ã芪ãã¥ãŒããããŸãã ããŒã¿ã¯ã³ã³ããã¹ãã«ãã£ãŠç°ãªããããåã³ã³ããŒãã³ãã¯ç¬èªã®ããŒã¿ããã§ããããŸããã ããšãã°ã_ãŠãŒã¶ãŒã®_ã³ã¡ã³ãã®ãªã¹ããš_æçš¿ã®_ã³ã¡ã³ãã®ãªã¹ãã
é¢é£ãããªããžã§ã¯ãããã¹ããããŠããªãïŒ {post: {author: {}, comments: []}}
ïŒããšãé€ããŠãã¢ãã«ã¯ããªãããã ãã§ããã代ããã«ãã£ãã·ã¥ããæ€çŽ¢ãããŸãã ããšãã°ã post.comments[2].author
ã¯ã post.author
ãšãŸã£ããåããªããžã§ã¯ãã§ããå¯èœæ§ããããŸãã ãããã£ãŠãäœæè
ãªããžã§ã¯ãã®è€æ°ã®ã³ããŒãäœæãã代ããã«ããã£ãã·ã¥ããæ€çŽ¢ããã³ããŒã1ã€ã ãäœæããŸãã äžèšã«å€æŽã¯ãããŸããããã¹ãŠã®ããŒã¿ã¯æåã®ãã§ããã§äœæãããŸãã
ãŸãããªã¯ãšã¹ãããã¯ãé¢é£æ§ããããšããããã§ã¯ãããŸãããã代ããã«ããã©ã€ããŒãããªããžã§ã¯ãã¡ã³ããŒãç£èŠããªãããšãã§ããŸãã ããã¯ãå é ã«ã·ã³ã°ã«ãŸãã¯ããã«ã¢ã³ããŒã¹ã³ã¢ãä»ããã¡ã³ããŒã§ããå¯èœæ§ããããŸãã ãã®ã¢ãããŒãã®æ¬ ç¹ã¯ãå€åãå£ãããšã«ãªããšããããšã§ãã
@rpkilbyå ±æããŠãããŠããããšãïŒ
@rpkilbyãªããžã§ã¯ããã³ããŒããŠ
var newObj = JSON.parse(JSON.stringify(obj))
ãç¶æ ãã®é åãä¿æããç¶æ å±¥æŽãªããžã§ã¯ããvuexã«å®è£ ãããã®ã§ãæ¬åœã«äŸ¿å©ã§ãã
ç·šéïŒãã®è§£æ±ºçã¯ç§ã®å Žåã«åºæã®ãã®ã§ããã ããæç¹ã§ããããã£å€ã®ã³ããŒã®ã¿ãå¿ èŠãªãªããžã§ã¯ãããããŸããã åç §ãåçæŽæ°ãªã©ã¯æ°ã«ããŸããã§ããã
çŸåšããªããžã§ã¯ããããªãŒãºããããšã¯é·æçãªè§£æ±ºçã§ã¯ãããŸããã [Vue-nonreactive]ã¯ãäŸåé¢ä¿ãšããŠVueãæã£ãŠããŸãããããã¯åçŽãªããšãããããšã«ãªããšããéãã§ãã instance.__ob__ !== false
ãããªã³ãŒãã®ç°¡åãªãã§ãã¯ã§ååã§ã¯ãªãã§ããããïŒ ããã«ãããã©ã€ãã©ãªã¯ãã£ãã·ã¥ãªã©ãç£èŠãããªãããã«ããããšãã§ããŸãã
class Unobservable {
construtor() {
Object.defineProperty(this, '__ob__', {
enumerable: false, configurable: false,
writable: false, value: false,
});
}
}
ããã¯äž»ã«ãVueã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããã©ã€ãã©ãªã®åé¡ã§ãïŒå°ãªããšãç§ã«ãšã£ãŠã¯ïŒã
1ã¬ãã«ã®æ·±ãã®ããŒã¿ã®ã¿ãç£èŠããïŒdefinePropertyãïŒããã«Vueã«æ瀺ããã«ã¯ã©ãããã°ããã§ããïŒ
ç§ã®å Žåã data.curObj
å€æŽããããšãã«Vueã«éç¥ãåãåãããã®ã§ããã
ãã ãã curObj.position
ã curObj.rotation
ãªã©ã¯äœ¿çšããªãã§ãã ããã
以åã¯Object.freeze
ã䜿çšããŠããŸãããããã®å Žåãthree.jsããªããžã§ã¯ãã«å€ãå²ãåœãŠãããšãããšãšã©ãŒãçºçããŸãã
以äžãè¡ãå¿
èŠããããŸããïŒ
ïŒå®éãç§ã¯å¥ã®åæ§ã®å Žæã§ãããè¡ããŸããïŒ
data () {
return {
wrapper: Object.freeze({
actual: [bigData]
})
}
},
methods: {
operation () {
this.wrapper = Object.freeze({
actual: [newBigData]
})
}
}
// core/observer/watch.js
function _traverse (val: any, seen: ISet) {
let i, keys
const isA = Array.isArray(val)
if ((!isA && !isObject(val)) || !Object.isExtensible(val)) {
return
}
// ...
// core/observer/index.js
export function observe (value: any, asRootData: ?boolean): Observer | void {
if (!isObject(value) || value instanceof VNode) {
return
}
let ob: Observer | void
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__
} else if (
observerState.shouldConvert &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
ob = new Observer(value)
}
// ...
> curObj PerspectiveCamera {uuid: "BD3C14DF-8C2B-4B96-9900-B3DD0EAC1163", name: "PerspectiveCamera", type: "PerspectiveCamera", parent: null, children: Array(0), âŠ}
> Lodash.isPlainObject(curObj) false
> Vue.isPlainObject(curObj) true
Object.isExtensible
ïŒ Object.freeze
ïŒã ãã§ãªãããŠãŒã¶ãŒãç£èŠãç¡å¹ã«ããå¥ã®æ¡ä»¶ãè¿œå ã§ããŸããïŒç Žå£ã䜿çšã§ããŸã
var newObj = { ...obj };
ããã§ä¿®æ£ãããã¯ãã§ãã isPlainObjectã¡ãœãããfalseãè¿ãããã«ãªããŸãã
/**
* Makes an object and it's children unobservable by frameworks like Vuejs
*/
class Unobservable {
/**
* Overrides the `Object.prototype.toString.call(obj)` result
* <strong i="6">@returns</strong> {string} - type name
* <strong i="7">@see</strong> {<strong i="8">@link</strong> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag}
*/
get [Symbol.toStringTag]() {
// Anything can go here really as long as it's not 'Object'
return 'ObjectNoObserve';
}
}
>> Object.prototype.toString.call(new Unobservable());
"[object ObjectNoObserve]"
ããã«ã¡ã¯ãåçã§å€±ããã1ã€ã®ãã€ã³ãã¯ãå
ã®ã³ã¡ã³ãã®ããŒã¿ãçŽç²ãªç¶æ
ã§ã¯ãªããšããããšã§ãã ç§ã®å Žåããªã¬ãŒã·ã§ã³ã·ããã«ãã¯ã¢ãããã£ãã·ã¥ãžã®ãã©ã€ããŒãåç
§ãæã€ã¢ãã«ã€ã³ã¹ã¿ã³ã¹ããããŸãã ããšãã°ã article
ã¯ããã®author
ãŸãã¯comments
ãæ€çŽ¢ã§ããŸãã article.author
ãåŒã³åºããšãããã¯ãã®é¢ä¿ãã£ãã·ã¥ãžã®åçãªããããã£ã«ãã¯ã¢ããã§ãããåçŽãªå±æ§ã¢ã¯ã»ã¹ã§ã¯ãããŸããã èæ
®ãã¹ãããã€ãã®äºæïŒ
ããã€ãã®ææ¡ã«å¿ããŠïŒ
ç§ã®å¯äžã®æ¹å€ïŒ
Vue-nonreactiveã«ã¯ãäŸåé¢ä¿ãšããŠVueããããŸããããã¯ãåçŽãªããšãè¡ãå Žåã«ã¯ããéãã§ãã
ãªããããæªãããšã«ãªãã®ãããããŸãããïŒ ã¢ããªã±ãŒã·ã§ã³ã§ãã§ã«Vueã䜿çšããŠããããã©ã°ã€ã³ã¯Vueã«åºæã§ãã ç§ãééã£ãŠããªããã°ãã»ãšãã©ã®ãã«ãããŒã«ã¯ãäŸåé¢ä¿ãéè€ãããã³ãã«ãäœæããªãã»ã©è³¢ãã§ãã ãšã«ãããããã¯æ£ãããããŸããã éçºäŸåé¢ä¿ã¯ãããŸãããå®è¡æäŸåé¢ä¿ã¯ãããŸããã
ãšã«ããããã®æçš¿ãããçšåºŠã®é¢å¿ãéããŠããã®ãèŠãŠããããæããŸãããããã®ä»ã®ãœãªã¥ãŒã·ã§ã³ã®ããã€ãã¯ãä»ã®ããŸããŸãªã±ãŒã¹ã§æ©èœãããšç¢ºä¿¡ããŠããŸãã å ã®ã³ã¡ã³ãããã®èŠä»¶ãšããã®ææ¡ããã®å Žåã®é©åãªä»£æ¿æ¡ã§ã¯ãªãçç±ã匷調ããããšæããŸãã
ããã§ãç§ã¯æè¿ããã«ééããVueã®ç£èŠããžãã¯ãç絡ããã¯ããã«ç°¡åãªæ¹æ³ãããããšãçºèŠããŸããïŒ_ããããã£ãæ§æäžå¯èœãšããŠå®çŸ©ããŸãã_
ããã¯ã°ã©ãŠã³ã
ç§ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããµãŒãããŒãã£ã®ã©ã€ãã©ãªïŒOpenLayersïŒã䜿çšããå¿ èŠããããŸãããã®ã©ã€ãã©ãªã¯ãããŒã¿ãä¿æããã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ãäœæããåå¿æ§ã·ã¹ãã ããµããŒãããŠããŸããã éŽã¹ããå±¥ãããšãããšãéåžžã«å€ãã®é çã®çš®ã«ãªããŸãã ãããã£ãŠããã®ã©ã€ãã©ãªãŒã䜿çšãã倧èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ã®å¯äžã®å®è¡å¯èœãªè§£æ±ºçã¯ãOpenLayersã«åžæã©ããã®æ©èœãæãããããšã§ãããããŠãç§ã«ãšã£ãŠããããã®æããããã¹ãããããéåœã®è¶ è¶ãªããžã§ã¯ãã§Vueãããå¿«é©ã«ãã¬ã€ã§ããããã«ããŸãã ãã®åé¡ãèŠã€ããåã¯ãç§ã®ã¢ããªã±ãŒã·ã§ã³ã¯ïŒæ倧ã®ããŒã¿ã»ããã§ïŒçŽ3ã®ã¬ã®RAMã䜿çšããŠããŸãããããã®ãã¹ãŠãVueã«ãã£ãŠãããã®ãªããžã§ã¯ããåå¿ãããããšãåå ã§ããã ãŸããããŒããããšãã¯æ¬åœã«é ãã£ãã ç§ã¯Vue-nonreactiveãè©ŠããŸããããããã¯åœ¹ã«ç«ã¡ãŸããããç§ãã¡ãçŽ1ã®ã¬ãŸã§äžããããšãã§ããŸããã Vueã䜿çšããåã¯ãã¢ããªã±ãŒã·ã§ã³ã¯çŽ350ã¡ã¬ãã€ãã§ããã
解決
åå¿ããããªããã®ã¯ãã¹ãŠã configurable: false
ãšããŠããŒã¯ããã ãã§ãã ããã¯æ¬¡ã®ããã«ç°¡åã§ãïŒ
Object.defineProperty(target, 'nested', { configurable: false });
ïŒããã«ããã nested
ããããã£ãããã³ãã®ãã¹ãŠã®ããããã£ãç£èŠãããªããªããŸããïŒ
ããã§ãããŸãïŒ Vueã«äŸåããããšã¯ãªããééããªãæ£ãããããŸããã ããã§ãç§ã®ã¢ããªã±ãŒã·ã§ã³ã¯æ倧ã®ããŒã¿ã»ããã§200ã¡ã¬ãã€ãã«ãªããŸããã ããã¯ã·ã³ãã«ã§ç°¡åã§ãããVueåŽã§ããã¥ã¡ã³ããå€æŽããã ãã§ãäœããéåå¿æ§ã«ãããå ¬åŒããªæ¹æ³ã«ããããšãã§ããŸãã
èå³æ·±ã-ééããªãå®è¡å¯èœãªä»£æ¿æ¡ã®ããã§ãã
芳å¯åå¿ãäžæçã«äžæåæ¢ããåŸã§äžæåæ¢ã解é€ããæ¹æ³ã¯ãããŸããïŒ
ç§ã¯ãããããŠã©ããã£ãŒãæã£ãŠããŸãããã®äžã§ãããŒã¿ã®æºåå šäœãå®äºããåŸã«ã®ã¿DOMæŽæ°ãããªã¬ãŒããããªã巚倧ãªãªããžã§ã¯ããæŽæ°ããŸãã
@intijkæ£ç¢ºã§ã¯ãããŸããã ã»ããããã¯ããªããããããšããŠããããšã«äŸåããŸãã Vueã¯æçµçã«ããªãã®ç¶æ ãé©çšããå¿ èŠãããã®ã§ãèšç®äžã«äžæåæ¢ããã ãã§ã¯ããŸã圹ã«ç«ã¡ãŸããã 代ããã«ãäžéç¶æ ãã¹ãããããŠæçµç¶æ ã®ã¿ãé©çšããããšããŠããå Žåã¯ãæ°ãããªããžã§ã¯ãããå§ããŠãæåŸã«ãã®ãªããžã§ã¯ããå²ãåœãŠãŸãã
äŸïŒæ¬äŒŒã³ãŒãïŒïŒ
doUpdate()
{
const state = _.cloneDeep(this.myState);
// Do intermediate state updates
this.myState = state;
}
ïŒãªããžã§ã¯ãã®åå¿æ§ã«é¢ããéåžžã®Vueã®èŠåãé©çšãããŸããïŒ
äžèšã®configurable
ããªãã¯ã䜿çšããŠããªã¢ã¯ãã£ãã§ããå¿
èŠã®ãªã倧ããªãªããžã§ã¯ãã®ã»ã¯ã·ã§ã³ãã¹ãããããããšããå§ãããŸãã ãã¹ãŠãåå¿ããå¿
èŠãããå Žåã¯ã vuex
ãããªãã®ã䜿çšããããšããå§ãããŸãã
@Morgulç§ã¯ãã§ã«ãã®ããªãã¯ãé·ãé䜿çšããŠããŸããããå®éã«ã¯ããã®ããªãã¯ã¯ãã䜿çšããããããŸããã
ç§ã®å ŽåãããŒã¿ãªããžã§ã¯ãã¯2Mãã100Mã®ç¯å²ã®å€§ããªãã®ã«ãªããŸããããã®ãããªãªããžã§ã¯ãã§ãã£ãŒãã³ããŒãå®è¡ããã®ã¯ãéåžžã«é¢åã§ãã
@intijk Vueããã€ã³ããããã®ãšããŠã¯ãéåžžã«è€éã«èãããŸãã ããã§ã®ãŠãŒã¹ã±ãŒã¹ã¯äœã§ããïŒ
@ã¢ã«ã°ã«
ã±ãŒã¹ã¯è€éã§ã¯ãªããšæããŸããã±ãŒã¹èªäœã¯åçŽã§ãããŒã¿ã ããã¡ãã£ãšå€§ããã§ãã ãããã¯ãŒã¯ãã€ã³ããã¯ã¹ä»ãã®èŠèŠåãã°ãã¡ã€ã«ãããŒããããã³ã«ãããã衚瀺ããããã®èŠèŠåã³ã³ããŒãã³ãããããŸãã
èšç®ãããããããã£å ã«éåå¿æ§ãã£ãŒã«ããå®çŸ©ããããšã«ã€ããŠèããããšããã人ã¯ããŸããïŒ ç§ã®æåã®ã¢ã€ãã¢ã¯ãé åãžã®å²ãåœãŠã®éåå¿æ§ã«äŸåããŠããŸã...
template: '<div v-html="markdown.render(input, env)"></div>',
props: ['id', 'input'],
computed: {
env: function() { return { reactive:this.id, non_reactive:[] } },
markdown: function() { return Markdown },
},
// within markdown.render():
env.non_reactive[0] = internal_data;
ããããããã¯æ£ç¢ºã«èªå·±ææžåã§ã¯ãããŸãã:-)
ããã¿ããªã ãã®åé¡ãèŠã€ãããšãããrpkilbyã®åé¡ã«ãã䌌ãåé¡ã«çŽé¢ããŠããããšãããããŸãããç§ã®ãããžã§ã¯ãã¯JSONãªããžã§ã¯ãããäžé£ã®Vueä»®æ³DOMïŒãŸãã¯vnodeãšåŒã°ããïŒãæ§ç¯ããŸãã ãã®JSONãªããžã§ã¯ãã䜿çšããŠAndroidã¢ããªãäœæããŸãã ãšã«ããããã®JSONãªããžã§ã¯ãã¯å€§ããªãµã€ãºã«ãªãå¯èœæ§ããããVueã§ãã®JSONã䜿çšãããšãVueã«ãã£ãŠç£èŠãããŸãã rpkilbyãšMorgulã®æ¹æ³ãè©ŠããŸããããæ©èœããŸããïŒBTWç§ã¯ããŒã ã«æå±ããŠããŸãããVueã«æ
£ããŠããªã人ããããããJSONã芳å¯ãããå¯èœæ§ããããŸããVueã®ããŒãžã§ã³ã¯2.5.16ã§ãã ïŒã Vueãã©ããŒã¹ã§ãããå®è¡ã§ãããã©ããçåã«æã£ãŠããŸãïŒ
function _traverseïŒvalãseenïŒ{
var iãããŒ;
var isA = Array.isArrayïŒvalïŒ;
ifïŒïŒïŒisA &&ïŒisObjectïŒvalïŒïŒ|| Object.isFrozenïŒvalïŒ|| VNodeã®valã€ã³ã¹ã¿ã³ã¹
|| ïŒval && val ['__ vueNonReactive __']ïŒïŒ{
æ»ã
}
..ã
ã芧ã®ãšããããval && val ['__ vueNonReactive__']ããè¿œå ããŸãã 次ã«ãJSONãªããžã§ã¯ããå€æŽããŠãJSONã®ã«ãŒãããŒãã§ã__ vueNonReactive__ = trueããèšå®ããŸããããã«ãããåé¡ã解決ããŸãã
ããã§åé¡ãçºçããã®ã§ã¯ãªãããšæããŸãã ãããŠãããã¯ãéçºè
ããªããžã§ã¯ãã®ããããã£ãæ§æããããšã«ãã£ãŠãVueã«ãã£ãŠç£èŠãããããã«ãªããžã§ã¯ããæ§æã§ãããã©ãããå¯èœã«ãããVueã®æ°æ©èœãšèŠãªãããŸããïŒïŒObject.freezeã¯ãªããžã§ã¯ããäžå€ãªããžã§ã¯ãã«å€æŽããå¯èœæ§ãããããããã¹ãŠã®ç¶æ³ã«å¯Ÿå¿ã§ããããã§ã¯ãããŸããïŒ
ãããæ€èšããŠãã ããhttps://github.com/vuejs/vue/blob/v2.5.16/src/core/observer/index.js#L121
set val._isVue = true
ã¯ãvueç£èŠæé ããè±åºã§ããŸãã
ä»æ¥ãç§ã¯Vueãmapbox-glã®ãããã€ã³ã¹ã¿ã³ã¹ã芳å¯ãããã®åŸå¥åŠãªããšãèµ·ãããããããæãããªããšããã±ãŒã¹ã«ééããŸããã ãã ãããããã€ã³ã¹ã¿ã³ã¹ã¯vueã€ã³ã¹ã¿ã³ã¹éã§åãæž¡ãå¿
èŠããããŸãã map._isVue = true
ãè¿œå ãããšãåé¡ã¯è§£æ±ºããŸããã
ãããå
¬åŒã«ãµããŒãããã«ã¯+1ã ã³ã³ããŒãã³ãã§åå¿æ§ãå¿
èŠãšããªã倧ããªãªããžã§ã¯ãã䜿çšããŠããŸãããæªäœ¿çšã®åå¿æ§ãç¡å¹ã«ãããšãã¡ã¢ãªãªããžã§ã¯ãã®ãµã€ãºã800MBãã43MBã«æžå°ããŸãã
äºææ§ã®åé¡ã®ããã«@magicdawnãœãªã¥ãŒã·ã§ã³ã䜿çšããŠããŸãããããã§ã¯
__ob__
ã®configurable
ãfalseã«èšå®ãããœãªã¥ãŒã·ã§ã³ã®å Žåãå®éã®__ob__
ãèšå®ããããšãããšãVueãã¯ã©ãã·ã¥ããŸãã
Vueå€æ°ãéåå¿æ§ã«ããããšãå¯èœã«ããVueãã©ã°ã€ã³ãæ§ç¯ããŸããïŒbeforeCreateããã¯ã䜿çšããŸãïŒã
ããã¯vueãããã¯ãªãŒã³ã§ã@ rpkilby ããã®ã³ã¡ã³ããèŠãŠãã ãã-ããªãã®ãœãªã¥ãŒã·ã§ã³ã¯Vueã®æ¬¡ã®ããŒãžã§ã³ã§ã¯æ©èœããŸããã
å€æ°ãéåå¿æ§ã«ããæ¹æ³ã«ã€ããŠã¯ã Vue-Staticãåç §ããŠãã ããã
<script>
export default {
static() {
return {
map: null,
};
},
mounted() {
this.map = new mapboxgl.Map({...}); /* something heavy */
},
};
</script>
ããã«ã¡ã¯@ samuelantonioli -vue-staticã¯å°ãç°ãªãããšãããŠããªããžã§ã¯ãå šäœã®åå¿æ§ãç¡å¹ã«ããŠããããã§ãã å¯Ÿç §çã«ãvue-nonreactiveã¯ããªããžã§ã¯ãã®æ®ãã®éšåããªã¢ã¯ãã£ãã«ä¿ã¡ãªãããåäžã®ããããã£ã®ç£èŠãç¡å¹ã«ããããšãã§ããŸãã
ãšã¯ãããæå³ã¯å°ãéãããã§ãã éçããããã£ã¯å€æŽãç£èŠããŸãããããã³ãã¬ãŒãã«ã¬ã³ããªã³ã°ããããšãç®çãšããŠããŸãã éåå¿æ§ã®ããããã£ã¯ã芳å¯ãããããšãæå³ããŠããããã¬ã³ããªã³ã°ãããããšãæå³ãããŠããŸããã
ããšãã°ãç§ã®ã¢ãã«ã€ã³ã¹ã¿ã³ã¹ã«ã¯ãé¢é£ãããªããžã§ã¯ãã®ã«ãã¯ã¢ãããå¯èœã«ãããªããžã§ã¯ããã£ãã·ã¥ãžã®åç
§ããããŸãã instance
ãšé¢é£ããinstance.author
ãç£èŠ/ã¬ã³ããªã³ã°ãããã®ã§ããã instance._cache
ã¯å¿
èŠãããŸããã
new Vue({
data() {
const instance = postStore.fetch({include: ['author', 'comments.author']})
Vue.nonreactive(instance._cache)
return {post: instance, },
},
...
});
ãããã«ãããé ãäžããŠãããŠããããšãã 次ã®ããŒãžã§ã³ã§ãããã·ãã©ã®ããã«äœ¿çšãããŠãããã調ã¹ãŠããªãã¶ãŒããŒ/ãããã·ã®äœæãè€è£œããæ¹æ³ããããã©ããã確èªããå¿ èŠããããŸãã
@ LinusBorg-å®éšçãªãã©ã³ãã¯
ç§ãã¡ã¯ãŸã 圌ã®ã³ã³ã»ãã/çµéšæ®µéã§ããããŸã ãã©ã³ããå ¬éããŠããŸããã ããã«é¢ããçå£ãªäœæ¥ã¯ã2.6ã®ã¢ããããŒããå ¬éããããŸã§ã¯éå§ãããŸãããããã¯ãvue-cli 3.0ãéããªããªãªãŒã¹ãããåŸãããèªäœãããçšåºŠã®äœæ¥ãå¿ èŠãšããŸãã
æŽæ°ããŠããã ãããããšãããããŸãã
ãããã£ãŠãES6ãããã·ãå°å ¥ãããåŸãåé¡ãåãã¹ã³ãŒãã«ååšãããã©ããã¯ããããŸããã ç§ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããããå€çšããŠããããããã®ãªãŒããŒããããšvueã®çŸåšã®èŠ³æž¬ã®ãªãŒããŒãããã¯ã¯ããã«å°ããããã§ãã æªéã现éšã«ããã®ã§ã¯ãªãããšæããŸãã
ç§ãVue-Static
æ±ããŠããåé¡ã¯ããããåé·ã ãšæããããšã§ãã JSã¢ãžã¥ãŒã«ã§ãªããžã§ã¯ããäœæããã€ã³ããŒãããŠãèšç®ãããé¢æ°ããå€ãè¿ãããšãã§ããŸãã 芳枬ãããªããããèšç®ãããé¢æ°ã®å€ãåèšç®ãããªãããšã¯åé¡ã§ã¯ãããŸããã ãããŠãç§ã¯vueã³ã³ããŒãã³ãã§ããžãã¹ããžãã¯ã¿ã€ãã®ããšãè¡ã£ãŠããªãã®ã§ãé¢å¿ã®åé¢ãã¯ããã«åªããŠããŸãã
ãããã«ãããããããã£ãæ§æäžå¯èœãšããŠèšå®ãããšããç§ã®ããªãã¯ã¯ãåé¡ãåŠçããããã®æã䟵襲æ§ãäœããVueã«äŸåããªãæ¹æ³ã§ãã ãŸããESãããã·ã§æ©èœããªããªããšæ³å®ããçç±ããããŸããã ããã§ããæ§æäžå¯èœãªããããã£ãç£èŠããããªãå ŽåããããŸãã ç§ã¯å®å
šã«ééã£ãŠããå¯èœæ§ããããŸããã __ob__
ããªããªãããšã_ç¥ã£ãŠããŸã...ããããã£ãæ§æå¯èœã§ãããã©ããã®ãã§ãã¯ã«ã€ããŠã¯ããããŸããã
ããã«ã8ãæ以äžãæ¬çªã³ãŒãã®ãã£ã³ããªã³ã®ããã«æ©èœããŠããŸãã ;ïŒïŒ@ samuelantonioliãšåæ§ã®åé¡ã¹ããŒã¹ããããŸããVueãã¡ã¢ãªã2.4ã®ã¬ã«èšããŸããããšãªããVueå ã§æäœããå¿ èŠã®ããOpenLayersãããããããŸã...ïŒ
ã¢ãžã¥ãŒã«ã®ã€ã³ããŒããèšç®ãããããããã£ãªã©ã®å¥ã®ãã¿ãŒã³ã䜿çšããå Žåã¯ã Vue-Staticã¯å¿ èŠãããŸããã åŸæ¥å¡ãç解ããããã䜿ãããããã¿ãŒã³ãåŸæ¥å¡ã«æããããšãã§ããã°ããã£ãã®ã§ãã import-module-and-use-computed-propertiesãã¿ãŒã³ã¯ãããã»ã©æ確ãªIMOã§ã¯ãããŸããã
å°ãOTïŒES6ãããã·ãè¯ãæ¹æ³ã ãšç¢ºä¿¡ããŠããŸããããã©ãŠã¶ã®äºææ§ã«ã€ããŠæžå¿µããããŸãïŒIE11以äžã¯ãµããŒãããŠããŸããïŒã ããå³ãããã©ãŠã¶èŠä»¶ãæã€ãããžã§ã¯ãã«Vueã䜿çšã§ããããã«ãäºææ§ã¬ã€ã€ãŒ/ããçš®ã®ããªãã£ã«ããããã©ããã«èå³ããããŸãã
1ã¬ãã«ã®æ·±ãã®ããŒã¿ã®ã¿ãç£èŠããïŒdefinePropertyãïŒããã«Vueã«æ瀺ããã«ã¯ã©ãããã°ããã§ããïŒ
ãã®ã¢ã€ãã¢ã®+1ã䜿çšãããšãå€éšã®Graphic libïŒéåžžã¯ãã«ãã¬ãã«ã®ãã¹ãããã倧ããªãªããžã§ã¯ãããããŸãïŒã§Vueã䜿çšããããã®ããŒã¿ãæ§é åããã®ãç°¡åã«ãªããŸãã
äžéšã®ããããã£ã®ã¿ããªã¢ã¯ãã£ãã«æå®ããã®ã¯ã©ãã§ããïŒ
ããã§æãããªäœããæ¬ ããŠãããããããŸããããthis.propertyName = {/ *ããã§äœã倧ããªãã®ã䜿çšããŠããŸã* /};
MountedïŒïŒããã¯ã§ã芳å¯ãããªãããããã£ãæã€ããšã®è§£æ±ºçã§ã¯ãããŸãããïŒ
ããã«ã¡ã¯@vlahanasã https://github.com/vuejs/vue/issues/2637#issuecomment-403630456ãåç §ããŠ
_isVue
ãèšå®ãããšãvue-devtoolãã¯ã©ãã·ã¥ããŸãã代ããã«ããã®é¢æ°ã䜿çšããŠãã ãã
export default function setIsVue(val) {
if (!val) return
Object.defineProperty(val, '_isVue', {
value: true,
enumerable: false,
configurable: true,
})
// vue-devtool
// https://github.com/vuejs/vue-devtools/blob/c309065c57f6579b778341ea37042fdf51a9fc6c/src/backend/index.js#L616
// å 䞺æ _isVue å±æ§
if (process.env.NODE_ENV !== 'production') {
if (!val.$options) {
Object.defineProperty(val, '$options', {
value: {},
enumerable: false,
configurable: true,
})
}
if (!val._data) {
Object.defineProperty(val, '_data', {
value: {},
enumerable: false,
configurable: true,
})
}
}
return val
}
ããã¯ãã€ãºã§å€±ãããŸããããããããã£ãæ§æäžå¯èœãšããŠããŒã¯ããããšã¯æ¬åœã«ä¿®æ£ã®ããã§ãã
Object.keys(scene).forEach((key)=>{
Object.defineProperty(target, 'nested', { configurable: false });
});
THREE.Scene
ãæž¡ãå¿
èŠãããããæåéãã·ãŒã³ã°ã©ãå
šäœã芳å¯å¯èœãªãã®ã®æ··ä¹±ã«ãªãããšãæãŸãªãå Žåã¯æ¬åœã«çŽ æŽãããã§ãã ãããŠãç§ã¯ãŸã å
ã®ãªããžã§ã¯ããåãããšãã§ããããã«åºã¥ããŠåå¿ããããšãã§ããŸãã å®å
šïŒ
ãŸã åé¡ã§ãã
éåå¿æ§ãä¿æãããå€ãã®ãã¹ããããã¬ãã«ã®ããããã£ãå«ããªããžã§ã¯ãããããŸãã
䜿ã£ãŠã
ããã¯ãã€ãºã§å€±ãããŸããããããããã£ãæ§æäžå¯èœãšããŠããŒã¯ããããšã¯æ¬åœã«ä¿®æ£ã®ããã§ãã
Object.keys(scene).forEach((key)=>{ Object.defineProperty(target, 'nested', { configurable: false }); });
THREE.Scene
ãæž¡ãå¿ èŠãããããæåéãã·ãŒã³ã°ã©ãå šäœã芳å¯å¯èœãªãã®ã®æ··ä¹±ã«ãªãããšãæãŸãªãå Žåã¯æ¬åœã«çŽ æŽãããã§ãã ãããŠãç§ã¯ãŸã å ã®ãªããžã§ã¯ããåãããšãã§ããããã«åºã¥ããŠåå¿ããããšãã§ããŸãã å®å šïŒ
ãŸã
ãããæ€èšããŠãã ããhttps://github.com/vuejs/vue/blob/v2.5.16/src/core/observer/index.js#L121
setval._isVue = true
ã¯ãvueç£èŠæé ããéããããšãã§ããŸããä»æ¥ãç§ã¯Vueãmapbox-glã®ãããã€ã³ã¹ã¿ã³ã¹ã芳å¯ãããã®åŸå¥åŠãªããšãèµ·ãããããããæãããªããšããã±ãŒã¹ã«ééããŸããã ãã ãããããã€ã³ã¹ã¿ã³ã¹ã¯vueã€ã³ã¹ã¿ã³ã¹éã§åãæž¡ãå¿ èŠããããŸãã
map._isVue = true
ãè¿œå ãããšãåé¡ã¯è§£æ±ºããŸããã
ãã¹ãããããªããžã§ã¯ãã®ããããã£ã¯ãªã¢ã¯ãã£ãã«ãªããŸãã
ååž°çã«å®è¡ããããšããŸãããã Maximum call stack size exceeded
ã§ãããããå€ãã®ã©ã°ãçºçããŸãã
@Mitrorightããã¯ååž°çã«è¡ãå¿ èŠããããŸãããã¢ãããŒããå®å šã«æ£ãããªãã£ãå¯èœæ§ããããŸãã
ããã§ã®åé¡ã¯ãVueãé
åãåŠçããæ¹æ³ã§ãã geoJsonData
ããããã£ãæ§æäžå¯ãšããŠããŒã¯ããã ãã§ã¯ãæ©èœããªãå¯èœæ§ããããŸãïŒããã«ã¯åé¡ããããŸãããããçç±ããæãäžããããšã¯ãããŸããã§ããïŒã
次ã®ãããªãã®ãè©ŠããŠãã ããã
function makeArrayNonConfigurable(objects)
{
objects.forEach((obj) =>
{
Object.keys(obj).forEach((key) =>
{
Object.defineProperty(obj, key, { configurable: false });
});
});
}
å¿ èŠãªã®ã¯ããã ããªã®ã§ã1ã¬ãã«ã ãæ·±ãããŸãã Vueã¯ãã¹ãããããªããžã§ã¯ãã®ããããã£ã調ã¹ãŸããã ãã ããæ§æäžå¯èœãšããŒã¯ãããããããã£ã®é åå ã®ãªããžã§ã¯ãã調ã¹ãŠããããã«èŠãããããçºçããŠããåé¡ãçºçããŸãã
ããã§ã10,000åã®ãªããžã§ã¯ããééãããšããã®é åãåããŠééãããšãã«æ°ç§éããããã§ãã£ãŒã³ããããšããäŒãããŸãã ããã¯ããã®ããŒã¿ãååŸããããã®ã³ã¹ãã®äžéšãšèŠãªãå¿ èŠããããŸãã ççŽã«èšã£ãŠããããã®ãªããžã§ã¯ããã¯ã©ã¹ã§äœ¿çšãïŒã³ã³ã¹ãã©ã¯ã¿ãŒãããããã·ãè¿ãã¯ã©ã¹ã䜿çšããŸãïŒãã¢ããªã±ãŒã·ã§ã³ã®åç¶æéäžã«è€æ°åããŒãããå Žåã¯ãäžæã®IDã§ãªããžã§ã¯ãããã£ãã·ã¥ããããšããå§ãããŸã-ã¹ãã³ã ããããããã¯å®éã«ã¯èšèšã®è©³çŽ°ã§ãããåââé¡ã«æ£ç¢ºã«é¢é£ããŠããããã§ã¯ãããŸããã
ç§ã¯ããã§è§£æ±ºçãèŠã€ããŸããïŒ
https://medium.com/@deadbeef404/tell -vue-js-to-stop-wasting-time-and-render-faster-7c3f7d2acaab
èŠããã«ãå¹çšé¢æ°ãäœãïŒ
import Vue from 'vue';
const Observer = (new Vue()).$data.__ob__.constructor;
export function makeNonreactive(obj) {
obj.__ob__ = new Observer({});
}
ããã«ã¡ã¯@Mitorightã åèãŸã§ã«ããã®èšäºã§ã¯vue-nonreactive
å
èã«ã€ããŠèª¬æããŠããŸãã éãã¯ãã³ãŒãããã©ã°ã€ã³ãšããŠïŒ vue-nonreactive
çµç±ã§ïŒäœ¿çšãããããã«ããŒé¢æ°ãšããŠäœ¿çšãããã§ãã ãŸãã vue-nonreactive
ã¯ããã®åé¡ã®èª¬æã®äžéšã«ããæŽæ°ã§èšåãããŠããŸãã
vue-devtoolãåã³æŽæ°ããããšã httpsïŒ //github.com/vuejs/vue/issues/2637#issuecomment-434154442ã«ãã£ãŠvue-devtoolãåã³ã¯ã©ãã·ã¥ããŸã
ãœãªã¥ãŒã·ã§ã³ã®ããã«vue-nonreactive
ãææ¡ããŸãð
__ob__
åæã§ããªãããã«ããã«ã¯ã defineProperty
䜿çšããŸã
vue-free.js
import Vue from 'vue'
const Observer = new Vue().$data.__ob__.constructor
function prevent(val) {
if (val) {
// Set dummy observer on value
Object.defineProperty(val, '__ob__', {
value: new Observer({}),
enumerable: false,
configurable: true,
})
}
return val
}
// vue global
Vue.VUE_FREE = prevent
// window
global.VUE_FREE = prevent
// default export
export default prevent
å³ç§ã¯ããã«ã€ããŠç§ã®2ã»ã³ããšè§£æ±ºçãäžããã§ãããã
Freezeã®æŠå¿µãšåœã®ãªãã¶ãŒããŒã®äž¡æ¹ãå®è£
ããéã«ãåæ§ã®åé¡ãçºçããŸããã ç§ã®ããŒã¿ã¯ãµãŒããŒããååŸãããååž°çãªTreeNodeã·ããªãªã§ãããã®å Žåãç§ã®ãããžã§ã¯ãã§ãvuexã䜿çšããŠãããçºçããåé¡ã«ã¬ã€ã€ãŒãè¿œå ãããŠããŸãã vues object.keysã«ãŒããåå ã§ãåžžã«Maximum call stack size exceeded
ãååŸããŸããã ããªãŒãºããŠåœã®VNodeå
ã§ããŒã¿ãèšå®ããããšããŸããããã©ã¡ããååž°ã®åé¡ãæ¢ããŠããªãããã§ãã
ç§ã¯ã€ãã«äžæ©äžãã£ãŠãå€å žçãªRevealing Module Patternã䜿çšããŠããéåå¿æ§ãã®ããããã£ãã©ããããŸãã
ããã¯ã¯ã©ã¹ïŒES6 / typescriptïŒã§ããããã¬ãŒã³ãã¥ãŒã«ãåãããšãé©çšã§ããŸã
import { first, forEach } from 'lodash';
export class TreeNode {
internalRefsInstance: () => { getParent: () => TreeNode; setParent: (parent: TreeNode) => void; getChildNodes: () => TreeNode[]; setChildNode: (childNode: TreeNode) => number; };
get visitedDate(): string | undefined {
return this._visitedDates.get(this.id) || undefined;
}
isSelectedTreeNode: boolean = false;
showSubheader: boolean = false;
showHelp: boolean = false;
treeNodeIconName: string = 'empty';
childTreeNodeCount: number = 0;
constructor(public id: string,
public componentName: string,
private _visitedDates: Map<string, string>,
public isActive: boolean = true,
public nextFlow?: string,
public prevFlow?: string,
parent: TreeNode | undefined = undefined) {
//invoke the internal refs module to create our static instance func to get the values from
this.internalRefsInstance = this.nonReactiveModule();
this.internalRefsInstance().setParent(parent);
}
nonReactiveModule = () => {
let _parent: TreeNode | undefined = undefined;
let _childNodes: TreeNode[] = [];
const _getParent = (): TreeNode | undefined => {
return _parent;
};
const _setParent = (parent: TreeNode | undefined): void => {
_parent = parent;
};
const _getChildNodes = (): TreeNode[] => {
return _childNodes || [];
};
const _setChildNode = (childNode: TreeNode): number => {
if (!_childNodes) {
_childNodes = [];
}
_childNodes.push(childNode);
return _childNodes.length;
};
const returnObj = {
getParent: _getParent,
setParent: _setParent,
getChildNodes: _getChildNodes,
setChildNode: _setChildNode,
};
return () => { return returnObj; };
}
getParent(): TreeNode | undefined {
return this.internalRefsInstance().getParent();
}
getChildNodes(): TreeNode[] {
return this.internalRefsInstance().getChildNodes();
}
setChildNode(childFlow: TreeNode): void {
this.childTreeNodeCount = this.internalRefsInstance().setChildNode(childFlow);
}
clone(parent: TreeNode | undefined = undefined): TreeNode {
const newInstance = new TreeNode(this.id, this.componentName, this._visitedDates, this.isActive, this.nextFlow, this.prevFlow, parent);
newInstance.showHelp = this.showHelp;
newInstance.showSubheader = this.showSubheader;
newInstance.isSelectedTreeNode = this.isSelectedTreeNode;
forEach(this.getChildNodes(), (flow: TreeNode) => {
newInstance.childTreeNodeCount = newInstance.internalRefsInstance().setChildNode(flow.clone(newInstance));
});
return newInstance;
}
setVisitedDates(visitedDates: Map<string, string>): void {
this._visitedDates = visitedDates;
forEach(this.getChildNodes(), (flow: TreeNode) => {
flow.setVisitedDates(visitedDates);
});
}
setAsSelected(setParent: boolean = true, setAllFirstChildren: boolean = true): void {
this.isSelectedTreeNode = true;
if (setAllFirstChildren) {
const firstChildFlow = first(this.getChildNodes());
if (firstChildFlow) {
firstChildFlow.setAsSelected(false, true);
}
}
if (setParent && this.getParent()) {
this.getParent()!.setAsSelected(setParent);
}
}
resetSelected(resetChildren: boolean = true): void {
this.isSelectedTreeNode = false;
if (resetChildren) {
forEach(this.getChildNodes(), (flow: TreeNode) => {
flow.resetSelected(resetChildren);
});
}
}
}
ç§ã®å ŽåãComputedã¯æ©èœããŸããã§ãããããã¯ãComputedã®å€æŽãéä¿¡ãããã³ãã©ãŒã§ã¯ãªããå®å šãªãªããžã§ã¯ããå¿ èŠã ã£ãããã§ãã å°ãªããšãããã£ãŒããŠã©ããã£ãŒãèšç®ããããµãã»ããåãããçµæã«å¯ŸããŠã©ã®ããã«æ©èœããããç解ããŠããªãå Žåã
ããã次ã®ã¬ãã«ã«åŒãäžããã®ã¯ãããã»ã¹ãã¹ããŒãã¢ããããããã«ãæ³šå ¥ãããéååž°çãªãã«ããŒãŸãã¯ãã³ã¬ãŒã¿ãŒãäœæããããšã ãšæããŸãã ã©ããªæçšãªãã£ãŒãããã¯ãçŽ æŽãããã§ãããã
誰ãããã§ã«ãã®åé¡ã解決ããããã§ãã
https://github.com/vuejs/vue/issues/4384ã§ãã¹ãŠã®è©³çŽ°ã確èªããŠ
ããã«ã¡ã¯ãç¹ã«ãã®ä»¥åã®åé¡ã«æ°ä»ããŠããªãã£ãã®ã§ãïŒ10265ãäœæããŸããã
å°æ¥ãèŠæ®ããŠããããã·ã䜿çšãããšãã«Vueãšã®äºææ§ãç¶æããããã«ãã©ã®ãããªè§£æ±ºçãæšå¥šãããã®ãçåã«æã£ãŠããŸãã
Object.defineProperty
ãconfigurable: false
Object.defineProperty
ãšäžç·ã«äœ¿çšãããšããŸããããŸãïŒãã ããæ¢åã®ã»ãã¿ãŒ/ã²ãã¿ãŒãæã€ããããã£ããªã¢ã¯ãã£ãã«ãªãã®ãé²ãããšã¯ã§ããŸããïŒã
ãã®ææ³ã¯Vue3ã§ãåŒãç¶ã䜿çšã§ããŸããïŒ
ããããšã
@ collin-guyon configurable: false
ã¯ãç¹ã«https://github.com/vuejs/vue-next/blob/d9c6ff372c10dde8b496ee32f2b9a246edf66a35/packages/reactivity/src/reactive.ts#L159ãããããã«èŠãããããããããæ©èœããŸãã
æ°ããææ¡ãããVue.observable
åæ§ã«ããªã¢ã¯ãã£ããªããžã§ã¯ãã«ããããã£ãèšå®ãããŠããå Žåããã®_new_å€ã¯æ±æãããããã®ãŸãŸã«ãªããŸãã 代ããã«ã_getter_ã¯ãã®ãªã¢ã¯ãã£ããããã·ãè¿ãããã£ãã·ã¥ã«ãŸã ååšããªãå Žåã¯ãããã·ãäœæããŸãã
幞ããªããšã«ããªã¢ã¯ãã£ããããã·ã§å€ãã®ããšãè¡ããªãéããããããåé¡ã¯ãªãã¯ãã§ãã ã¡ã¢ãªã®å æãçžäºéçšæ§ãæžå¿µãããå Žåã¯ããªããžã§ã¯ããäœã§ãããããã«ã€ããŠå¿é ããå¿ èŠã¯ãããŸãããã©ã€ãã©ãªããã®ããŒã¿ã®å·šå€§ãªã³ã¬ã¯ã·ã§ã³ããåå¿æ§ãé©çšãããå Žåã®åäœãäºæž¬ã§ããªãå€éšãªããžã§ã¯ãã§ãã âçµå±ã®ãšãããããã«ã€ããŠã¯äœã觊ããããŠããŸããã ãã®æå³ã§ãVue 3.xã¯ããã®æ©èœãä»ã®æ¹æ³ã§åœ¹ç«ã€å€ãã®ã³ãŒããŒã±ãŒã¹ãå®éã«è§£æ±ºããŸãã
çŸæç¹ã§ã¯ã vue-next
ã³ãŒãã¯ãçŸåšã®ããŒãžã§ã³ã®Vueãšåãããã«ãã·ã³ãã«ããŒãåå¿ããªãããã«é€å€ããŠããããã§ãã
ãããæ€èšããŠãã ããhttps://github.com/vuejs/vue/blob/v2.5.16/src/core/observer/index.js#L121
setval._isVue = true
ã¯ãvueç£èŠæé ããè±åºã§ããŸããä»æ¥ãç§ã¯Vueãmapbox-glã®ãããã€ã³ã¹ã¿ã³ã¹ã芳å¯ãããã®åŸå¥åŠãªããšãèµ·ãããããããæãããªããšããã±ãŒã¹ã«ééããŸããã ãã ãããããã€ã³ã¹ã¿ã³ã¹ã¯vueã€ã³ã¹ã¿ã³ã¹éã§åãæž¡ãå¿ èŠããããŸãã
map._isVue = true
ãè¿œå ãããšãåé¡ã¯è§£æ±ºããŸããã
_isVue
ãçã§ããããªããžã§ã¯ããVueã³ã³ããŒãã³ãã€ã³ã¹ã¿ã³ã¹ã§ãããšèŠãªããããVueéçºããŒã«ããã°ã¢ãŠããããŸã§ãã®ã¡ãœããã䜿çšããŠããŸããããããã§ã¯ãããŸããã
æ·±å»ãªå¯äœçšããªãã®ãç§ãèŠãå¯äžã®ããã¯ã¯ã vue-nonreactive
ã©ã€ãã©ãªã䜿çšããOPã®ã¢ãããŒãã®ããã§ãã
ããã«å¯ŸããV3ã®ä»£æ¿ãœãªã¥ãŒã·ã§ã³ã¯ãããŸããïŒ
@HunderlineK ShoulderRefãshallowReactiveãmarkRaw
æãåèã«ãªãã³ã¡ã³ã
data
å ã®ãªããžã§ã¯ã/é åã®ç£èŠãã¹ãããããå¿ èŠãããå Žåã¯ãObject.freeze()
ã䜿çšããŸããdata
ã§ããã«ã¢ã¯ã»ã¹ããããã«ãthis
ãcreated()
ããã¯ã®this
ã«æ¥ç¶ããã ãã§ã¯ããŸã£ãã芳å¯ãããŸããã