Element-uiに倣って簡単な$message方法を実現します。
前言
ユーザーに対して提示が必要な場合、このような場面に遭遇することがあります。モダリティボックスを使ってあまりにもハード核を提示し、toastヒントを使うのはまた軽すぎます。この時はページの上部を使ってスライドしたメッセージメッセージを選択して提示します。本論文はelement-uiの実装を模倣したものである。
考えが整理される
まず、element-uiの中のメッセージの効果はどうですか?考えを探してみます。
図から見れば、メッセージヒントは複数のストリップを同時に表示することができ、位置付けはすべてfixedであるように見えます。これらのメッセージを格納するために配列を使用することが考えられます。そして、各プロンプトメッセージの表示に基づいて、各項目のtop値を変更し、いくつかのアニメーション(transionを使用して)を追加し、詳細に処理しました。
コンポーネント作成
新しい2つのコンポーネントのMsgBox.vueとMsg.vueは、前者が着信メッセージデータの収集と処理を担当しています。
MsgBoxコンポーネント
tsの部分
まずMsgBox.vueで方法を作成し、配列を処理する方法addMsg、reetTop、clear、addMsgはメッセージデータの収集を担当しています。各msgには隠し属性ショーの表示を制御する責任があります。restettopは、トップからのメッセージのプロパティtopおよび各メッセージの表示非表示を制御する。clearは、配列中のすべてのメッセージが非表示状態にあるとき、メッセージ配列をクリアする責任を負う。
template部分
html部分は比較的に簡単で、msgs配列を遍歴して、一つずつサブアセンブリMsgに伝えます。
Msgコンポーネント
tsの部分
サブアセンブリには論理が少なく、主にコンポーネントマウント時にタイマーを起動し、一定時間後に親コンポーネント中のreetTopをemitでトリガする方法でコンポーネントをクローズします。また、パラメータによって現在のメッセージを取得するためのcomputed方法があります。
ビューの部分も比較的簡単で、主にvueの持っているtransionのコンポーネントを使って実現するアニメーション効果で、apparの属性をプラスして入場するアニメーション効果があることに注意します。
スタイルの部分は主にelement-uiのスタイルを参考にして、アニメーションを使って簡単なアニメーション効果を作りました。
セットの中の方法をVueプロトタイプのチェーンにセットします。
しかし、私たちはどうやって呼び出すべきですか?element-uiでの使用方法this.$messageを参照して、コンポーネントの入口方法をVueのプロトタイプチェーンにマウントし、その前にこのコンポーネントを実装しておくべきです。次に、モジュールのインスタンスをbodyにマウントし、インスタンス上の入口方法をVueプロトタイプチェーンに追加します。
ここでは、当社のビッグプレーヤーがreactを参考にして書いたvueのトランスポートゲートメソッドpotalを使用しています。コンポーネントを新しいVueにアップロードし、実用化してから、新しいインスタンスをbodyの下にマウントします。
ユーザーに対して提示が必要な場合、このような場面に遭遇することがあります。モダリティボックスを使ってあまりにもハード核を提示し、toastヒントを使うのはまた軽すぎます。この時はページの上部を使ってスライドしたメッセージメッセージを選択して提示します。本論文はelement-uiの実装を模倣したものである。
考えが整理される
まず、element-uiの中のメッセージの効果はどうですか?考えを探してみます。
図から見れば、メッセージヒントは複数のストリップを同時に表示することができ、位置付けはすべてfixedであるように見えます。これらのメッセージを格納するために配列を使用することが考えられます。そして、各プロンプトメッセージの表示に基づいて、各項目のtop値を変更し、いくつかのアニメーション(transionを使用して)を追加し、詳細に処理しました。
コンポーネント作成
新しい2つのコンポーネントのMsgBox.vueとMsg.vueは、前者が着信メッセージデータの収集と処理を担当しています。
MsgBoxコンポーネント
tsの部分
まずMsgBox.vueで方法を作成し、配列を処理する方法addMsg、reetTop、clear、addMsgはメッセージデータの収集を担当しています。各msgには隠し属性ショーの表示を制御する責任があります。restettopは、トップからのメッセージのプロパティtopおよび各メッセージの表示非表示を制御する。clearは、配列中のすべてのメッセージが非表示状態にあるとき、メッセージ配列をクリアする責任を負う。
private addMsg(msg: Msg) {
this.msgs.push({...msg, show: true})
this.resetTop()
}
private resetTop(ind1 = -1) {
this.clear()
let ind = 0
const msgs = this.msgs.map((msg: MsgInfo, i: number) => {
if (i === ind1) {
msg.show = false
}
if (msg.show) {
msg.top = 20 + ind * 72
ind++
}
return msg
})
this.msgs = [...msgs]
}
private clear() {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
const allFalse = this.msgs.some((t) => t.show)
if (!allFalse) {
this.msgs = []
}
}, 1000)
}
新しいメッセージが追加されるたびに、または元のメッセージが隠されているときに、reetTop方法がトリガされ、各メッセージの位置を再計算するために使用される。template部分
html部分は比較的に簡単で、msgs配列を遍歴して、一つずつサブアセンブリMsgに伝えます。
<template>
<div>
<msg-box v-for="(msg,i) of msgs" :msg="msg" :key="i" :ind="i" @resetTop="resetTop" :msgs="msgs"></msg-box>
</div>
</template>
ここに入ってきた配列msgsの原因は、reetTopを呼び出して配列を変更するたびに、サブアセンブリがmsgの変化を監視できなくなり、msgsを直接msgsに導入し、msgsから関連データを取ります。Msgコンポーネント
tsの部分
サブアセンブリには論理が少なく、主にコンポーネントマウント時にタイマーを起動し、一定時間後に親コンポーネント中のreetTopをemitでトリガする方法でコンポーネントをクローズします。また、パラメータによって現在のメッセージを取得するためのcomputed方法があります。
private get info() {
const msgs = this.msgs as MsgInfo[]
return msgs[this.ind]
}
private get boxClass() {
const type = this.msg.type
return type ? `box-item-${type}` : ''
}
@Emit('resetTop')
private close() {
return this.ind
}
private mounted() {
if (this.msg.delay !== 0) {
const delay = parseInt(this.msg.delay) || 3000
setTimeout(() => {
this.close()
}, delay)
}
}
template部分ビューの部分も比較的簡単で、主にvueの持っているtransionのコンポーネントを使って実現するアニメーション効果で、apparの属性をプラスして入場するアニメーション効果があることに注意します。
<template>
<transition name="msg" appear>
<div :class="['box-item', boxClass]" v-if="info.show" :style="{top: info.top + 'px'}">
<div class="msg-container">
<i :class="['iconfont', iconClass]"></i>
{{ info.msg }}
</div>
<span @click="close">
<i class="iconfont icon-cc-close"></i>
</span>
</div>
</transition>
</template>
css部分スタイルの部分は主にelement-uiのスタイルを参考にして、アニメーションを使って簡単なアニメーション効果を作りました。
.box-item {
height: 16px;
position: fixed;
min-width: 380px;
// element-ui
border-width: 1px;
border-style: solid;
border-color: #EBEEF5;
position: fixed;
left: 50%;
transform: translateX(-50%);
background-color: #edf2fc;
transition: opacity .3s,transform .4s,top .4s;
padding: 15px 15px 15px 20px;
display: flex;
align-items: center;
justify-content: space-between;
&-success{
background-color: #f0f9eb;
border-color: #e1f3d8;
}
&-warning {
background-color: #fdf6ec;
border-color: #faecd8;
}
&-error {
background-color: #fef0f0;
border-color: #fde2e2;
}
}
.msg-container {
display: flex;
align-items: center;
.iconfont {
margin-right: 5px;
}
}
.msg-enter-active {
animation: anim 0.5s;
}
.msg-leave-active {
animation: anim 0.5s reverse;
}
@keyframes anim {
0% {
opacity: 0;
transform: translate(-50%, -200%);
}
100% {
opacity: 1;
transform: translate(-50%, 0);
}
}
ここまで、cssコードを除いて150行しかメッセージ提示コンポーネントを実現していません。セットの中の方法をVueプロトタイプのチェーンにセットします。
しかし、私たちはどうやって呼び出すべきですか?element-uiでの使用方法this.$messageを参照して、コンポーネントの入口方法をVueのプロトタイプチェーンにマウントし、その前にこのコンポーネントを実装しておくべきです。次に、モジュールのインスタンスをbodyにマウントし、インスタンス上の入口方法をVueプロトタイプチェーンに追加します。
ここでは、当社のビッグプレーヤーがreactを参考にして書いたvueのトランスポートゲートメソッドpotalを使用しています。コンポーネントを新しいVueにアップロードし、実用化してから、新しいインスタンスをbodyの下にマウントします。
import Vue, {VueConstructor} from "vue";
interface Param {
cmp: VueConstructor & {instance?: () => any};
name: string;
method?: string;
target?: string | HTMLElement;
props?: any;
}
export default function portal(param: Param){
let {cmp, name, method, target = document.body, props = {}} = param
if(typeof target === 'string') target = document.querySelector(target) as HTMLElement;
method = method || 'show'
cmp.instance = ()=>{
let instance = new Vue({
render(h){
return h(cmp, {props})
}
})
instance.$mount();
// instance.$el
(target as HTMLElement).appendChild(instance.$el);
return instance.$children[0];
}
const instance = cmp.instance()
Vue.prototype[`$${name}`] = instance[method];
}
次に、Vueプロジェクトの入り口ファイルで転送ゲート方法を使ってMsgコンポーネントをマウントしてコンポーネントの中で使用することができます。
portal({
name: 'msg',
cmp: MsgBox,
method: 'addMsg'
})
ここでは、Element-uiをまねて簡単な$message方法を実現する記事について紹介します。Element-ui$messageの内容については、以前の文章を検索したり、次の関連記事を見たりしてください。これからもよろしくお願いします。