写在前面,博主是个在北京打拼的码农,从事前端工作5年了,做过十多个大大小小不同类型的项目,最近心血来潮在这儿写点东西,欢迎大家多多指教。
- 对于文章中出现的任何错误请大家批评指出,一定及时修改。
- 有任何想要讨论和学习的问题可联系我:13287946835@139.com。
- 发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。
本文关键字:vue,dom元素、页面中的模块随意换位置、通过拖拽改变元素位置、通过拖拽交换元素位置
基本思路:
1.写成渲染函数比较麻烦,一个又一个模块比较复杂,还是用template模版语法渲染比较好
2.所以决定分成多个组件,使用动态组件进行渲染
批量引入探索
批量引入文件夹下的vue文件
created() {
this.requireSvgs();
},
methods: {
// 将引入资源的动作定义成了函数
requireSvgs () {
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./hintSetChild', false, /\.less$/);
console.log('req.keys() :>> ', req.keys());
requireAll(req)
},
报错
This relative module was not found:
* ./common.less in ./src/components/orgOffice/statisticAnalysis/hintSetChild nonrecursive \.less$
项目技术栈版本:
"vue": "^2.6.11",
"webpack": "^3.12.0",
老项目开发起来很难受很难受,web自动导入探索失败,目前认定是webpack版本太低不支持,至少到5版本比较好,
所以最后我并没有进行自动引入
定位跳转
动态组件引入组件后,通过定位跳转到指定位置
<div
v-for="item of modelSortList"
:key="item.code"
@click="gotoView(item.code)"
>
{{ item.shortName }}
</div>
<template v-for="item of modelSortList"
><component
:createTime="createTime"
:key="item.code"
:is="'Chart' + item.code"
:ref="'Chart' + item.code"
></component
></template>
gotoView(code) {
this.$nextTick(() => {
const index = "Chart" + code;
if (this.$refs[index][0]) {
this.$refs[index][0].$el.scrollIntoView();
}
});
},
父组件点击后所有子组件刷新
vue 点击父组件,刷新子组件_AB教程网
排序接口返回内容:
[
{
"id": "1",
"code": 1,
"name": "单位统计分析",
"shortName": "单位",
"sortNum": 7,
"delFlag": 0
},
{
"id": "7",
"code": 1,
"name": "舆情处置情况统计报表",
"shortName": "处置",
"sortNum": 6,
"delFlag": 0
},
{
"id": "2",
"code": 1,
"name": "舆情事件",
"shortName": "舆情",
"sortNum": 5,
"delFlag": 0
},
{
"id": "3",
"code": 1,
"name": "媒体来源top20",
"shortName": "媒体",
"sortNum": 4,
"delFlag": 0
},
{
"id": "4",
"code": 1,
"name": "舆情所属条线分析",
"shortName": "条线",
"sortNum": 3,
"delFlag": 0
},
{
"id": "5",
"code": 1,
"name": "负面类别",
"shortName": "类别",
"sortNum": 2,
"delFlag": 0
},
{
"id": "6",
"code": 1,
"name": "长期悬而未决事件",
"shortName": "长期",
"sortNum": 1,
"delFlag": 0
}
]
全部代码
<template>
<div
class="extractCommont extractSearch userControl extractDataMaintenanceSearch specialH"
id="container"
>
<div class="with90" style="width:98%">
<div>
<div class="commentInformationSearchBox">
<div class="titleLabel set-style-1">
<div class="titleLabel col-3">
<label class="font-weight">时间范围</label>
<el-cascader
placeholder="请选择"
:options="timeOption"
filterable
clearable
change-on-select
v-model="timeRange"
:props="{
emitPath: true
}"
@change="(timeRangeStart = ''), (timeRangeEnd = '')"
></el-cascader>
<el-radio-group
style="width: 120px;"
v-model="rangeSet"
size="mini"
>
<el-radio-button label="自定义"></el-radio-button>
</el-radio-group>
<el-date-picker
:picker-options="pickerOptionsEnd"
v-if="rangeSet == '自定义'"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="timeRangeStart"
type="datetime"
placeholder="开始日期"
@change="timeRange = ''"
>
</el-date-picker>
<el-date-picker
:picker-options="pickerOptionsEnd"
v-if="rangeSet == '自定义'"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="timeRangeEnd"
type="datetime"
placeholder="结束日期"
@change="timeRange = ''"
>
</el-date-picker>
<label>事发单位</label>
<el-cascader
:options="organization"
filterable
clearable
change-on-select
v-model="sendOrgId"
:props="{
label: 'name',
value: 'id',
children: 'childrenList',
emitPath: false,
expandTrigger: 'hover'
}"
:show-all-levels="false"
></el-cascader>
<button class="blue" style="height:30px" @click="search()">
<img src="@images/search.png" />查询
</button>
</div>
</div>
</div>
<div class="fixedTab noUnfold" v-if="!isUnfold">
<div
v-for="item of modelSortList"
:key="item.name"
@click="gotoView(item.id)"
>
{{ item.shortName }}
</div>
<div style="font-size:25px" @click="isUnfold = !isUnfold">
<i class="el-icon-arrow-right"></i>
</div>
</div>
<div class="fixedTab unfold" v-else>
<div v-for="(item, index) of modelSortList" :key="item.shortName">
<span @click="gotoView(item.id)">{{ item.name }}</span>
<template v-if="setSortNow"
>
<i
v-if="index != modelSortList.length - 1"
@click="setIt('下移', index)"
class="el-icon-bottom"
></i
><i
v-if="index != 0"
@click="setIt('上移', index)"
class="el-icon-top"
></i
> </template
>
</div>
<div style="font-size:25px">
<i @click="isUnfold = !isUnfold" class="el-icon-arrow-left"></i>
<button
v-if="!setSortNow"
class="blue"
style="height:30px"
@click="setSortNow = true"
>
排序设置
</button>
<button
v-else
class="blue"
style="height:30px"
@click="setSortNow = false,setSortList()"
>
保存
</button>
</div>
</div>
<!-- <div class="tab">
<div>
<span
:class="type == 'Table' ? 'checked' : ''"
@click="type = 'Table'"
>统计报表</span
>| <span
:class="type == 'Chart' ? 'checked' : ''"
@click="type = 'Chart'"
>图表分析</span
>
</div>
</div> -->
<template v-for="item of modelSortList"
><component
:createTime="createTime"
:key="item.id + timer"
:is="'Chart' + item.id"
:ref="'Chart' + item.id"
></component
></template>
<!--
<div v-show="type == 'Chart'">
<hint-set-chart :createTime="createTime" />
</div> -->
</div>
</div>
</div>
</template>
<script>
// import checkMixin from "@/js/checkMisIn.js";
// import hintSetChart from "./hintSetChart.vue";
import { removeEmptyChildren, treeToList } from "@/js/common.js";
import Component from "../../common/cwDialog/src/component.vue";
import Chart1 from "./hintSetChild/chart1.vue";
import Chart2 from "./hintSetChild/chart2.vue";
import Chart3 from "./hintSetChild/chart3.vue";
import Chart4 from "./hintSetChild/chart4.vue";
import Chart5 from "./hintSetChild/chart5.vue";
import Chart6 from "./hintSetChild/chart6.vue";
import Chart7 from "./hintSetChild/chart7.vue";
const month = new Date().getMonth() + 1;
export default {
components: {
// hintSetChart,
Component,
Chart1,
Chart2,
Chart3,
Chart4,
Chart5,
Chart6,
Chart7
},
// mixins: [checkMixin],
data() {
return {
setSortNow:false,
timer: "",
limitObj: {},
limitTimeStr: "",
modelSortList: [],
isUnfold: false,
sendOrgId: "",
organization: [], //组织机构树
organizationList: [], //组织机构列表
pickerOptionsEnd: {
disabledDate: time => {
// if (this.timeRangeStart) {
// return (
// time.getTime() > Date.now() - 8.64e6 ||
// //结束日期要在选择的开始日期之后,小于开始时间的日期不能选
// time.getTime() < new Date(this.timeRangeStart).getTime()
// );
// }
return (
time.getTime() > Date.now() - 8.64e6 ||
time.getTime() < new Date(this.limitTimeStr).getTime()
); //今天及之前
}
},
timeRangeStart: "",
timeRangeEnd: "",
rangeSet: "",
timeRange: "", //默认当年当季当月
defaultObj: {
value: "",
label: "",
children: [
{
value: "1",
label: "第一季度",
children: [
{
value: "1",
label: "1月"
},
{
value: "2",
label: "2月"
},
{
value: "3",
label: "3月"
}
]
},
{
value: "2",
label: "第二季度",
children: [
{
value: "4",
label: "4月"
},
{
value: "5",
label: "5月"
},
{
value: "6",
label: "6月"
}
]
},
{
value: "3",
label: "第三季度",
children: [
{
value: "7",
label: "7月"
},
{
value: "8",
label: "8月"
},
{
value: "9",
label: "9月"
}
]
},
{
value: "4",
label: "第四季度",
children: [
{
value: "10",
label: "10月"
},
{
value: "11",
label: "11月"
},
{
value: "12",
label: "12月"
}
]
}
]
},
timeOption: [],
type: "Table",
sortObj: {},
createTime:
new Date().getFullYear() + (month < 10 ? "-0" + month : "-" + month),
expireTimeOption: {
disabledDate(time) {
return time.getTime() > Date.now() - 8.64e6; //如果没有后面的-8.64e6就是不可以选择今天的
}
},
//旧
importlogShow: false,
header: {
Authorization: localStorage.getItem("header")
},
editBtnFlag: false,
loginRole: JSON.parse(localStorage.getItem("loginUl")),
isRole: false, //打开岗位组
loading: true,
missionList: [],
cur: 1, //分页
all: 0,
rows: 15, //条数
totalCount: 0, //总条数
list: {},
//
searchVal: "", //搜索
gridData: [],
options: "", //地域
value: "",
optionsUnit: "", //单位名称
valueStation: "",
optionsStation: [],
valueUnit: "",
optionsSubordinate: "", //下级单位
valueSubordinate: "",
checked: false, //全选框状态
checkeds: false,
isHint: false, //删除
deleteId: "",
item: {
name: "确定删除选中的数据吗?"
},
saveLoading: false,
tradeSetting: {},
editSHow: false,
addressId: "",
orgId: "",
deleteIds: "",
editList: {},
addListsj: "",
uploadLoading: false,
addxz: "",
orderBy: "create_time",
depList: [],
orgNewName: "",
depNewId: "",
createdDep: false,
createdDepNameText: "",
newUnit: "",
departmentList: [],
unitXID: "",
radio: "",
isHidden: false
};
},
watch: {},
created() {
this.getNowTimeRange();
this.getDateDic();
this.getModelSortList();
},
async mounted() {
this.setBgStyleNow();
this.getLimitTimeInfo();
},
methods: {
setIt(type, index) {
switch (type) {
case "上移":
[this.modelSortList[index], this.modelSortList[index - 1]] = [
this.modelSortList[index - 1],
this.modelSortList[index]
];
// this.modelSortList[index - 1].isVisible = false;
this.$forceUpdate();
break;
case "下移":
[this.modelSortList[index], this.modelSortList[index + 1]] = [
this.modelSortList[index + 1],
this.modelSortList[index]
];
// this.modelSortList[index + 1].isVisible = false;
this.$forceUpdate();
break;
}
},
gotoView(id) {
this.$nextTick(() => {
const index = "Chart" + id;
if (this.$refs[index][0]) {
this.$refs[index][0].$el.scrollIntoView();
}
});
},
getLimitTimeInfo() {
this.timeOption = [];
const year = new Date().getFullYear() + "";
this.$http({
method: "GET",
url: "/cbrc/work/statistics/module/startDate"
}).then(res => {
this.limitObj = res.data.data;
this.limitTimeStr = this.limitObj["时间"];
for (var i = this.limitObj["年"] * 1; i <= year * 1; i++) {
let obj = this.defaultObj;
obj.value = i + "";
obj.label = i + "年";
obj.children.forEach((a, index) => {
if (a.value == this.limitObj["季度"]) {
obj.children = obj.children.slice(index, obj.children.length);
}
a.children.forEach((b, index2) => {
if (b.value == this.limitObj["月"]) {
a.children = a.children.slice(index2, a.children.length);
}
});
});
this.timeOption.push(obj);
}
console.log("this.timeOption :>> ", this.timeOption);
});
this.$forceUpdate();
},
getModelSortList() {
this.$http({
method: "GET",
url: "/cbrc/work/statistics/moduleSort/query?code=" + 1
}).then(res => {
this.modelSortList = res.data.data;
});
},
async setSortList(){
this.modelSortList.forEach((i,index)=>{
i.sortNum=this.modelSortList.length-index;
})
console.log('this.modelSortList :>> ', this.modelSortList);
await this.$http({
method: "POST",
url: "/cbrc/work/statistics/moduleSort/save",
data: this.modelSortList
}).then(res => {
if (res && res.data) {
if(res.data.code==200){
this.$message.success('保存成功');
}else{
this.$message.warning('保存失败');
}
}})
},
getDateDic() {
this.$http({
method: "GET",
url: "/cbrc/user_center/organization/query/children?levelNum=" + 4
}).then(res => {
this.organization = res.data.data;
if (this.organization) {
this.organizationList = treeToList(this.organization);
removeEmptyChildren(this.organization);
this.$forceUpdate();
}
});
},
getNowTimeRange() {
//获取当前年
const year = new Date().getFullYear() + "";
// 获取当前季度:
var currMonth = new Date().getMonth() + 1;
var currQuarter =
Math.floor(currMonth % 3 == 0 ? currMonth / 3 : currMonth / 3 + 1) + "";
// const info = {
// 1: "第一季度",
// 2: "第二季度",
// 3: "第三季度",
// 4: "第四季度"
// };
// const quarter = info[currQuarter];
//获取当前月
const monthNum = new Date().getMonth() + 1;
const nowMonth = monthNum + "";
this.timeRange = [year, currQuarter, nowMonth];
},
setBgStyleNow() {
const that = this;
if (this.missionList && this.missionList.length > 0) {
this.$nextTick(() => {
that.missionList.forEach((item, index) => {
if (index % 2 !== 0) {
that.$refs["setBgStyle" + index][0].style.backgroundColor =
"#f8f8f8";
}
});
});
}
},
//搜索
search() {
if (this.timeRange && this.timeRange.length) {
// if (this.timeRange.length < 2) {
// return this.$message.warning("请选择季度");
// }
this.timeRangeStart = "";
this.timeRangeEnd = "";
} else {
if (!this.timeRangeStart != !this.timeRangeEnd) {
if (!this.timeRangeStart) {
return this.$message.warning("请选择开始日期");
} else {
return this.$message.warning("请选择结束日期");
}
}
}
this.timer = new Date().getTime();
}
}
};
</script>
<style lang="less" scoped>
.commonStyle() {
cursor: pointer;
min-width: 80px;
color: #fff;
font-size: 14px;
border-radius: 6px !important;
}
.col {
display: inline !important;
}
.blue {
.commonStyle;
}
.blues {
height: 38px;
.commonStyle();
}
.green {
float: right !important;
}
.fl {
width: 100% !important;
margin: 10px 0 !important;
}
.popRed {
color: red;
}
.el-cascader {
width: 100%;
}
.extractDataMaintenanceSearch .odd .fl button {
margin-bottom: 0px;
}
.lead {
position: relative;
img {
position: absolute;
width: 25px;
bottom: 25px;
cursor: pointer;
}
}
.styleSet {
.item {
height: 40px;
line-height: 40px;
display: flex;
justify-content: space-between;
.el-input,
.el-select,
.el-cascader,
.col-1-1 {
width: 80%;
}
}
}
.buttonStyle {
cursor: pointer;
display: inline-block;
width: 20px;
height: 20px;
margin: 0px 5px;
margin-top: 10px;
vertical-align: middle;
cursor: pointer;
background-size: contain;
}
.item {
margin-top: 4px;
padding-top: 4px;
}
.order {
vertical-align: middle;
cursor: pointer;
width: 18px;
}
.tab {
margin-top: 20px;
margin-bottom: 20px;
padding-left: 20px;
font-size: 16px;
display: flex;
align-items: center;
justify-content: flex-end;
span {
margin-right: 20px;
cursor: pointer;
}
.checked {
font-weight: bold;
color: var(--mainColor);
}
}
.fixedTab {
z-index: 1000;
position: fixed;
top: 350px;
background: #fff;
left: 40px;
border-radius: 10px;
font-size: 16px;
line-height: 30px;
border: 1px solid var(--mainColor);
text-align: center;
div {
padding: 5px;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
.noUnfold {
width: 50px;
div {
&:hover {
color: var(--mainColor);
}
}
}
.unfold {
width: 250px;
i,span {
&:hover {
color: var(--mainColor);
}
}
}
</style>
<style>
@import "common.css";
</style>