Vue.js実践(3):きれいで柔軟で多重化可能なヒントコンポーネントを実現


今回のチュートリアルでは、コンポーネント化を最後まで行います!最近の半年のいくつかのプロジェクトでは、ToastまたはNotificationコンポーネントを使用する必要がある場合があります.現在存在するいくつかのVueに基づく.jsが開発したコンポーネントライブラリは、あまり適切ではないので、自分で1つ実現しました.いくつかのプロジェクトの磨きを経て、このヒントコンポーネントの機能はますます完備しています.今回はコンポーネントとその実現構想を共有しましょう.
GitHub倉庫:https://github.com/Yuyz0112/vue-notieDemoアドレス:http://lab.myriptide.com/vue-notie/

コンポーネント化、コンポーネントの分割、統合、多重化


Vue.jsのコンポーネント化はその看板特性の一つと言えるが,実際の応用では,コンポーネント粒子が小さいほどよいという追求ではなく,プロジェクトの実際のニーズに基づいて,自分がどのレベルのコンポーネントを必要とするかを分析する必要がある.
たとえば、1つのSPAでは、ホームページ、記事リストページ、記事ページ、パーソナルセンターページの4つの主要なビューがある可能性があります.そこで、それぞれ対応するものを4つのコンポーネントに書きます.
しかし,実際に作成する過程で,同じサイドバーセットを共用していることが分かったが,サイドバーに対応するコードも4つのコンポーネントで4回繰り返し書かれている.したがって、サイドバーを単独でコンポーネントとして多重化することができます.
その後、フォームやボタンなどのコンテンツをコンポーネントに多重化できることがわかります.しかし、実際には、過度なコンポーネント化がコード量の上昇、開発時間の増加、追加のデータ転送などをもたらすこともわかります.したがって、完全なコンポーネントライブラリを作成するつもりがない場合は、実際のプロジェクトで必要に応じて分割、統合を行うことができ、多重化可能な各部分を単一のコンポーネントとして過度に追求する必要はありません.

なぜヒントコンポーネントが必要なのか


alertのほとんどの時間は私たちのニーズを満たすことができないからです.往々にしてプロジェクトにはalertのようなものが必要であり、美しくカスタマイズ可能な方法でユーザーにいくつかの情報を提示するため、このような提示コンポーネントが必要です.
同時に、同じ時間に複数のプロンプトがユーザを混同することを望んでいないため、設計上、アプリケーション全体で各ビューが同じプロンプトコンポーネントを呼び出す一意性を持つようにプロンプトコンポーネントを設定します.

Show me the code


次に,ヒントコンポーネントの各機能を簡略化繁により順次実現する.

きほんきのう


最も基本的な機能はもちろんトリガ後に表示され、何らかの方法で閉じることができる.カスタマイズが必要な唯一の部分は、具体的に表示される内容です.最初のコンポーネント長は次のようになります.



export default {
  props: {
    options: {
      type: Object,
      default: () => {
        return {}
      }
    },
    show: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    close () {
      this.show = false
      this.options = {}
    }
  }
}



構想は簡単で、propsは2つのデータを伝達し、showは表示を制御し、optionsはコンテンツを含むカスタムコンテンツを伝達する.ヒントの表示をより自然にするために、スライドして入るtransitionと離れるtransitionを追加しました.
注意:ここの閉じるボタンはcssで実現され、あなたのプロジェクトに対応するiconがあれば、それを置き換えることができます.
ここでは、slotを使用してコンテンツの転送を行うこともできますが、後で他のパラメータがコンポーネント内に転送される必要があることを考慮して、一度に1つの統一されたオブジェクトoptionsで転送します.

カスタムスタイル


通常、ヒントの内容は種類が多く、成功ヒントもあれば、警告もあれば、エラーもあります.そのため、異なるスタイルを定義して、異なる内容を表現する必要があります.方法は簡単で、optionsにバックグラウンド色とテキスト色の2つのパラメータを入力し、コンポーネントで入力されたスタイルパラメータが検出された場合、デフォルトのスタイルを置き換えます.
Vue.jsはダイナミックスタイルを処理するときに非常に柔軟で、コードをより明確にするために、ダイナミックスタイルをインラインするのではなく、計算プロパティsetStyleを単独で使用して設定します.
computed: {
  setStyle () {
    return {
      color: this.options.textColor || '#fff',
      background: this.options.backgroundColor || '#21e7b6'
    }
  }
}

これにより、optionsにtextColorとbackgroundColorの2つのプロパティを一括して入力すれば、プロンプトスタイルを簡単にカスタマイズできます.

自動オフ


多くの場合、コンポーネントは自動的に閉じるモードを拡張する必要があります.同様に、「データ駆動」の考え方の下で、このプロンプトが自動的に閉じられるかどうかを示すデータを提供する必要があります.
optionsのautoClose属性がこの役割です.同様に、自動オフの遅延時間もカスタマイズできることは明らかであり、showTimeという属性も一緒に追加されています.
自動オフ自体は複雑ではありません.settimeoutを使用してタイマーを定義するだけです.
まず、リスナープロンプトコンポーネントの表示です.
ここでは、watchでoptionsの変化を監視することでタイマーを処罰します.タイマーを閉じるcloseメソッドを定義し、閉じるときにshowとoptionsの値をリセットしたので、optionsが変化するときは、optionsのautoCloseがtrueであるかどうかを判断するだけで、タイマーを起動する必要があるかどうかを知ることができます.ここではcountdownメソッドを単独で使用してタイマ関連の動作を処理する.
新しいコードは次のとおりです.
data () {
  return {
    timers: []
  } 
},
methods: {
  countdown () {
    if (this.options.autoClose) {
      const t = setTimeout(() => {
        this.close()
      }, this.options.showTime || 3000)
      this.timers.push(t)
    }
  }
},
watch: {
  options () {
    this.timers.forEach((timer) => {
      window.clearTimeout(timer)
    })
    this.timers = []
    this.countdown()
  }
}

注意深く見ると、このコードには奇妙な処理があることがわかります.空の配列timersを定義し、1つのタイマを開始するたびにタイマを配列に格納し、optionsが変化するたびにtimersからすべてのタイマを巡回してキャンセルし、その後timersをクリアします.
この方法は,主に1つのタイマがまだ終了していないときに,新しいプロンプトによるプロンプトが早期に閉じられるクリアを開始することを避けるためである.例えば、このような処理がなければ、自動的に閉じるプロンプトを発行し、自動的に閉じる前に新しいプロンプトを発行する.では、最初のプロンプトのタイマは、新しいプロンプトを誤って閉じます.
このような問題は、主に私たちのすべてのタイマーが同じコンポーネントにあり、本質的に同じヒントであるため、衝突を避けるためにタイマーをクリアする必要があります.多くのコンポーネントライブラリで同様の機能コンポーネントは、各プロンプトがプロンプトコンポーネントを新たに生成する方法で実現されます.しかしそのように複数のヒントが連続して現れると,積み重ねられ,それぞれが離れる場合がある.
以前のバージョンでは、私のヒントコンポーネントも同様の設計を採用していましたが、最近のプロジェクトでは、半透明のヒントコンポーネントを実現する必要があり、積み重ねてヒント文字が見えない現象が発生し、現在の新しいモードを使用しました.

さらに拡張


続いて、自動オフモードでのカウントダウンバー機能を拡張しました.考えの上でVueを使っていません.jsのtransitionシステムではなく、Css 3自体のアニメーションシステムを採用しています.自動クローズのプロンプトが初期化されると、タイミングバーにスタイルが追加され、X軸の負方向に100%移動し、transition時間は属性対応設定を計算します.具体的な実装はソースコードを参照することができるが,ここではあまり説明しない.

柔軟性の向上


最後に、プロンプトコンポーネントをより柔軟にすることです.時には、スタイルをカスタマイズできるテキスト、またはハイパーリンク、さらに多くを示したい場合があります.Vuejsはあまり簡単に実現しないでください.アセンブリ内のレンダリングに使用する{{ options.content }}{{{ options.content }}}に変更するだけで、3重カッコのテンプレートに対してVue.jsは、HTMLラベルを通常の内容でレンダリングします.
これにより、任意のHTMLコンテンツをヒントに入れることができます.もちろん、ユーザーが入力した内容を3重カッコのテンプレートにレンダリングしないように注意し、XSS攻撃を回避してください.

結合vuex


多くの場合、ヒントコンポーネントをAppに導入します.vueというルートコンポーネントですが、ヒントを与えるのはコンポーネントツリーのいずれかのコンポーネントかもしれません.コードに様々なdispatchやbroadcastが広がりたくない場合は、vuexを導入して管理するのが良い方法です.
大まかな考え方は以下の通りである.
// store.js
const state = {
  show: false,
  options: {
    autoClose: false,
    content: 'notice content'
  }
}

const mutations = {
  NEW_NOTICE (state, options) {
    state.show = true
    state.options = options
  },
  CLOSE_NOTICE (state) {
    state.show = false
    state.options = {}
  }
}

// actions.js

export const newNotice = ({dispatch}, options) => {
  dispatch('NEW_NOTICE', options)
}
export const closeNotice = ({dispatch}) => {
  dispatch('CLOSE_NOTICE')
}

// Notification.vue

vuex: {
  getters: {
    show: state => state.show
    options: state => state.options
  },
  actions: {
    close: closeNotice
  }
}

//     notice   

vuex: {
  actions: {
    notice: newNotice
  }
}

vuexを導入した後、上記のコードに従って構成すれば、いずれかのコンポーネントでthis.notice({options})を用いてデータを転送することができる.しかし、vuexの単一のデータフロー特性のため、stateデータに対するすべての操作はactions呼び出しmutationsによって実現されなければならない.プロンプトコンポーネントのcloseメソッドもactionsのcloseNoticeメソッドに置き換える必要がある.

総括する


このヒントコンポーネントを通じて、私たちはVueをもっと上手にマスターしました.jsのコンポーネントシステム、データ転送、計算プロパティ、transitionアニメーションなどの特性.また、このコンポーネントは本番環境で直接使用できます.star、fork、prを歓迎します.