10/20

22013 ワード


Vueインフラストラクチャコースの復習


Ref : https://www.inflearn.com/course/vuejs/


1. $nextTick()


:コールバック関数をパラメータとして次のDOM更新サイクルに渡して実行します.データ変更後に使用する必要があります.
  • ソースコード使用
  • //Card.vue
     <header slot="header" class="cardView__header">
       		//1. isEditTitle === true
                    <b-form-input
                        v-model="inputTitle"
                        placeholder="타이틀을 입력하세요:-)"
                        class="cardView__inputTitle"
                        v-if="isEditTitle"
                        ref="inputTitle"
                    ></b-form-input>
    		//2. isEditTitle === false
                    <span class="cardView__title" v-else @click="setEditTitle">
    			{{card.title}}
                  	</span>
    </header>
  • v-ifディレクトリとisEditTitle変数を使用して、「input」と「span」タグを交互に表示します.
  • //Card.vue methods
    setEditTitle() {
                this.isEditTitle = true;
                this.inputTitle = this.card.title.trim();
                //this.$refs.inputTitle.focus(); //1.
                this.$nextTick(() => {	     //2.
                    this.$refs.inputTitle.focus();
                });
    }
  • $nextTick未使用の場合、inputタグを「$refs」で参照できません.=>DOMをレンダリングするためにisEditTitleを変更した場合と比較して、//1です.理由は2行目がもっと早く運行していたから!!
  • そのためthis.$このローをコールバック関数としてnextTick()に渡し、次のDOM更新後に実行します.
  • カード修正ロジック
  • ドレッシング
  • //Card.vue
    onEditCard() {
                const listId = this.card.listId;
                const title = this.inputTitle.trim();
      	   //1.
                const description = this.inputDesc.length ? this.inputDesc.trim() : null;
                const id = this.cid;
    
      	   //2.
                if (!this.inputTitle.length) {
                    alert("카드 제목을 입력해주세요!");
                  	//3.
                    this.inputTitle = this.card.title;
                    this.$nextTick(() => this.$refs.inputTitle.focus());
                    return false;
                }
    
      	    //4. 
                this.UPDATE_CARD({ id, title, listId, description })
                    .catch((err) => console.error(err))
                    .finally(() => {
                 	 this.restoreEdit();
                  	 //7.
                  	 this.fetchData();
                });
            },
    
    //actions.js
    UPDATE_CARD({ dispatch, state }, { id, title, description, listId, pos }) {
      	//5.
            const payload = { title, description, listId, pos };
      
            return api.card
                .update({ id, payload })
                .then(() => {
              	//6.
                    dispatch("FETCH_BOARD", { id: state.board.id });
                })
                .catch((err) => Promise.reject(err));
        },
              
  • descriptionは、ペイロードを構成するときに、入力値が空のときに空の値で渡すために作成される行です.
  • タイトル無しを除く
  • inputTitle既存データにタイトルを割り当て、DOM更新後にnextTick()を使用してフォーカスを移動する.
  • Storeメソッドを使用して、修正APIを呼び出す.
  • 受信したデータを用いてペイロード対象を組織し、データ転送を簡素化する
  • カード修正完了後、dispatch()を使用して基板データをサーバから再インポートし、基板素子を更新する.
  • これと同様に、現在のカードコンポーネントもサーバからデータを取得することでデータを更新する.
  • 3.カードのドラッグ&ドロップを実施する


  • 使用ライブラリ:https://github.com/SortableJS/Vue.Draggable

  • 使用例
  • //List.vue
     <draggable
                class="list-item__cardList list-group" //1.
                :list="data.cards"			   //2.
                :data-list-id="data.id"
                draggable=".card-item"		   //3.
                group="cardItem"			   //4.
                @end="onEnd"			   //5.
            >
                <card-item
                    v-for="card in data.cards"
                    :data="card"
                    :key="card.pos"
                />
            </draggable>
  • 適用ライブラリで提供される「list-group」クラス.
  • :リストに配列形式のデータをバインドする.
  • ドラッグ可能な属性にドラッグするクラスを設定します.
  • groupはよくわかりませんが、該当しないとドラッグアンドドロップできません…!
  • @endイベントとイベントハンドルonEnd
  • イベントハンドル、イベントハンドルに渡されるオブジェクト
  • : https://github.com/SortableJS/sortablejs#event-object-demo
    onEnd(event) {
      	    //1. 2.
                const { to, item } = event;
    
                const listId = to.dataset.listId;
    
                const currentCard = {
                    id: item.dataset.cardId * 1,
                    pos: 65535,
                    listId: listId * 1,
                };
            },
  • to:配置されたドラッグ可能エレメントレイヤー
  • item:ドラッグしたエンティティ(ここでは「.card-item」)
    =>*注意事項:「.card-item」、ドラッグするエンティティの:キーが重複してエラーが発生した場合、itemを正しく選択できません!!
  • from:リスト間移動時に既存のドラッグ可能エレメント
  • newIndex:to Ellientを基準としてEllientのインデックス値
  • card-item:鍵重複エラー防止のためにカード生成ロジックを修正
  • //AddCard.vue
    const pos = this.getPos();
    
    getPos() {
      	    //1.
                const list = this.board.lists.filter(
                    (b) => b.id === this.listId
                )[0];
      	    //2.
                const lastCard = list.cards[list.cards.length - 1];
      	    //3.
                return lastCard ? lastCard.pos * 2 : 65535;
            }
  • storeはboardデータをインポートし、現在属するlistのid値からlistデータをインポートします.
  • listをインポートしたcards propertyから最後のcardデータを取得する.
  • 2番にインポートしたカードがあれば、インポートしたカードのpos値に2を乗じた値を返し、なければデフォルトのpos値65535を返します.
  • 体得:教室で使われているdragライブラリを使わず、一人で新しいライブラリを使って機能を学ぶのは面白くて、難しいですが、喜んでいます:-)
    講義で使用する方法を現在のライブラリと組み合わせて使用する予定です.

    * Reference


    1. Vue.nextTick : https://kr.vuejs.org/v2/api/index.html#Vue-nextTick