凌波不过横塘路,但目送,芳尘去,锦瑟年华谁与度?
如果放弃使用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.component
api来定义我们需要的组件。
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
最后说两句
- 动一动您发财的小手,
「点个赞吧」
- 动一动您发财的小手,
「点个在看」
- 都看到这里了,不妨
「加个关注」
- 不妨
「转发一下」
,好东西要记得分享