Vue项目中左右布局支持拉伸宽度
<template><el-row :gutter="10">
<el-col
:span="5"
v-show="type === '2' && sidebar.opened"
style="margin-top: 10px;"
>
<data-tree
:treeLazy="treeLazy"
:data="treeData"
:currentKey="treeCurrentKey"
@show-lazy-tree="showLazyTree"
@tree-node-click="handleTreeNodeClick"
>
</data-tree>
<lazy-tree
:treeLazy="treeLazy"
:currentKey="treeCurrentKey"
@tree-node-click="handleTreeNodeClick"
@lazy-data="lazyData"
></lazy-tree>
<div
class="pull-line"
@mousedown="canDrag = true"
@mouseup="resetStyle"
></div>
</el-col>
<el-col :span="type === '2' && sidebar.opened ? 19 : 24">
<data-search
v-if="searchData"
:fields="searchFields"
:formData="searchData"
:columnModel="columnModel"
@getRelatedOptions="getRelatedOptions"
@search="search"
@formStatus="getSearchFormStatus"
>
<template slot="search">
<slot name="search"></slot>
</template>
</data-search>
<data-tab v-if="modelTabs.length > 0" :modelTabs="modelTabs"></data-tab>
<data-tree-table
v-if="type === '1'"
:data="data"
:columns="tableColumns"
:selectorType="selectorType"
:showTableOperate="showTableOperate"
:height="tHeight"
:selectionWidth="selectionWidth"
:currentRows="currentRows"
@select="select"
@selection-change="handleSelectionChange"
:nonOptional="nonOptional"
:lazy="tablelazy"
:searchData="searchData"
>
<template slot="operate" slot-scope="scope">
<slot name="tableOperate" v-bind="scope"></slot>
</template>
<template slot="operateMore" slot-scope="scope">
<slot name="tableOperateMore" v-bind="scope"></slot>
</template>
</data-tree-table>
<data-table
v-if="type !== '1'"
:data="data"
:columns="tableColumns"
@sort-change="handleSortChange"
@selection-change="handleSelectionChange"
@select="select"
:selectorType="selectorType"
:currentRows="currentRows"
:showTableOperate="showTableOperate"
:height="tHeight"
:OperateWith="OperateWith"
>
<template slot="operate" slot-scope="scope">
<slot name="tableOperate" v-bind="scope"></slot>
</template>
<template slot="operateMore" slot-scope="scope">
<slot name="tableOperateMore" v-bind="scope"></slot>
</template>
</data-table>
<div v-if="type !== '1' && pageInfo" class="pagination_bar">
<fd-pagebar
v-bind="$attrs"
v-on="$listeners"
:current-page.sync="pageInfo.pageNum"
:page-size="pageInfo.pageSize"
:page-sizes="pageSizes"
layout="sizes, prev, pager, next, jumper"
:total="pageInfo.total"
>
</fd-pagebar>
</div>
</el-col>
</el-row>
</template>
<script>
import dataTree from '../DataList/tree';
import lazyTree from '../DataList/lazy-tree';
import dataSearch from '../DataList/search';
import dataTable from './table';
import dataTreeTable from './tree-table';
import { mapGetters } from 'vuex';
export default {
name: 'de-data-list',
components: {
dataSearch,
dataTable,
lazyTree,
dataTreeTable,
dataTree
},
props: {
treeLazy: {
type: Boolean,
default: false
},
selectionWidth: {
type: String,
default: '48'
},
columnModel: {
type: Object,
default: () => {}
},
type: {
type: String, // 0-普通列表 1-treeTable 2-tree 和 table
default: '0'
},
treeData: {
type: Array,
default: () => []
},
treeCurrentKey: {
type: String,
default: () => ''
},
columns: {
type: Array,
default: () => []
},
searchData: {
type: Object
},
data: {
type: Array,
default: () => []
},
pageInfo: {
type: Object
},
selectorType: {
type: String,
default: () => ''
},
currentRows: {
type: Array,
default: () => []
},
height: [String, Number],
nonOptional: String,
tablelazy: Boolean,
pageSizes: {
type: Array,
default: () => [10, 20, 30, 40]
},
modelTabs: {
type: Array,
default: () => []
},
OperateWith: {
type: Number,
default: 70
}
},
data() {
return {
canDrag: false,
baseColumnWidth: 100,
searchFormStatus: false
};
},
computed: {
...mapGetters({ sidebar: 'foundation/app/sidebar' }),
searchFields() {
let fields = this.columns.filter(item => {
return item.searchableFlag === '1';
});
return fields;
},
tableColumns() {
let columns = this.columns;
columns.map(item => {
item.widthFactor = item.widthFactor ? item.widthFactor : 1;
item.width = item.widthFactor * this.baseColumnWidth;
});
return columns;
},
scopedSlots() {
return this.$scopedSlots;
},
slots() {
return this.$slots;
},
showTableOperate() {
return !!this.scopedSlots.tableOperate;
},
searchFormHeight() {
let height = null;
let fieldsLength = this.searchFields.length;
let rows = 0;
if (fieldsLength > 0 && fieldsLength <= 3) {
// 第一行
rows = 1;
} else if (fieldsLength > 3 && fieldsLength < 10) {
// 从第二行开始算 + 1 = 总共几行
rows = Math.ceil((fieldsLength - 3) / 3) + 1;
} else {
rows = 5; //searcharea的区域高度固定位200 每行40 所以是5行
}
// rows 是行数, 40 是行高
height = rows * 40;
if (this.searchFormStatus) {
return height + 80; // 80 包含按钮区域及查询条件里面的padding值
} else {
return 60;
}
},
tHeight() {
if (this.height) {
return this.height;
}
let height = null;
let containerHeight = this.$store.state.foundation.app.containerHeight;
let pageBar = this.type !== '1' ? 74 : 0;
height = containerHeight - this.searchFormHeight - pageBar;
return height + 'px';
}
},
mounted() {
// 右侧面板拉伸
this.pl = document.querySelector('.pull-line');
this.elCol5 = document.querySelector('.el-col-5');
this.elCol19 = document.querySelector('.el-col-19');
this.window = document.documentElement || document.body;
this.leftTreeWidth = this.sidebar.opened ? 200 : 0;
this.winWidth = this.window.clientWidth;
this.padWidth = 50;
this.window.addEventListener('mousemove', e => {
if (this.canDrag) {
let treeWidth = e.pageX - this.leftTreeWidth;
if (e.pageX < this.leftTreeWidth) {
this.elCol5.style.cursor = 'e-resize';
this.pl.style.cursor = 'e-resize';
this.window.style.cursor = 'e-resize';
return;
}
if (e.pageX > this.winWidth - this.leftTreeWidth - 100) {
this.elCol19.style.cursor = 'w-resize';
this.pl.style.cursor = 'w-resize';
this.window.style.cursor = 'w-resize';
return;
}
this.elCol5.style.width = treeWidth + 'px';
this.elCol19.style.width =
this.winWidth - this.leftTreeWidth - treeWidth - this.padWidth + 'px';
this.pl.style.cursor = 'col-resize';
this.elCol5.style.cursor = 'col-resize';
this.elCol19.style.cursor = 'col-resize';
}
});
this.window.addEventListener('mouseup', () => {
this.window.onmousemove = null;
this.window.onmouseup = null;
});
},
watch: {
'sidebar.opened'() {
if (!this.sidebar.opened) {
this.$nextTick(() => {
let e24 = document.querySelector('.el-col-24');
e24 && (e24.style.width = '100%');
});
} else {
this.$nextTick(() => {
this.elCol19 &&
(this.elCol19.style.width =
this.winWidth -
parseInt(getComputedStyle(this.elCol5).width) -
this.leftTreeWidth -
this.padWidth +
'px');
});
}
}
},
methods: {
resetStyle() {
this.window.style.cursor = 'unset';
this.elCol5.style.cursor = 'unset';
this.elCol19.style.cursor = 'unset';
this.canDrag = false;
},
lazyData(data, resolve) {
this.$emit('lazy-data', data, resolve);
},
showLazyTree(data) {
this.$emit('show-lazy-tree', data);
},
handleTreeNodeClick(data) {
this.$emit('tree-node-click', data);
},
handleSortChange({ column, prop, order }) {
this.$emit('sort-change', { column, prop, order });
},
handleSelectionChange(val) {
this.$emit('selection-change', val);
},
getRelatedOptions(property) {
this.$emit('getRelatedOptions', property);
},
search(data, type) {
this.$emit('search', data, type);
},
select(row) {
this.$emit('select', row);
},
getSearchFormStatus(status) {
this.searchFormStatus = status;
}
}
};
/**
*Attributes 说明 可选值
type 页面展示类型 0(普通列表) 1(treeTable) 2(tree 和 table)
selectorType table 列类型 checkbox/radio(多选框/单选)
currentRows table 默认选中
selectorType 查询区域默认数据
treeData tree 数据
*methods 方法说明 参数说明
handleTreeNodeClick tree节点被点击时回调 data 该节点对象
handleSortChange 表格排序 { column, prop, order }
handleSelectionChange 表格选择项变化时触发 selection
search 查询按钮被点击时触发 data 表单数据 type 查询类型( 0普通 1高级)
handleSizeChange pageSize改变时触发 每页条数
handleCurrentChange currentPage改变时触发 当前页
select 表格单选按钮被点击时回调 行数据
*/
</script>
<style lang="scss" scoped>
// @import "../../../../styles/flex.scss";
/deep/ .search-form {
.el-form-item {
height: 30px;
.separator {
font-style: normal;
margin: 0 5px;
}
}
}
/deep/ .el-col-5 {
position: relative;
}
.pull-line {
position: absolute;
right: 14px;
top: 0;
width: 4px;
height: 100%;
cursor: col-resize;
}
.cursor-unset {
cursor: unset;
}
</style>
以上是 Vue项目中左右布局支持拉伸宽度 的全部内容, 来源链接: utcz.com/z/379450.html