vue組件系列-氣泡卡片

從模態彈框講起

前端攻城?️對模態彈框確定很熟悉,無論是套用bootstrap的仍是本身寫的,它經常使用來完成與用戶的展現交互和處理一些數理邏輯。可是在用來展現小體量的信息時我認爲它是過於龐大的,咱們能夠採用更優雅的氣泡卡片來展現那些小體量的信息。
就像這樣的↓↓↓
圖片描述
先附上體驗地址css

實現

vue模版

<div class="v-popover-tag" @click.stop="pop($event)">
    <slot></slot>
  </div>
  <div class="v-popover-wrap" :style="{left: x + 'px', top: y + 'px', visibility: show ? 'visible' : 'hidden'}" v-el:pop>
    <div class="v-popover-box">
      <div class="v-popover-title">{{title}}</div>
      <div class="v-popover-content">{{content}}</div>
      <div :class="['v-popover-arrow', placement == 'top' ? 'v-popover-arrow-top' : 'v-popover-arrow-bottom']" :style="{left: arrowLeft + 'px'}"></div>
    </div>
  </div>

這裏對熟悉vue的同窗來說沒有什麼特殊的地方,主要有一個slot標籤會有疑問,在編譯模版時遇到slot標籤會回到html文檔中用相應的內容代替,使用方式能夠參考官方文檔vue-slothtml

數據

props: {
  title: {
    type: String,
    default: '標題'
  },
  content: {
    type: String,
    default: '內容'
  },
  placement: {
    type: String,
    default: 'top'
  }
},
data() {
  return {
    show: false,
    arrowLeft: 0,
    x: 0,
    y: 0
  }
}

來自父組件的數據titlecontent是必選項(雖然我也給它們設置了默認值),placement表明氣泡卡片的出現位置,默認會出如今觸發目標的上方,暫時支持top和bottom。其餘都是子組件的自身數據,用於控制氣泡卡片的顯示隱藏和位置。前端

事件函數

pop(e) {
    if(this.show){
      this.show = false
      return
    }
    var target = e.target
    this.arrowLeft = target.offsetWidth / 2
    this.x = target.offsetLeft
    if(this.placement == 'top'){
      this.y = target.offsetTop - this.$els['pop'].offsetHeight - 3
    }else {
      this.y = target.offsetTop + target.offsetHeight + 3
    }
    this.show = true
  }

這裏依靠事件的冒泡,slot中的事件會冒泡到子組件中定義的父層div標籤上,進而觸發事件執行後續的位置計算。vue

scss

這方面難點主要是那兩個小三角形的,其餘的都比較簡單。git

.v-popover-arrow{
  position: absolute;
  width: 0;
  height: 0;
  border: 5px solid transparent;
  margin-left: -5px;
  &:after{
    content: " ";
    margin-left: -4px;
    border: 4px solid transparent;
    position: absolute;
    width: 0;
    height: 0;
  }
}
.v-popover-arrow-top{
  border-bottom-width: 0;
  border-top-color: #d9d9d9;
  bottom: -5px;
  &:after{
    border-top-color: #fff;
    bottom: -3px;
  }
}

使用

html:
  <div id="app">
    <v-popover :title="popTitle" :content="popContent" :placement="popPlacement">
      <button class="btn btn-primary">點擊彈出氣泡卡片</button>
    </v-popover>
  </div>

js:
  var btn = new Vue({
    el: '#app',
    data: {
      popTitle: '我是標題'
      popContent: '氣泡內容氣泡內容氣泡內容氣泡內容氣泡內容氣泡內容氣泡內容氣泡內容氣泡內容',
      popPlacement: 'top'
    },
    components: {
      'v-popover': components.popover
    }
  })

這裏我在組件標籤中插了一個button標籤,上面提到的slot最終就會被這個按鈕代替,同時它的點擊事件會通過冒泡被觸發。github

打個廣告

插播小廣告。。。不要打我,我和@二胖手正在維護相關組件庫web-style,待組件基本完善後,參考文檔也會跟上,歡迎關注,有什麼好的建議也歡迎討論。web

相關文章
相關標籤/搜索