vue实现时间拖动组件

<template>

<div style="-moz-user-select:none;-webkit-user-select:none;user-select:none;overflow-x:auto;overflow-y:hide">

<div class="plans" :style="{width:width}">

<div class="plan-row-header">

<!-- <div class="plan-week plan-header" @click.prevent="refresh()" style="cursor:pointer;"><i

class="el-icon-close" title="点击还原"></i>&nbsp;重置</div> -->

<div class="plan-week plan-header" v-if="editStatus == false" @click.prevent="selectall()" style="cursor:pointer;"><i

class="el-icon-check" title="点击全选"></i>&nbsp;全选</div>

<div class="plan-week plan-header" v-if="editStatus == false" @click.prevent="unselectall()" style="cursor:pointer;"><i

class="el-icon-close" title="点击清空"></i>&nbsp;清空</div>

<div class="plan-week plan-header" v-if="editStatus == true" style="cursor:pointer;"><i

class="el-icon-check" title="点击全选"></i>&nbsp;全选</div>

<div class="plan-week plan-header" v-if="editStatus == true" style="cursor:pointer;"><i

class="el-icon-close" title="点击清空"></i>&nbsp;清空</div>

</div>

<div v-for="(day, index) in zhouList" class="plan-row" :index="index" :key="index">

<div class="plan-week">

<el-checkbox :disabled="editStatus" v-model="day.checked" @change="checkType(day)">{{

day.name

}}</el-checkbox>

<!-- 星期{{day.name}} -->

</div>

<div class="plan-hours">

<div v-for="hour in 24" :key="hour"

:class="{'plan-title-num': true,'plan-title-num-left': hour <=1 ,'plan-title-num-right': hour >= 10 }">

{{ ((hour%2) == 0 || hour == 1 ) ? (hour == 1 ? 0:hour):''}}</div>

<div v-for="hour in 24" :key="'kd'+hour"

:class="{'plan-title-line': true,'plan-title-line-left': hour <=1 }">|</div>

<div :index="index" class="plan-day" @mousedown.prevent="dayClick($event,index)">

<span v-for="(d, i) in (durations[index] || [])" :key="i">

<el-popover placement="top" :title="title" width="250" trigger="click">

<div style="width:224px;margin:auto;">

<el-input style="width:46px;" :disabled="editStatus" size="mini" placeholder="时"

v-model="dstarthh" min="0" max="23"></el-input> :

<el-input style="width:46px;" :disabled="editStatus" size="mini" placeholder="分"

v-model="dstartmm" min="0" max="59"></el-input> -

<el-input style="width:46px;" :disabled="editStatus" size="mini" placeholder="时"

v-model="dendhh" min="0" max="23"></el-input> :

<el-input style="width:46px;" :disabled="editStatus" size="mini" placeholder="分"

v-model="dendmm" min="0" max="59"></el-input>

</div>

<div style="text-align: center; margin: 0">

<el-button size="mini" v-if="editStatus==false" type="text"

@click="removeDuration(index,i)">删除</el-button>

<el-button size="mini" v-if="editStatus==false" type="text"

@click="saveDuration(index,i)">保存</el-button>

</div>

<div v-if="editStatus" slot="reference"

@mousedown.prevent="durationClick($event,d,index)" class="plan-duration"

:style="'width:'+ durationWidth(d,index)+'%;left:'+durationLeft(d,index,i)+'%;'">

</div>

<div v-else-if="editStatus==false" slot="reference" @mousemove.prevent="durationmove($event,index,i)"

@mousedown.prevent="durationClick($event,d,index)" :id="'duration'+index+''+i"

:dayindex="index" :durationindex="i" :start="d['s'+(index+1)]"

:end="d['e'+(index+1)]" class="plan-duration"

:style="'width:'+ durationWidth(d,index)+'%;left:'+durationLeft(d,index,i)+'%;'">

</div>

</el-popover>

</span>

</div>

</div>

</div>

</div>

</div>

</template>

<script>

export default {

props: {

serial: {

type: String,

default: ''

},

code: {

type: String,

default: ''

},

// title

title: {

type: String,

default: ''

},

// 宽度

width: {

type: String,

default: ''

},

// 查看或 新增编辑

editStatus: {

type: Boolean,

default: false

}

},

data() {

return {

zhouList: [

{

checked: false,

name: "星期一",

weekType: 1,

},

{

checked: false,

name: "星期二",

weekType: 2,

},

{

checked: false,

name: "星期三",

weekType: 3,

},

{

checked: false,

name: "星期四",

weekType: 4,

},

{

checked: false,

name: "星期五",

weekType: 5,

},

{

checked: false,

name: "星期六",

weekType: 6,

},

{

checked: false,

name: "星期日",

weekType: 7,

},

],

days: ["一", "二", "三", "四", "五", "六", "日"],

checks: [],

ho: 24,

isclick: false,

recordPlan: "",

isDown: false,

divIndex: 0,

currentDayWidth: 0,

isDown: false,

visible: false,

currentDuration: null,

isDownLeft: false,

isDownLeft: false,

value1: "",

durations: [[], [], [], [], [], [], []],

originDurations: [],

dayindex: 0,

overIndex: -1,

durationDatas: [],

prex: 0,

durationindex: 0,

startNum: 0,

dstarthh: "",

dstartmm: "",

dendhh: "",

dendmm: "",

moveprex: 0,

recordPlan: "",

mouseup: null,

mousemove: null,

movePosNum: 0,

nextStartNum: 0,

}

},

created() { },

watch: {},

mounted() {

this.mouseup = (e) => {

this.isDown = false;

this.isDownLeft = false;

this.isDownRight = false;

this.moveprex = 0;

this.movePosNum = 0;

this.prex = 0;

this.nextStartNum = 0;

this.checkPlanData(false);

this.log("mouse up")

}

this.mousemove = (e) => {

if (!this.isDown && !this.isDownLeft && !this.isDownRight) {

return false

}

if (this.isDown) {

var x = this.getPosX(e);

this.moveprex = x;

var pos = Math.floor((x / 656) * 1440 / 60) + ":" + Math.floor((x / 656) * 1440 % 60);

//校准成30的倍数

var posNum = this.timeToNum(pos);

posNum = posNum + (30 - posNum % 30);

if (posNum > 1440) {

posNum = 1440;

}

if (posNum <= this.movePosNum) {

return

}

this.movePosNum = posNum;

if (x == this.prex) {

return

}

if (x > this.prex) {

var start_time = this.numToTime(this.startNum);

var end_time = this.numToTime(posNum);

var start_key = "s" + (this.dayindex + 1);

var end_key = "e" + (this.dayindex + 1);

if (this.startNum == posNum || start_time == end_time) {

this.log("right move ignore isDown:" + this.isDown + ",prex=" + this.prex + ",x=" + x + "datalenth=" + this.durationDatas.length + ",durationindex=" + this.durationindex + ",posNum=" + posNum)

return

}

//判断有没有和其它交界

if ((this.durationindex + 1) < this.durationDatas.length) {

this.nextStartNum = this.timeToNum(this.durationDatas[this.durationindex + 1][start_key]);

if (posNum > this.nextStartNum) {

this.log("right move ignore 交界 isDown:" + this.isDown + ",prex=" + this.prex + "',x=" + x + ",datalenth=" + this.durationDatas.length + ",durationindex=" + this.durationindex + ",posNum=" + posNum + ",nextStart=" + this.durationDatas[this.durationindex + 1]["s" + (this.dayindex + 1)])

return

}

}

if (this.nextStartNum != 0 && posNum > this.nextStartNum) {

posNum = this.nextStartNum;

this.movePosNum = posNum;

end_time = this.numToTime(posNum);

}

this.durationDatas[this.durationindex][start_key] = start_time;

this.durationDatas[this.durationindex][end_key] = end_time;

this.log("right move log isDown:" + this.isDown + ",prex=" + this.prex + ",x=" + x + ",datalenth=" + this.durationDatas.length + ",durationindex=" + this.durationindex + ",posNum=" + posNum)

this.$set(this.durations, this.dayindex, this.durationDatas);

}

}

}

if (this.editStatus == false) {

document.addEventListener('mouseup', this.mouseup);

document.addEventListener('mousemove', this.mousemove);

}

{"startTime":"17:00","endTime":"21:30","weekType":1},{"startTime":"09:00","endTime":"15:00","weekType":2},{"startTime":"19:30","endTime":"22:00","weekType":2}]')

},

beforeDestroy() {

if (this.editStatus == false) {

document.removeEventListener('mouseup', this.mouseup);

document.removeEventListener('mousemove', this.mousemove);

}

},

methods: {

checkType(day){

if(day.checked == false){

this.durations[day.weekType-1] = [];

}

},

init(recordPlan) {

let recordPlanJx = JSON.parse(recordPlan);

if (recordPlanJx.length != 0) {

let FhData = [[], [], [], [], [], [], []]

for (let i = 0; i < recordPlanJx.length; i++) {

if (recordPlanJx[i].weekType == 1) {

FhData[0].push({ s1: recordPlanJx[i].startTime, e1: recordPlanJx[i].endTime })

}

if (recordPlanJx[i].weekType == 2) {

FhData[1].push({ s2: recordPlanJx[i].startTime, e2: recordPlanJx[i].endTime })

}

if (recordPlanJx[i].weekType == 3) {

FhData[2].push({ s3: recordPlanJx[i].startTime, e3: recordPlanJx[i].endTime })

}

if (recordPlanJx[i].weekType == 4) {

FhData[3].push({ s4: recordPlanJx[i].startTime, e4: recordPlanJx[i].endTime })

}

if (recordPlanJx[i].weekType == 5) {

FhData[4].push({ s5: recordPlanJx[i].startTime, e5: recordPlanJx[i].endTime })

}

if (recordPlanJx[i].weekType == 6) {

FhData[5].push({ s6: recordPlanJx[i].startTime, e6: recordPlanJx[i].endTime })

}

if (recordPlanJx[i].weekType == 7) {

FhData[6].push({ s7: recordPlanJx[i].startTime, e7: recordPlanJx[i].endTime })

}

this.zhouList[recordPlanJx[i].weekType -1].checked = true;

}

this.durations = FhData

} else {

this.durations = [[], [], [], [], [], [], []];

}

this.originDurations = [];

for (var i = 0; i < 7; i++) {

var el = [];

if (this.durations[i]) {

el = this.durations[i];

} else {

this.durations[i] = el;

}

this.originDurations[i] = el;

}

},

isModify() {

if (this.originDurations.length == 0) {

return false;

}

for (var i = 0; i < this.durations.length; i++) {

if (this.originDurations[i] != this.durations[i]) {

return true;

}

}

return false;

},

log(content) {

return

console.log(content)

},

durationmove(e, dayindex, durationindex) {

if (this.isDown && durationindex == this.durationindex && dayindex == this.dayindex) {

var x = this.getPosX(e);

var end_num = this.timeToNum(Math.floor(((this.prex + x) / 656) * 1440 / 60) + ":" + Math.floor(((this.prex + x) / 656) * 1440 % 60));

end_num = end_num + (30 - end_num % 30);

if (x == 0) {

end_num = this.startNum;

}

if (end_num > 1440) {

end_num = 1440;

}

this.log("duration move log moveprex=" + this.moveprex + ",prex=" + this.prex + ",x=" + x + ",startNum=" + this.startNum + ",end_num=" + end_num);

if (end_num >= this.startNum) {

if (this.nextStartNum != 0 && end_num > this.nextStartNum) {

end_num = this.nextStartNum;

}

this.movePosNum = end_num;

this.durations[dayindex][durationindex]["e" + (dayindex + 1)] = this.numToTime(end_num);

}

}

},

removeDuration(dayindex, durationindex) {

var newdaydurations = [];

for (var i = 0; i < this.durations[dayindex].length; i++) {

if (i == durationindex) {

continue

}

newdaydurations.push(this.durations[dayindex][i]);

}

if(newdaydurations.length == 0){

this.zhouList[dayindex].checked = false;

}

this.$set(this.durations, dayindex, newdaydurations);

$(".plan-row-header").click();

},

saveDuration(dayindex, durationindex) {

if (this.dstarthh.length == 1) {

this.dstarthh = "0" + this.dstarthh;

}

if (this.dstartmm.length == 1) {

this.dstartmm = "0" + this.dstartmm;

}

if (this.dendhh.length == 1) {

this.dendhh = "0" + this.dendhh;

}

if (this.dendmm.length == 1) {

this.dendmm = "0" + this.dendmm;

}

var start_time = this.dstarthh + ":" + this.dstartmm;

var end_time = this.dendhh + ":" + this.dendmm;

var newdaydurations = [];

var len = this.durations[dayindex].length;

for (var i = 0; i < len; i++) {

if (i == durationindex) {

if (this.timeToNum(start_time) > this.timeToNum(end_time)) {

this.$message({

type: 'warning',

message: '结束时间不能小于开始时间'

});

return

}

if (this.timeToNum(end_time) > 1440) {

this.$message({

type: 'warning',

message: '结束时间不能大于24点'

});

return

}

if (this.timeToNum(start_time) < 0) {

this.$message({

type: 'warning',

message: '开始时间不能小于0点'

});

return

}

if (i > 0) {

var pd = this.durations[dayindex][i - 1];

if (this.timeToNum(start_time) < this.timeToNum(pd["e" + (dayindex + 1)])) {

this.$message({

type: 'warning',

message: '开始时间须大于上一段结束时间'

});

return

}

}

if (i + 1 < len) {

var pd = this.durations[dayindex][i + 1];

if (this.timeToNum(end_time) > this.timeToNum(pd["s" + (dayindex + 1)])) {

this.$message({

type: 'warning',

message: '结束时间须小于下一段开始时间'

});

return

}

}

var ndata = {};

ndata["s" + (dayindex + 1)] = start_time;

ndata["e" + (dayindex + 1)] = end_time;

newdaydurations.push(ndata);

} else {

newdaydurations.push(this.durations[dayindex][i]);

}

}

this.$set(this.durations, dayindex, newdaydurations);

$(".plan-row-header").click();

},

durationClick(e, d, dayindex) {

this.dstarthh = d["s" + (dayindex + 1)].split(":")[0];

this.dstartmm = d["s" + (dayindex + 1)].split(":")[1];

this.dendhh = d["e" + (dayindex + 1)].split(":")[0];

this.dendmm = d["e" + (dayindex + 1)].split(":")[1];

if (e && e.stopPropagation) {

e.stopPropagation();

} else {

window.event.cancelBubble = true;

}

},

dayClick(event,hour) {

if (this.durations.length != 7) {

this.$message({

type: 'warning',

message: '初始化中,请稍后...'

});

return

}

this.isDown = true

var x = this.getPosX(event);

this.prex = x;

this.dayindex = parseInt($(event.currentTarget).attr("index"));

var durationDatas = [];

var start = Math.floor((x / 656) * 1440 / 60) + ":" + Math.floor(((x / 656) * 1440 % 60))

//校准成30的倍数

var snum = this.timeToNum(start);

if (snum % 30 > 15) {

this.startNum = snum + (30 - snum % 30);

} else {

this.startNum = snum - snum % 30;

}

var newData = {}

newData["s" + (this.dayindex + 1)] = this.numToTime(this.startNum);

newData["e" + (this.dayindex + 1)] = this.numToTime(this.startNum);

var hasPush = false;

for (var i = 0; i < this.durations[this.dayindex].length; i++) {

var el = this.durations[this.dayindex][i];

if (this.startNum < this.timeToNum(el["s" + (this.dayindex + 1)]) && !hasPush) {

hasPush = true;

this.durationindex = i;

durationDatas.push(newData)

}

durationDatas.push(el)

}

if (durationDatas.length == 0 || !hasPush) {

durationDatas.push(newData)

this.durationindex = durationDatas.length - 1;

}

this.durationDatas = durationDatas;

this.zhouList[hour].checked = true;

this.log("day click log x=" + x + ",dayindex=" + this.dayindex + ",predatalength=" + (this.durations[this.dayindex] || []).length + ",time=" + newData["s" + (this.dayindex + 1)] + "dataarr=" + this.durations[this.dayindex]);

},

getPosX(event) {

var x, y;

var event = event || window.event;

if (event.offsetX || event.offsetY) {

x = event.offsetX;

y = event.offsetY;

} else if (event.layerX || event.layerY) {

x = event.layerX;

y = event.layerY;

}

x = parseInt(x);

if (x < 0) {

x = 0;

} else if (x > 656) {

x = 656;

}

return x;

},

timeToNum(t) {

var time = t && t.split(":");

var h = parseInt(time[0]);

var m = parseInt(time[1]);

var sum = h * 60 + m;

return sum

},

numToTime(sum) {

var h = Math.floor(sum / 60) < 10 ? '0' + Math.floor(sum / 60) : Math.floor(sum / 60);

var m = sum % 60 < 10 ? '0' + (sum % 60) : sum % 60;

var t = h + ":" + m;

return t;

},

durationLeft(d, dayindex, durationindex) {

var preWidth = 0;

for (var i = 0; i < durationindex; i++) {

preWidth += this.durationWidth(this.durations[dayindex][i], dayindex);

}

if (preWidth < 0) {

preWidth = 0;

}

var s = this.timeToNum(d["s" + (dayindex + 1)]);

var ret = (s / 1440) * 100 - preWidth;

return ret

},

durationWidth(d, dayindex) {

var s = this.timeToNum(d["e" + (dayindex + 1)]) - this.timeToNum(d["s" + (dayindex + 1)]);

return (s / 1440) * 100

},

refresh() {

this.$confirm(

'<div class="tips" style="color:#333;font-weight:600;font-size:16px;margin-bottom:20px;">恢复初始配置,当前的编辑会丢失,是否继续?</div>',

"温馨提示",

{

confirmButtonText: "确定",

cancelButtonText: "取消",

showCancelButton: true,

// customClass: "del-model",

cancelButtonClass: "cancelOk",

confirmButtonClass: "letOk2",

dangerouslyUseHTMLString: true,

center: true,

}

)

.then(() => {

this.reset();

})

.catch(() => { });

},

getChecks() {

var plans = this.checks.join("")

return plans

},

reset() {

for (let i = 0; i < this.zhouList.length; i++) {

this.zhouList[i].checked = false

}

for (var i = 0; i < 7; i++) {

var el = this.originDurations[i] || [];

this.$set(this.durations, i, el);

}

},

checkPlanData(join) {

var durationDatas = [];

for (var i = 0; i < 7; i++) {

var els = [];

if (this.durations[i]) {

for (var j = 0; j < this.durations[i].length; j++) {

var s_key = "s" + (i + 1);

var e_key = "e" + (i + 1);

var s_num = this.timeToNum(this.durations[i][j][s_key]);

if (s_num < 0 || s_num > 1440) {

continue

}

var e_num = this.timeToNum(this.durations[i][j][e_key]);

if (e_num < 0 || e_num > 1440) {

continue

}

if (s_num >= e_num) {

continue

}

var _duration = {}

if (els.length > 0) {

var pre = els[els.length - 1];

var e_num_pre = this.timeToNum(pre[e_key]);

if (s_num < e_num_pre) {

s_num = e_num_pre;

}

if (join) {

if (s_num == e_num_pre) {

els[els.length - 1][e_key] = this.numToTime(e_num);

continue

}

}

}

_duration[s_key] = this.numToTime(s_num);

_duration[e_key] = this.numToTime(e_num);

els.push(_duration);

}

}

durationDatas.push(els)

}

this.durations = durationDatas;

},

getplan() {

this.checkPlanData(true);

let rtData = [];

if (this.zhouList[0].checked == true) {

if (this.durations[0].length != 0) {

for (let i = 0; i < this.durations[0].length; i++) {

rtData.push({ startTime: this.durations[0][i].s1, endTime: this.durations[0][i].e1, weekType: 1 })

}

}

}

if (this.zhouList[1].checked == true) {

if (this.durations[1].length != 0) {

for (let i = 0; i < this.durations[1].length; i++) {

rtData.push({ startTime: this.durations[1][i].s2, endTime: this.durations[1][i].e2, weekType: 2 })

}

}

}

if (this.zhouList[2].checked == true) {

if (this.durations[2].length != 0) {

for (let i = 0; i < this.durations[2].length; i++) {

rtData.push({ startTime: this.durations[2][i].s3, endTime: this.durations[2][i].e3, weekType: 3 })

}

}

}

if (this.zhouList[3].checked == true) {

if (this.durations[3].length != 0) {

for (let i = 0; i < this.durations[3].length; i++) {

rtData.push({ startTime: this.durations[3][i].s4, endTime: this.durations[3][i].e4, weekType: 4 })

}

}

}

if (this.zhouList[4].checked == true) {

if (this.durations[4].length != 0) {

for (let i = 0; i < this.durations[4].length; i++) {

rtData.push({ startTime: this.durations[4][i].s5, endTime: this.durations[4][i].e5, weekType: 5 })

}

}

}

if (this.zhouList[5].checked == true) {

if (this.durations[5].length != 0) {

for (let i = 0; i < this.durations[5].length; i++) {

rtData.push({ startTime: this.durations[5][i].s6, endTime: this.durations[5][i].e6, weekType: 6 })

}

}

}

if (this.zhouList[6].checked == true) {

if (this.durations[6].length != 0) {

for (let i = 0; i < this.durations[6].length; i++) {

// this.durations[6][i].startTime = this.durations[6][i].s7;

// this.durations[6][i].endTime = this.durations[6][i].e7;

// this.durations[6][i].weekType = 7;

rtData.push({ startTime: this.durations[6][i].s7, endTime: this.durations[6][i].e7, weekType: 7 })

}

}

}

console.log(rtData)

var plan = JSON.stringify(rtData);

return plan;

},

selectall() {

for (let i = 0; i < this.zhouList.length; i++) {

this.zhouList[i].checked = true

}

for (var i = 0; i < 7; i++) {

var el = [];

var n = {};

n["s" + (i + 1)] = "00:00";

n["e" + (i + 1)] = "24:00";

el.push(n);

this.$set(this.durations, i, el);

}

},

unselectall() {

for (let i = 0; i < this.zhouList.length; i++) {

this.zhouList[i].checked = false

}

for (var i = 0; i < 7; i++) {

var el = [];

this.$set(this.durations, i, el);

}

}

},

}

</script>

<style lang="less" scoped>

/* @import url(~assets/styles/variables.less); */

.plans {

font-size: 12px;

text-align: center;

border: 0;

float: left;

background-color: #f8fbfe;

padding: 15px 30px 30px 20px;

}

.plan-week {

width: 10%;

height: 100%;

float: left;

background-color: #f8fbfe;

color: #646363;

line-height: 88px;

border: 0;

}

.plan-week:hover {

background-color: #f8fbfe;

}

.plan-hours {

margin-left: 2%;

width: 88%;

height: 100%;

float: left;

background-color: #f8fbfe;

}

.plan-title-num {

font-weight: bold;

height: 25% !important;

color: #7f7e7e;

background-color: #f8fbfe;

line-height: 20px !important;

width: 4.166%;

float: left;

font-size: 12px;

border-color: #eee;

border-style: none none none none;

text-align: right;

}

.plan-title-num-right {

margin-left: 2px;

margin-right: -2px;

}

.plan-title-num-left {

text-align: left !important;

margin-left: -10px;

padding-left: 5px;

margin-right: 10px;

}

.plan-title-line {

font-weight: bold;

height: 15% !important;

color: #dddddd;

background-color: #f8fbfe;

line-height: 14px !important;

width: 4.167%;

float: left;

font-size: 12px;

border-style: none none none none;

text-align: right;

}

.plan-title-line-left {

border-style: none none none solid !important;

border-color: #dddddd;

border-left-width: 1px;

margin-left: -0.4%;

}

.plan-day {

width: 100%;

height: 60%;

float: left;

background-color: white;

color: #eee;

line-height: 40px;

border: solid;

border-width: 1px;

border-color: #dddddd;

margin-left: -0.5%;

}

.plan-header {

font-weight: bold;

height: 24px !important;

color: #646363;

background-color: #f8fbfe !important;

line-height: 24px !important;

}

.plan-header:hover {

background-color: #f8fbfe;

}

.plan-row-header {

height: 24px;

width: 100%;

}

.plan-row {

height: 60px;

width: 100%;

border-top: 1px;

border-style: none;

border-color: #eee;

}

.plan-duration {

display: block;

height: 100%;

background-color: #347fff;

border-color: black;

border-style: none none none none;

font-size: 10px;

cursor: pointer;

float: left;

position: relative;

}

.plan-duration:hover {

background-color: #80acf7;

}

</style>

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue3 的组件拖拽排序可以通过使用 `Sortable.js` 库来实现。以下是一个简单的示例: 1. 安装 `Sortable.js` 库: ``` npm install sortablejs --save ``` 2. 在需要排序的组件中导入 `Sortable.js`: ```javascript import Sortable from 'sortablejs'; ``` 3. 在组件的 `mounted` 钩子中初始化排序: ```javascript mounted() { const el = this.$refs.sortable; this.sortable = Sortable.create(el, { onEnd: this.onSortEnd }); }, ``` 4. 创建 `onSortEnd` 方法来处理排序结束后的逻辑: ```javascript methods: { onSortEnd(event) { const itemEl = event.item; const newIndex = event.newIndex; // 处理排序结束后的逻辑 } } ``` 5. 在组件中添加拖拽排序的 HTML: ```html <template> <div ref="sortable"> <div v-for="(item, index) in items" :key="item.id"> {{ item.text }} </div> </div> </template> ``` 在以上代码中,`items` 是一个数组,包含需要排序的项目。将 `items` 数组绑定到组件的属性中即可。 完整的代码示例: ```javascript <template> <div ref="sortable"> <div v-for="(item, index) in items" :key="item.id"> {{ item.text }} </div> </div> </template> <script> import Sortable from 'sortablejs'; export default { data() { return { items: [ { id: 1, text: 'Item 1' }, { id: 2, text: 'Item 2' }, { id: 3, text: 'Item 3' }, { id: 4, text: 'Item 4' } ], sortable: null }; }, mounted() { const el = this.$refs.sortable; this.sortable = Sortable.create(el, { onEnd: this.onSortEnd }); }, methods: { onSortEnd(event) { const itemEl = event.item; const newIndex = event.newIndex; // 处理排序结束后的逻辑 } } }; </script> ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值