天天看點

vue3-巧用指令

vue3-巧用指令

不知道大家在工作中用上vue3了沒有,vue3好是好,但是有部分插件并沒有更新到3.0的,比如我比較喜歡的自定義滾動條overlayscrollbars,vue3直接使用overlayscrollbars-vue會報錯,今天我們主要介紹一下如何使用指令來應用這些插件,自定義滾動條overlayscrollbars以及拖拽sortablejs。

directive​

指令的話這裡就不多說了,參考官方文檔(https://v3.cn.vuejs.org/api/options-assets.html#directives),overlayscrollbars以及sortablejs都是提供了js方式調用的,我們可以在指令裡面進行插件的初始化。

main.js:​

import { createApp } from 'vue'
import directive from './directive'


const app = createApp(App)


directive(app)      

directive:

import { Sortable } from 'sortablejs'
import 'overlayscrollbars/css/OverlayScrollbars.css'
import OverlayScrollbars from 'overlayscrollbars'


export default function(app) {
  app.directive('focus', {
    mounted(el) {
      el.focus()
    }
  })
  app.directive('sortable', {
    mounted(el, binding) {
      const config = binding.value
      new Sortable(el, config || {})
    }
  })
  app.directive('OverlayScrollbars', {
    mounted(el, binding) {
      const config = binding.value
      const instance = OverlayScrollbars(el, config || {
        scrollbars: { autoHide: 'move' }
      })
      if (config && config.scrollReady) {
        config.scrollReady(instance)
      }
    }
  })
}      

vue:

<template>
  <ul v-sortable="sortableOptions" class="listBox">
    <li class="li" v-for="item in list" :key="item">{{ item }}</li>
  </ul>
  <div
    class="mobiReview"
    v-OverlayScrollbars="{ ...scrollOptions, scrollReady }"
  ></div>
</template>


<script setup>
import { reactive, toRefs } from 'vue'


const state = reactive({
  list: [1, 2, 3, 4, 5],
  scroll: {
    instance: null
  },
  scrollOptions: {
    className: 'os-theme-thin-dark',
    scrollbars: { autoHide: 'move' }
  }
})


function scrollReady(instance) {
  state.scroll.instance = instance
}


const sortableOptions = {
  animation: 150,
  sort: true,
  draggable: '.li',
  onUpdate: (event) => {
    event.stopPropagation()
    state.list.splice(event.newDraggableIndex, 0, state.list.splice(event.oldDraggableIndex, 1)[0])
  }
}


const { list } = toRefs(state)
</script>


<style lang="less" scoped>
.listBox {
  display: flex;
  list-style: none;
  > li {
    width: 100px;
    height: 100px;
    margin: 10px;
    background-color: red;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: move;
  }
}
.mobiReview {
  height: 500px;
  width: 300px;
  .box {
    height: 1000px;
  }
}
</style>      

我們可以通過指令來傳遞初始化參數,也可以擷取插件調用執行個體,比如scrollReady,當然如果你指令裡面寫了預設參數,也可以不用參數的傳遞。

<div
    class="mobiReview"
    v-OverlayScrollbars
  ></div>      

sortablejs

這裡算是一個額外補充說明,有些同學在做表格拖拽時使用了sortablejs:

<template>
  <el-table :data="tableData" style="width: 100%" row-key="id">
    <el-table-column type="index" width="50"></el-table-column>
    <el-table-column prop="date" label="日期" width="180"></el-table-column>
    <el-table-column prop="name" label="姓名" width="180"></el-table-column>
    <el-table-column prop="address" label="位址"></el-table-column>
  </el-table>
</template>


<script setup>
import { reactive, toRefs, onMounted } from 'vue'
import { Sortable } from 'sortablejs'


const state = reactive({
  tableData: [{
    id: 1,
    date: '2016-05-02',
    name: '王小虎',
    address: '上海市普陀區金沙江路 1518 弄'
  }, {
    id: 2,
    date: '2016-05-04',
    name: '王小虎',
    address: '上海市普陀區金沙江路 1517 弄'
  }, {
    id: 3,
    date: '2016-05-01',
    name: '王小虎',
    address: '上海市普陀區金沙江路 1519 弄'
  }, {
    id: 4,
    date: '2016-05-03',
    name: '王小虎',
    address: '上海市普陀區金沙江路 1516 弄'
  }]
})


onMounted(() => {
  const tbody = document.querySelector('.el-table__body-wrapper tbody')
  Sortable.create(tbody, {
    onUpdate: (event) => {
      event.stopPropagation()
      state.tableData.splice(event.newDraggableIndex, 0, state.tableData.splice(event.oldDraggableIndex, 1)[0])
    }
  })
})


const { tableData } = toRefs(state)
</script>      

假如不設定row-key會出現拖拽資料錯亂的情況,或者說在拖拽一個清單,而清單的key為index,也會出現這個問題,因為大多數人喜歡把index作為key的指派,而我們拖拽時index會變動,移除和添加時數組的索引會變,這會讓diff出現問題,就好比每一個人都有一個身份證,把某個人前面的人移除掉,這個人不可能就繼承前面那個人的身份證了,key對于這條資料應該是唯一的,不可變的,就像人的身份證一樣,故不要把index作為key來綁定。

本文完~

vue3-巧用指令