乐趣区

关于前端:vue3巧用指令

不晓得大伙在工作中曾经用上 vue3 没有,vue3 好是好,然而有局部插件并没有更新到 3.0 的,比方我比拟喜爱的自定义滚动条 overlayscrollbars,vue3 间接应用overlayscrollbars-vue 会报错,本期咱们次要介绍一下如何应用指令来利用这些插件,自定义滚动条 overlayscrollbars 以及拖拽sortablejs

directive

指令的话这里就不多说了,参考官网文档,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 会呈现拖拽数据错乱的状况,或者说在拖拽一个列表,而列表的 keyindex,也会呈现这个问题,因为大多数人喜爱把 index 作为 key 的赋值,而咱们拖拽时 index 会变动,移除和增加时数组的索引会变,这会让 diff 呈现问题,就好比每一个人都有一个身份证,把某个人后面的人移除掉,这个人不可能就继承后面那个人的身份证了,key对于这条数据应该是惟一的,不可变的,就像人的身份证一样,故不要把 index 作为 key 来绑定。

本系列更新只有利用周末和下班时间整顿,比拟多的内容的话更新会比较慢,心愿能对你有所帮忙,请多多 star 或点赞珍藏反对一下。

本文地址:https://xuxin123.com/web/vue3-directive

退出移动版