elementui.tag标签用法:Element - The world's most popular Vue UI framework
vue.draggaable用法:vue.draggable中文文档 - itxst.com
数据库表中数据:
部分结果截图:
部分关键代码:
全部代码:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:include="include/header_element::header('')"></head>
<style>
body, html {
}
.el-form-item {
margin-bottom: 10px;
}
.el-tag + .el-tag {
margin-left: 10px;
}
.button-new-tag {
margin-left: 10px;
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
</style>
<body>
<div id="zsvm" v-cloak>
<el-row :gutter="20">
<!--数组列表 start-->
<el-col :span="20">
<el-card class="box-card" style="font-weight: 300;padding: 20px;">
<el-divider content-position="left">
<el-button type="warning" @click="saveList(hotActivityTipsArr,'hotActivityTipsArr')"
size="mini">保存活动列表
</el-button>
</el-divider>
<el-row>
<!-- vue-draggable 实现拖拽效果的使用方法:
https://blog.csdn.net/sinat_33255495/article/details/109112514 -->
<!-- group:相同的组之间可以相互拖拽 -->
<!-- animation:拖动时的动画效果,还是很酷的,数字类型。如设置animation=1000表示1秒过渡动画效果 -->
<!-- @start:开始拖动时触发的事件 @end:拖拽完成时的事件 -->
<draggable v-model="hotActivityTipsArr" group="site" animation="300" @start="onStart" @end="onEnd">
<el-col :span="4" v-for="tag,i in hotActivityTipsArr" style="margin-top: 8px;">
<!--closable:显示关闭按钮 effect:tag标签主题(dark/light/plain)-->
<el-tag effect="plain" type="info" closable @close="removeList(hotActivityTipsArr,tag)">
{{i}}--{{tag}}
</el-tag>
</el-col>
<el-input class="input-new-tag" v-if="inputVisible" v-model="inputValue" ref="saveTagInput"
size="small" @keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm"
style="margin-top: 8px;margin-left: 0px;" maxlength="20">
</el-input>
<el-button style="margin-top: 8px;margin-left: 0px;" v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>
</draggable>
</el-row>
</el-card>
</el-col>
<!--数组列表 end-->
<!--卡片列表 start-->
<el-col>
<el-row :gutter="12">
<el-col :span="24" style="margin-top: 10px;">
<el-form>
<el-form-item>
<el-button type="success" size="mini" icon="el-icon-plus" @click="addNewActiveBtn" title="添加新的活动">新增</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col v-for="item in dataArray" :span="6" style="margin-top: 10px;">
<el-card style="font-size: 15px;font-weight: 300;height: 410px">
<el-row slot="header" >
<span>{{item.keyStr}}</span>
<el-button style="float: right; padding: 3px 0" @click="addList(hotActivityTipsArr,item)" icon="el-icon-plus" title="将活动加入数组"></el-button>
</el-row>
<el-row style="margin-bottom: 5px;">
<el-col align="middle" style="margin-top: 5px;">
{{item.title}}
<span style="font-size: 8px;color: red; border: 1px solid red; border-radius: 3px;">活动持续 {{item.days}}天</span>
</el-col>
<el-col align="middle" style="margin-top: 8px;">
{{item.context}}
</el-col>
<el-col align="middle" style="margin-top: 8px;">
<el-image style="width: 100%; height: 200px; border-radius: 5px;" :src="item.url" >
</el-image>
</el-col>
<el-col align="middle" style="margin-top: 8px;">
<el-button type="warning" round size="mini" disabled>跳转至{{item.key}}</el-button>
</el-col>
</el-row>
</el-card >
</el-col>
</el-row>
</el-col>
</el-row>
<!--卡片列表 end-->
<!--新增活动 模态框-->
<el-dialog title="新增活动配置" :visible.sync="dialogAddgsVisible" @close="closeDialogAddgsVisible" width="70%">
<el-form :model="param" :rules="formRule" ref="ruleForm" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="类型" :label-width="formLabelWidth">
<el-input v-model="param.type" disabled autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" :label-width="formLabelWidth">
<el-input v-model="param.remark" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="活动标签key" prop="keyStr" :label-width="formLabelWidth">
<el-input v-model="param.keyStr" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="编辑者" :label-width="formLabelWidth">
<el-input v-model="param.editor" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="rateType" :label-width="formLabelWidth">
<el-select v-model.trim="param.rateType" style="width:100%">
<el-option label="无规则" :value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动持续天数" :label-width="formLabelWidth">
<el-input-number :min="0" v-model="param.days" ></el-input-number >
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动开始时间" prop="date" :label-width="formLabelWidth">
<el-date-picker v-model="param.date" value-format="yyyy-MM-dd" align="right" type="date" placeholder="选择日期" :picker-options="pickerOptions"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活跃天数限制" :label-width="formLabelWidth">
<el-input-number :min="0" v-model="param.need" ></el-input-number>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否地域限制" :label-width="formLabelWidth">
<el-select v-model.trim="param.cityLimit" style="width:100%">
<el-option label="是" :value="true"></el-option>
<el-option label="否" :value="false"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="图片路径" prop="url" :label-width="formLabelWidth">
<el-input v-model="param.url" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="跳转标签" prop="key" :label-width="formLabelWidth">
<el-input v-model="param.key" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="活动标题" prop="title" :label-width="formLabelWidth">
<el-input type="text" v-model="param.title" maxlength="10" show-word-limit clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="活动内容" prop="context" :label-width="formLabelWidth">
<el-input type="textarea" v-model="param.context" maxlength="40" show-word-limit clearable></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer" size="mini">
<el-button size="mini" @click="dialogAddgsVisible = false">取 消</el-button>
<el-button size="mini" type="primary" @click="saveAddForm(param)">确 定</el-button>
</div>
</el-dialog>
</div>
<div th:include="include/footer_element::footer"></div>
<script th:src="@{../../libs/sort/Sortable.min.js}"></script>
<script th:src="@{../../libs/dr/vuedraggable.umd.min.js}"></script>
<script type="text/javascript">
Vue.component('vuedraggable', window.vuedraggable.name)
var vm = new Vue({
el: '#zsvm',
components: {
vuedraggable: vuedraggable,//当前页面注册组件
},
data: {
configObject: {},
id: null,
inputVisible: false,
inputValue: '',
hotActivityTipsArr: [],
formLabelWidth: '120px',
dialogAddgsVisible: false,
activeNames: ["1"],//模板固定参数
param: {//搜索参数
editor: parent.user.username,
rateType: 0,
remark: "系统配置",
type: "hotActivityTips",
rateConfig: "",
keyStr: "",
valueStr: "",
days: 1,
date: "",
cityLimit: false,
need: 0,
title: "",
context: "",
url: "",
key: "",
},
valueStrJson: {
days: 1,
date: "",
cityLimit: false,
need: 0,
title: "",
context: "",
url: "",
key: "",
order: null,
},
formRule: {
keyStr: [{required: true, message:"活动标签输入不能为空",trigger:"blur"}],
title: [{required: true, message:"活动标题输入不能为空",trigger:"blur"}],
context: [{required: true, message:"活动内容输入不能为空",trigger:"blur"}],
url: [{required: true, message:"图片路径输入不能为空",trigger:"blur"}],
key: [{required: true, message:"跳转路径输入不能为空",trigger:"blur"}],
date: [{required: true, message:"活动开始日期输入不能为空",trigger:"blur"}],
},
dataArray: [],
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
},
methods: {
showInput:function() {
var th=this;
th.inputVisible = true;
th.$nextTick(_ => {
th.$refs.saveTagInput.$refs.input.focus();
});
},
handleInputConfirm:function() {
var th=this;
let inputValue = th.inputValue;
if (inputValue) {
th.hotActivityTipsArr.push(inputValue);
}
th.inputVisible = false;
th.inputValue = '';
},
addList: function (list, v) {
console.log("数组列表*****:"+list+"-------添加的活动key"+v.keyStr)
if (list.indexOf(v.keyStr) == -1) {
list.push(v.keyStr);
}else{
this.$message('该活动已存在活动列表中!');
return;
}
},
removeList: function (list, v) {
var th=this;
th.hotActivityTipsArr.splice(th.hotActivityTipsArr.indexOf(v), 1);
},
onStart() {
this.drag = true;
},
onEnd() {
this.drag = true;
},
saveList: function (list, key) {
var th=this;
console.log("要保存的活动列表---:"+list);
//dataArray hotActivityTipsArr
var dataArrayObj=th.dataArray;
for (var i=0;i<th.hotActivityTipsArr.length;i++){
for (var j=0;j<dataArrayObj.length;j++){
if (th.hotActivityTipsArr[i] == dataArrayObj[j].keyStr){
break;
}
if (j == dataArrayObj.length-1
&& th.hotActivityTipsArr[i] != dataArrayObj[dataArrayObj.length-1].keyStr){
th.$message(th.hotActivityTipsArr[i]+" 活动配置还没有,请先添加在保存!");
return;
}
}
}
var stringifyVal = JSON.stringify(list);
th.configObject.valueStr=stringifyVal;
th.update(
th.configObject,function (){
th.$message({
message: '操作成功',
type: 'success'
});
th.load();
})
},
update: function (params, fun) {
params.editor=parent.user.username
var th = this;
zs_postFapi({
url: '../../api/config/update?_' + $.now(),
param: params,
success: function (data) {
fun && fun(data);
}
});
},
//点击新增按钮,弹出新增模态框
addNewActiveBtn:function(){
var th=this;
th.dialogAddgsVisible = true;
},
//关闭或取消模态框,清空值
closeDialogAddgsVisible:function(){
var th=this;
th.param.keyStr="";
th.param.date="";
th.param.title="";
th.param.context="";
th.param.url="";
th.param.key="";
},
//确定新增数据
saveAddForm:function(val){
var th=this;
th.valueStrJson.days=val.days;
th.valueStrJson.date=val.date;
th.valueStrJson.cityLimit=val.cityLimit;
th.valueStrJson.need= val.need;
th.valueStrJson.title=val.title;
th.valueStrJson.context=val.context;
th.valueStrJson.url=val.url;
th.valueStrJson.key=val.key;
//转为json字符串
th.param.valueStr=JSON.stringify(th.valueStrJson)
// console.log("输入的活动配置--:"+JSON.stringify(th.valueStrJson));
this.$refs
["ruleForm"].validate(function(yes,b){
if(yes){
zs_post({
url: '../../api/config/create?_' + $.now(),
param:th.param,
success:function(r){
vm.load();
th.dialogAddgsVisible=false;
}
})
}else{
return false;
}
});
},
handleCurrentChange:function(val) {//table 查询
// console.log(`当前页: ${val}`);
this.load(val,0);
},
handleSizeChange:function(val) {//table 查询
// console.log(`每页 ${val} 条`);
this.load(0,val);
},
load:function(page,size){//查询
var th = this;
if(page!=undefined&&page!=0){
this.param.pageNumber=page;
}
if(size!=undefined&&size!=0){
this.param.pageSize=size;
}
zs_post({
url: '../../api/config/getAll?_' + $.now(),
param:th.param,
success:function(data){
console.log("查询到的数组------:"+data);
for (var i=0;i<data.length;i++){
if (data[i].keyStr != "hotActivityTipsArr") {
//字符串转json对象
var valueStrVal = JSON.parse(data[i].valueStr)
//将活动key放入 json对象中
valueStrVal["keyStr"] = data[i].keyStr;
//将json 对象放入数组中
vm.dataArray.push(valueStrVal);
}else{
th.configObject=data[i];
console.log("hotActivityTipsArr ------:"+th.configObject.valueStr);
// console.log("*************:"+JSON.parse(data[i].valueStr));
th.hotActivityTipsArr=JSON.parse(data[i].valueStr);
th.id=data[i].id;
}
}
}
})
},
},
mounted: function () {
this.load();
},
})
</script>
</body>
</html>
代码还可优化、缩减,比较菜、且时间原因就暂不完善了