带有引导程序 vue 的可拖动表
Posted
技术标签:
【中文标题】带有引导程序 vue 的可拖动表【英文标题】:Draggable table with bootstrap vue 【发布时间】:2019-07-07 07:35:42 【问题描述】:我一直在寻找一种在 Bootstrap Vue 表上拖放行的方法。 我可以在这里找到一个工作版本:Codepen
我已经尝试将此代码实现到我自己的表中:
模板:
<b-table v-sortable="sortableOptions" @click="(row) => $toast.open(`Clicked $row.item.name`)" :per-page="perPage" :current-page="currentPage" striped hover :items="blis" :fields="fields" :filter="filter" :sort-by.sync="sortBy" :sort-desc.sync="sortDesc" :sort-direction="sortDirection" @filtered="onFiltered">
<template slot="move" slot-scope="row">
<i class="fa fa-arrows-alt"></i>
</template>
<template slot="actions" slot-scope="row">
<b-btn :href="'/bli/'+row.item.id" variant="light" size="sm" @click.stop="details(cell.item,cell.index,$event.target)"><i class="fa fa-pencil"></i></b-btn>
<b-btn variant="light" size="sm" @click.stop="details(cell.item,cell.index,$event.target)"><i class="fa fa-trash"></i></b-btn>
</template>
<template slot="priority" slot-scope="row">
<input v-model="row.item.priority" @keyup.enter="row.item.focussed = false; updatePriority(row.item), $emit('update')" @blur="row.item.focussed = false" @focus="row.item.focussed = true" class="form-control" type="number" name="priority" >
</template>
</b-table>
脚本:
import Buefy from 'buefy';
Vue.use(Buefy);
const createSortable = (el, options, vnode) =>
return Sortable.create(el,
...options
);
;
const sortable =
name: 'sortable',
bind(el, binding, vnode)
const table = el.querySelector('table');
table._sortable = createSortable(table.querySelector('tbody'), binding.value, vnode);
;
export default
name: 'ExampleComponent',
directives: sortable ,
data()
let self = this;
return
blis: [],
currentPage: 1,
perPage: 10,
pageOptions: [ 5, 10, 15 ],
totalRows: 0,
sortBy: null,
sortDesc: false,
sortDirection: 'asc',
sortableOptions:
chosenClass: 'is-selected'
,
filter: null,
modalInfo: title: 'Title', content: 'priority' ,
fields: [
key: 'move',
sortable: true
,
///...rest of the fields
]
;
现在我收到了这个错误:指令可排序绑定挂钩中的错误:“TypeError: Cannot read property 'querySelector' of null”
为什么找不到<tbody>
?
编辑:https://jsfiddle.net/d7jqtkon/
【问题讨论】:
您可以为您的箱子制作小提琴或钢笔吗?可能是queySelector
无法读取,因为tbody
不可用尝试在document.addEventListener('DOMContentLoaded',function() );
中添加代码
我遇到了同样的错误jsfiddle.net/d7jqtkon@karthickj25
【参考方案1】:
在const table = el.querySelector('table');
行中,您正在尝试获取表格元素。 var el
是表格元素。这就是为什么当你使用 querySelector
时它返回 null
分配正确的表变量后,错误消失
const table = el;
table._sortable = createSortable(table.querySelector("tbody"), binding.value, vnode);
Link to working fiddle
【讨论】:
这实际上是有道理的。感谢您的帮助,它现在可以正常工作了。 :-) @karthickj25 我也尝试过这个解决方案,但我收到一个错误,因为我的脚本不知道来自return Sortable.create
的标签Sortable
然后使用npm install sortablejs
安装Sortable 并在您的app.js 或任何作为vue js 项目入口文件的文件中导入import Sortable from 'sortablejs'
。你可以在这里找到官方文档link。【参考方案2】:
new Vue(
el: "#app",
directives:
sortable:
bind(el, binding, vnode)
let self =el
Sortable.create(el.querySelector('tbody'),
...binding.value,
vnode:vnode,
onEnd: (e) =>
let ids = el.querySelectorAll("span[id^=paper_]")
let order = []
for (let i = 0; i < ids.length; i++)
let item = JSON.parse(ids[i].getAttribute('values'))
//extract items checkbox onChange v-model
let itemInThisData = vnode.context.items.filter(i => i.id==item.id)
order.push(
id:item.id,
paper: item.paper,
domain:item.domain,
platform: item.platform,
country:item.country,
sort_priority: item.sort_priority,
selectpaper:itemInThisData[0].selectpaper
)
binding.value = []
vnode.context.items = []
binding.value = order
vnode.context.items = order
console.table(vnode.context.items)
,
);
,
,
mounted()
this.totalRows = this.items?this.items.length: 0
,
methods:
onFiltered(filteredItems)
// Trigger pagination to update the number of buttons/pages due to filtering
this.totalRows = filteredItems.length
this.currentPage = 1
,
log()
console.table(this.items)
console.log(this)
,
,
data()
return
rankOption:'default',
totalRows: 1,
currentPage: 1,
filter: null,
filterOn:[],
sortBy:'paper',
sortDesc: false,
sortableOptions:
chosenClass: 'is-selected'
,
perPage: this.results_per_page==='Todo' ? this.items.length : this.results_per_page?this.results_per_page:50,
pageOptions: [10, 50, 100, 500,'Todo'],
sortDirection: 'asc',
fields : [
key: 'paper', label: 'Soporte', sortable: true,
key: 'domain', label: 'Dominio', sortable: true,
key: 'platform', label: 'Medio', sortable: true,
key: 'country', label: 'País', sortable: true,
key: 'sort_priority', label: 'Rank', sortable: true,
key: 'selectpaper', label: 'Selección', sortable: true,
],
items : [
id:12,
paper: 'Expansion',
domain:'expansion.com',
platform: 'p',
country:'España',
sort_priority: '',
selectpaper:false
,
id:13,
paper: 'El economista',
domain:'eleconomista.es',
platform: 'p',
country:'España',
sort_priority: '',
selectpaper:false
,
id:14,
paper: 'El país',
domain:'elpais.es',
platform: 'p',
country:'España',
sort_priority: '',
selectpaper:false
]
)
<div id="app">
<template id="">
<b-table
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
v-sortable="items"
show-empty
small
stacked="md"
:items="items"
:fields="fields"
:current-page="currentPage"
:per-page="perPage"
:filter="filter"
:filterIncludedFields="filterOn"
:sort-direction="sortDirection"
@filtered="onFiltered"
>
<template v-slot:cell(selectpaper)="row">
<span :id="'paper_'+row.item.id" :values="JSON.stringify(row.item)"></span>
<b-form-group>
<input type="checkbox" @change="log" v-model="row.item.selectpaper" />
</b-form-group>
</template>
<template v-slot:cell(sort_priority)="row" v-if="rankOption==='foreach-row'">
<b-form-group>
<b-form-input type="number" @change="log"
size="sm" placeholder="Rank" v-model="row.item.sort_priority">
</b-form-input>
</b-form-group>
</template>
</b-table>
</template>
</div>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
【讨论】:
以上是关于带有引导程序 vue 的可拖动表的主要内容,如果未能解决你的问题,请参考以下文章