使用原生方式开发Vue的一次体验

389 阅读2分钟

凌波不过横塘路,但目送,芳尘去,锦瑟年华谁与度?

如果放弃使用webpack及脚手架进行基于Vue的项目开发,效果会怎样?如何进行组件化?如何进行状态管理?

背景

上周末原本打算去找朋友玩,但是另外一个朋友需要我帮他写一个表格。能够支持拖拽表头进行列排序。同时这个需要放到JavaWeb的项目里去运行。

实现思路

想了一下,这个也不难,直接在html里引入vue的cdn的文件就可以了,同时需要引入些件库的cnd文件。

// iview 组件库的样式
   <link rel="stylesheet" href="https://unpkg.com/view-design/dist/styles/iview.css">
    <script type="text/javascript" src="./lib/vue.js"></script>
    <script src="https://unpkg.com/view-design/dist/iview.min.js"></script>
    <script type="text/javascript" src="./components/vue-comp.js"></script>

vue-comp.js是自定定义的组件。

拖拽部分还是直接使用拖拽api即可。

组件化

基于脚手架我们可以直接使用.vue的后缀名创建文件,直接实现需要的组件。但是放弃脚手架后,我们需要使用vue.componentapi来定义我们需要的组件。

Vue.component('drag-item', {
  template: `
  <div
  class="draggable-item can-put"
  :draggable="true"
  @dragstart="dragStart"
  @dragover="dragEnter"
  @dragend="dragEnd"
  :data-index="dataIndex"
>
  <div>{{ itemInfo.title }}</div>
</div>
  `,
  data() {
    return {
      dragInfo: {
        start: '',
        end: ''
      }
    }
  },
  props: ['itemInfo', 'dataIndex'],
  methods: {
    dragStart(e) {
      this.dragInfo.start = e.target.dataset.index
      e.target.className = 'draggable-item'
      this.$emit('setstartindex', e.target.dataset.index)
    },
    dragEnd(e) {
      if (e.target.className == 'draggable-item') {
        this.$emit('sortname')
        e.target.className = 'draggable-item can-input'
      }
    },
    dragEnter(e) {
      e.preventDefault()
      const { index } = e.target.dataset
      if (index) {
        console.log('end-index', e.target.dataset.index)
        this.$emit('setendindex', e.target.dataset.index)
      }
    },
  },
});

自定义组件有一个需要注意的地方:porps定义时用的是驼峰标记itemInfo,但是在使用组件时,需要写成连字符的形式。例如:

          <drag-item :item-info="item" :data-index="index" @sortname="dragColumn"
            @setstartindex="setstartindex"
            @setendindex="setendindex"
          /> 

我们定义的组件最后都会放到this.$options.components这个对象中。

交换表头位置

交换表头位置,本质上是将column这个数组的两个元素交换位置。

但是在交换位置的过程中,由于响应式原理对数组的限制

Vue 不能检测以下数组的变动: 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength

我们需要使用vue.set方法实现位置交换的功能。

        // 拖动易位
        dragColumn() {
          const {start,end} = this.dragState
          const arr = page.columnsInitial
          var item = arr[start];
          Vue.set(page.columnsInitial, start, arr[end])
          Vue.set(page.columnsInitial, end, item)
        },

实现拖拽需要注意的细节

如果熟悉拖拽APi化,拖拽表头进行列排序这个功能非常容易实现。但是在实现的过程中需要时刻注意以下事项。

  • dragstart,dragend事件触发的元素的拖动的元素
  • dragenter,dragover,drop事件触发的元素是要放置的位置所代表的元素
  • drop事件的触发需要dragover设置preventDefault()
  • e.dataTransfer.setData能有有效的减少交互的复杂度
  • e.dataTransfer.effectAllowed可以设置拖拽过程的样式,可选值copy|move|link|none

总结

平时用脚手架开发习惯了,偶尔尝试一下原生方式也未尝不可。并且这个过程帮助强换了Vue.component拖拽API的细节。

同时感觉这个开发方式可以应用到比较旧的项目中,比如比较旧的JavaWeb项目。

仓库地址:https://gitee.com/mynoe/table-for-friend.git

最后说两句

  1. 动一动您发财的小手,「点个赞吧」
  2. 动一动您发财的小手,「点个在看」
  3. 都看到这里了,不妨 「加个关注」
  4. 不妨 「转发一下」,好东西要记得分享

点击加个关注