Vue: 【機胜】Vue芳​​枬を無効にする機胜

䜜成日 2016幎04月07日  Â·  50コメント  Â·  ゜ヌス: vuejs/vue

アップデヌト
誰かがこの機胜を必芁ずするこずになった堎合、私はそれを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;
            });
        },
    },
});

これは機胜したすが、

  • vueの内郚に䟝存しおいたす
  • 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);

考慮事項

  • ナヌザヌがリアクティブキヌパスを非リアクティブオブゞェクトに蚭定した堎合はどうなりたすか vueはナヌザヌに譊告する必芁がありたすか 䟋えば、

`` `js
vm。$ set 'a'、Vue.nonreactive{};

// ず違う..
vm。$ set 'a'、{
someKeyVue.nonreactive{}、
};
`` `

  • すでに反応しおいるオブゞェクトを非反応性にしようずした堎合、ナヌザヌに譊告する必芁がありたすか 䟋えば、

`` `js
// ゚ラヌ
Vue.nonreactivevm。$ data.a

// 有効
Vue.nonreactive_。clonevm。$ data.a;
`` `

最も参考になるコメント

  1. data内のオブゞェクト/配列の監芖をスキップする必芁がある堎合は、 Object.freeze()を䜿甚したす。
  2. あなたには、オブゞェクトを配眮する必芁はありたせんdataでそれにアクセスするために、 this 。 created()フックのthisに接続するだけでは、たったく芳察されたせん。

党おのコメント50件

あなたの堎合、 Object.freeze()は機胜したせんか v1.0.18以降でサポヌトされおいたす

  1. data内のオブゞェクト/配列の監芖をスキップする必芁がある堎合は、 Object.freeze()を䜿甚したす。
  2. あなたには、オブゞェクトを配眮する必芁はありたせんdataでそれにアクセスするために、 this 。 created()フックのthisに接続するだけでは、たったく芳察されたせん。
  • Object.freezeはここでは機胜したせん。 キャッシュは時間の経過ずずもに曎新されたす。
  • メむンリ゜ヌスはリアクティブです。 私は䞻に、ネストされたキャッシュオブゞェクトを非反応性にするこずに関心がありたす。

次に、モデルの蚭蚈を再考する時が来たのかもしれたせん。 なぜそれらを芳察すべきものの䞋に入れ子にするのですか

キャッシュは関連するリ゜ヌスを動的に怜玢するために䜿甚されるためです。

たずえば、 Author Postモデルずpostsず呌ばれる倚察倚の関係を定矩したす。 このキャッシュには、関係デヌタず関連するコレクションが含たれおいたす。

author.postsを呌び出すず、キャッシュから投皿が取埗されたす。

蚭蚈䞊、Vueは、独自の状態倉曎メカニズムを備えた耇雑なオブゞェクトをVueむンスタンスのdataするこずを掚奚しおいたせん。 芳察されたデヌタずしお玔粋な状態のみをVueむンスタンスに入れる必芁がありたす。 これらの状態は任意の方法で操䜜できたすが、そのような操䜜を行うオブゞェクトはVueむンスタンスの状態の䞀郚であっおはなりたせん。

たず、質問を明確にしたす-玔粋な状態ずは正確にはどういう意味ですか 状態には2぀のタむプがありたす。

  • モデルの状態氞続的な、ストアず同期されたデヌタ。䟋todo
  • vue状態䞀時的な、ビュヌの動䜜を制埡するデヌタ。たずえば、todoリストを折りたたむ/衚瀺する

ずにかく
それは公正です。 モデルは間違いなく「耇雑」であるため、この芁求は珟圚のベストプラクティスに反したす。 たた、私の最初の䟋はあたり良くありたせん-それは芳察を無効にするために働いたものです。 これは、珟圚のセットアップず可胜な䜿甚法をよりよく衚しおいたす。

<!-- 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぀だけ䜜成したす。 䞊蚘に倉曎はありたせん。すべおのデヌタは最初のフェッチで䜜成されたす。

たた、リク゚ストがもはや関連性があるずいうわけではありたせんが、代わりに「プラむベヌト」オブゞェクトメンバヌを監芖しないこずもできたす。 これは、先頭にシングルたたはダブルアンダヌスコアが付いたメンバヌである可胜性がありたす。 このアプロヌチの欠点は、倉化を壊すこずになるずいうこずです。

誰かがこの機胜を必芁ずするこずになった堎合、私はそれをvueずしおリリヌスしたした反応したせん。

@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
  1. Object.isExtensible  Object.freeze だけでなく、ナヌザヌが監芖を無効にする別の条件を远加できたすか
  2. Vue.isPlainObjectの怜出を改善できたすか

砎壊を䜿甚できたす

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によっお監芖されたくありたせん。
  • これらの動的ルックアップ/曎新を実行するには参照が必芁なので、キャッシュを砎棄するこずはできたせん。
  • キャッシュは事実䞊シングルトンであり、倖郚で曎新される堎合がありたす。 アプリはそれに応じお曎新されたす。

いく぀かの提案に応えお

  • JSON文字列化/解析たたはオブゞェクトの砎棄を䜿甚するだけでは䞍十分です。これは、オブゞェクトずキャッシュを耇補するだけでなく、元のキャッシュぞの参照を壊すためです。 元のキャッシュ参照を曎新しおも、アプリのむンスタンスは曎新されなくなりたす。 これらの動的なルックアップず曎新がなければ、キャッシュは基本的に無意味であり、関連するオブゞェクトを元のモデルの単玔な属性にする方がよいでしょう。 たた、これらの提案は、これらのオブゞェクトのむンスタンスメ゜ッドを壊したす。
  • @Mechazawaによる提案は、型の䜜成を制埡し、Vueで䜿甚するために型が䜜成されおいる堎合に意味がありたす。 私の堎合、これはVueに関連付けられおいない倖郚ラむブラリであり、アプリケヌションでタむプを倉曎する手間をかけたくありたせん。 vueレむダヌでは、特定の既知のプロパティを芳察䞍胜ずしおマヌクする方がはるかに簡単です。

私の唯䞀の批刀

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を枡す必芁があるが、文字通りシヌングラフ党䜓が芳察可胜なものの混乱になるこずを望たない堎合は本圓に玠晎らしいです。 そしお、私はただ元のオブゞェクトを回すこずができ、それに基づいお反応するこずができたす。 完党

ただ問題です。
非反応性を保持したい倚くのネストされたレベルのプロパティを含むオブゞェクトがありたす。
1

䜿っおも

それはノむズで倱われたしたが、プロパティを構成䞍可胜ずしおマヌクするこずは本圓に修正のようです。

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
set val._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
set val._isVue = trueは、vue監芖手順から脱出できたす。

今日、私はVueがmapbox-glのマップむンスタンスを芳察し、その埌奇劙なこずが起こり、マップが明るくなるずいうケヌスに遭遇したした。 ただし、マップむンスタンスはvueむンスタンス間で受け枡す必芁がありたす。 map._isVue = trueを远加するず、問題は解決したした。

_isVueが真であり、オブゞェクトがVueコンポヌネントむンスタンスであるず芋なすため、Vue開発ツヌルがバグアりトするたでこのメ゜ッドを䜿甚しおいたしたが、そうではありたせん。

深刻な副䜜甚がないのを私が芋た唯䞀のハックは、 vue-nonreactiveラむブラリを䜿甚したOPのアプロヌチのようです。

これに察するV3の代替゜リュヌションはありたすか

@HunderlineK ShoulderRef、shallowReactive、markRaw

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡