ホームページ > 記事 > ウェブフロントエンド > Vue で props を使用してデータに初期値を割り当てるときに発生する問題と解決策
この記事の内容は、Vue で props を使用してデータに初期値を割り当てるときに発生する問題と解決策についてです。必要な友人が参考になれば幸いです。あなたは助けてくれました。
以前、運用活動のためのプロジェクトに取り組んでいたのですが、プロジェクトの立ち上げ後、調査中に、問題の原因が初期値にあることがわかりました。 Vue のデータの初期値は props から取得されます。説明の便宜上、問題は次のように抽象化されます。
1. 現象
コード:
nbsp;html> <meta> <title>用props初始化data中变量</title> <script></script> <div> <user-info></user-info> </div> <script> //全局组件 let userInfo = Vue.component('userInfo' ,{ name: 'user-info', props: { userData: Object }, data() { return { userName: this.userData.name } }, template: ` <div> <div>姓名:{{userName}} <div>性别:{{userData.gender}} <div>生日:{{userData.birthday}} ` }); //Vue实例 new Vue({ el: '#app', data: { user: { name: '', gender: '', birthday: '' } }, created(){ this.getUserData(); }, methods:{ getUserData(){ setTimeout(()=>{ this.user = { name: '于永雨', gender: '男', birthday: '1991-7' } }, 500) } }, components: { userInfo } }); </script>
コードの解釈:
ルート コンポーネント データにはオブジェクトがあり、名前、性別、誕生日の 3 つの属性が含まれています。
ページ 初期化後、名前、性別、誕生日がすべて空として表示されます。500 ミリ秒後、性別と誕生日は通常の結果のみを表示します。名前は変わりません。
なぜそうなるのでしょうか?私の最初のアイデア: user.name は基本データ型に属し、これを使用して子コンポーネント データの userName に値を割り当てます。これは基本データ型の割り当てに属します。したがって、親コンポーネントの user.name が変更されても、サブコンポーネントの userName はそれに応じて変更されません。 #########そうですか?そこで、user.name をオブジェクトに変更し、データ型への参照によって値を割り当て、それが期待どおりかどうかを観察することにしました。コードは次のとおりです。
nbsp;html> <meta> <title>用props初始化data中变量-对象形式</title> <script></script> <div> <user-info></user-info> </div> <script> //全局组件 let userInfo = Vue.component('userInfo' ,{ name: 'user-info', props: { userData: Object }, data() { return { userName: this.userData.name } }, template: ` <div> <div>姓名:{{userName.text}} <div>性别:{{userData.gender}} <div>生日:{{userData.birthday}} ` }); //Vue实例 new Vue({ el: '#app', data: { user: { name: {text: ''}, gender: '', birthday: '' } }, created(){ this.getUserData(); }, methods:{ getUserData(){ setTimeout(()=>{ this.user = { name: {text: '于永雨'}, gender: '男', birthday: '1991-7' } }, 500) } }, components: { userInfo } }); </script>
実行結果: 名前にはまだ値がありません。最初の結果と同じです。 ! !
2. 理由
それでは、その理由は何でしょうか?その後、友人と話し合ったときに、「初期化中にデータが深くコピーされているからではないでしょうか?」と尋ねられたことがありました。 この説明の方が信頼できると思うので、証拠を集めに行きました。まず、Vue の公式 Web サイトにアクセスして、データに関するドキュメントを読みました。
「再帰的」という単語を見た場合、ディープ コピーの中心原理は再帰であるため、基本的には上記の推論が正しいと結論付けることができます。 Vue は初期化中にデータのすべてのプロパティを再帰的に走査し、Object.defineProperty を使用してこれらすべてのプロパティを双方向バインディングのゲッター/セッターに変換することがわかりました。
公式ドキュメントの Reactivity in Depth の章で明確に述べられています:
Vue が IE8 をサポートしない理由も説明されています: IE8 Object.defineProperty はサポートされていません。
3. 解決策データのディープ コピーによりプロパティの変更に応じてデータを更新できないため、Vue 関数では当然 2 つの監視関数: watch と computed## が考えられます。 #。
コードを次のように変更し、結果を確認します。nbsp;html> <meta> <title>解决方案:watch、computed</title> <script></script> <div> <user-info></user-info> </div> <script> //全局组件 let userInfo = Vue.component('userInfo' ,{ name: 'user-info', props: { userData: Object }, data() { return { userName: this.userData.name } }, computed: { computedUserName(){ return this.userData.name } }, watch: { 'userData.name': function (val) {//监听props中的属性 this.userName = val; } }, template: ` <div> <div>姓名(watch):{{ userName }} <div>姓名(computed):{{ computedUserName }} <div>性别:{{ userData.gender }} <div>生日:{{ userData.birthday }} ` }); //Vue实例 new Vue({ el: '#app', data: { user: { name: '', gender: '', birthday: '' } }, created(){ this.getUserData(); }, methods:{ getUserData(){ setTimeout(()=>{ this.user = { name: '于永雨', gender: '男', birthday: '1991-7' } }, 500) } }, components: { userInfo } }); </script>
# #完璧 ! ! !
4. 概要: Vue の props に関する重要なポイントその後、props に関するドキュメントを注意深く読みました。
## 簡単に要約しましょう: 1. Props は一方向のデータ フローです。親コンポーネントのデータ変更は、Props を通じて子コンポーネントにリアルタイムで反映され、その逆も同様です 2 . サブコンポーネント内の props の直接操作は許可されていません
3. Props は偽装して操作できます (1) データ内でローカル変数を宣言し、それらを props で初期化します。 ## 欠点: ローカル変数は従わない プロパティが更新されると更新
(2) 計算されたプロパティの値を変換して出力以上がVue で props を使用してデータに初期値を割り当てるときに発生する問題と解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。