vue開発の過程でよく出会う問題の総括、乾物!


vue開発過程でよく遭遇する問題の総括
1.props一方向バインド
vueのpropsは一方向にバインドされており、親コンポーネントの属性が変化するとサブコンポーネントに渡されます.サブコンポーネントの内部でpropsの値を変更するべきではありません.そうしないと、コンソールから警告が表示されます.
ただし、propsのタイプが配列またはオブジェクトの場合、サブコンポーネント内でpropsの値を変更するコンソールは警告しません.配列またはオブジェクトがアドレス参照であるため、vueはpropsの変更を検出しません.したがって、サブコンポーネントの内部で親コンポーネントの値を変更する必要がある場合があります.プロパティを配列またはオブジェクトタイプの入力として定義できます.
しかし、政府は、vueにおけるpropsの一方向バインドの考え方に違反するため、サブコンポーネント内で親コンポーネントの値を変更することを提案していません.
2.オブジェクトに値を割り当てる
1から、アドレス参照タイプのデータ、例えばオブジェクトobj={a:1}が、objにおけるa属性を変更するにはobjを通過することができる.a=2このように値を割り当てると、ページは更新されず、vueを使用する必要がある.setメソッドの変更が機能しますVue.set(this,obj,a,2)またはthis.$set(obj,'a',2);
同様に、objに新しい属性を追加する場合は、dataに宣言されていない場合、ページもリフレッシュされません.つまり、vueドキュメントで宣言する「Vueはオブジェクト属性の追加や削除を検出できない」ということで、同様にvueを使用する必要がある.setまたはthis.$setメソッドは付与してこそ使いやすい.
3.配列またはオブジェクトを深くコピーする
オブジェクトまたは配列の単純な割り当てでは、新しい値を変更しても元の値が変更されます.この場合、元の値の深いコピーオブジェクトを取得する必要があります.
オブジェクトについてはnewObj=JSON.parse(JSON.stringfy(obj))が実現します.
配列については、newArr=[...arr]またはnewArr=arr.slice(0)によって実現することができる.
4.コンポーネントに独自のスタイルを追加
vueの各コンポーネントは、それぞれのcssスタイルをカスタマイズできます.コンポーネント内のスタイルが現在のコンポーネントにのみ機能する場合は、styleラベルにscopedを追加できます.
この書き方では、vueはコンポーネントをレンダリングするときに各要素にdata-v-/バージョン番号/の属性を追加し、同じdata-v-data-v-/バージョン番号/の要素のみにこのスタイルを適用することを保証します.
5.v-forループキー属性
vueのv-forループにkeyプロパティを追加すると、高バージョン(2.2.0+)のvueでコンソールがエラーを報告します.
keyプロパティには一意が必要です.理想的なkey値は、各アイテムに一意のidがあり、グローバルには一意は必要ありませんが、1つのサイクルで一意が必要です.
6.引用画像
画像参照の問題.ローカルの画像アドレスをsrcに直接置いても大丈夫です.しかし、アドレスを抽出してdataに書くか、methodでsrcに動的に値を割り当てると参照できません.
templateテンプレートに置くとwebpackでパッケージ化されるので可能ですが、dataや動的付与に置くと、ピクチャパスは文字列だけでwebpackは処理されないので参照できません.
解決策:importまたはrequiredによって導入されます.import src from ‘../../img.png'またはdata:{img:require('..//../img.png')}
7.親コンポーネントの評価
サブコンポーネントが親コンポーネントから入力された値を使用する場合は、dataまたはcomputedによって付与されるpropsの値をコピーすることが望ましい.
data付与とcomputed付与の違い:
data付与:data:{return{aaa:this.aaa}dataで付与されている場合、親コンポーネントのaaa値が変更された場合、サブコンポーネントのaaaに再付与されません.
computed付与:サブコンポーネントを親コンポーネントに従って変更するには、付与操作をcomputedに書く必要があります.computed:{aaa(){return this.aaa}
8.オブジェクト配列の深度リスニング
バックエンドから渡される配列は配列オブジェクトであり、ページにはオブジェクトの特定の属性がバインドされ、その値が変化すると関数が呼び出され、自然にwatchメソッドと考えられる.しかし、watch配列オブジェクトの特定の属性をどのように書くかは、明らかに1つの属性にwatchを書くことはできません.
解決策:
1.watchはオブジェクト全体でdeepをtrueに設定し、オブジェクトが変更されたときに処理関数を呼び出す.
2.ページにバインドされた属性をcomputed関数に書き、watchというcomputedの関数は、オブジェクト値が変化するとcomputed関数に入り、さらにwatch関数に入り、処理関数を呼び出す.
9.classを動的に追加
要素にclassを動的に追加する場合は、テンプレートにclass={'hasClass’:ifHasClass}を使用して実装できます.ifHasClassがtrueの場合、その要素にhasClassのスタイルが自動的に追加されます.
動的にバインドされたclassは、通常の書き込みとともに使用できますが、1つの要素で2つのclassを使用するとエラーが表示されます.
10.コンポーネントでのタイマーの使用および問題の破棄
ページAでタイマーを使用している場合、ページAからページBにジャンプしたときに、手動でタイマーをクリアしないと、まだ実行されます.これは私たちが望んでいることではありません.
一般的に考えられる一般的な解決策は、dataプロパティにtimerを定義し、コードでタイマを起動し、コンポーネントが破棄されたときにタイマをクリアすることです.具体的なコードは以下の通りです.
data(){ 
    return{ timer:null } 
}, 
methods:{ 
    onStartTimer(){    
        this.timer = setInterval( () => { 
        //        
        }, 1000) } }, 
    beforeDestroy() { 
        clearInterval(this.timer); 
        this.timer = null;     
    }
}

しかし、ここには2つの潜在的な問題があります.
  • このコンポーネントインスタンスにこのtimerを保存する必要があります.できればライフサイクルフックだけがアクセスできることが望ましいです.これは深刻な問題ではありませんが、雑物と見なすことができます.
  • 私たちの確立コードは私たちの整理コードとは独立しており、私たちが確立したすべてのものをプログラム的に整理するのは難しいです.

  • Vueの公式ドキュメントでは、timerを定義するときに$once命令を使用してbeforeDestroyというフック関数をリスニングするソリューションが提供されています.具体的なコードは次のとおりです.
     methods:{ 
        onStartTimer(){ 
            const timer = setInterval( () => { 
            //        }, 1000)
            this.$once('hook:beforeDestroy', () => {
                 clearInterval(timer); 
            }) 
        } 
    },

    これにより、上記の2つの問題が解決されます.この方法は、ページを離れるときに破棄する必要があるコンポーネントと同様に使用できます.
    11.ローカル開発のドメイン間問題
    バックエンド・サーバ・インタフェースをローカルで開発する場合、ドメイン間で問題が発生することは避けられません.解決策は、node中間層またはnginxを逆エージェントとして追加することによって行うことができる.しかし、vue-cliで構築されたプロジェクトであれば、vue-cliはconfigにproxyTable属性を持っており、この属性を構成してドメイン間の問題を解決することができます.
    // config/index.js
    module.exports = {
    // ... 
        dev: {
    	proxyTable: { 
    	    '/api': { //   /api         ,        ,   url   /api  
    		target: 'http://jsonplaceholder.typicode.com', //      
    		changeOrigin: true, //       
    		pathRewrite: {
    		    '^/api': '' //      /api   ''
    		}
    	    }
            }
        }
    }

    以上のコードは、/api/posts/1リクエストエージェントをhttp://jsonplaceholder.typicode.com/posts/1.
    各インタフェースに/api識別子を手動で追加したくない場合は、axiosのデフォルト構成axiosを変更できます.defaults.baseURL='/api'で、axiosはurlに/apiの接頭辞を自動的に追加します.
    特に、構成を変更した後、serverを再起動する必要があることに注意してください.
    本文の内容は最初の内容から参考にして、ブログに移ってみんなと自分で勉強します!
    参照先:https://www.toutiao.com/a6670480302428652040/?tt_from=copy_link&utm_campaign=client_share×tamp=1553136328&app=news_article_lite&utm_source=copy_link&utm_medium=toutiao_ios&group_id=6670480302428652040