Showing
4 changed files
with
384 additions
and
0 deletions
src/components/YlForm/index.vue
0 → 100644
This diff is collapsed. Click to expand it.
src/components/YlInput/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-input | ||
| 3 | + v-bind="$attrs" | ||
| 4 | + clearable | ||
| 5 | + @input="handleInput" | ||
| 6 | + @focus="handleFocus" | ||
| 7 | + @blur="handleBlur" | ||
| 8 | + @change="handleChange" | ||
| 9 | + class="yl-input" | ||
| 10 | + ></el-input> | ||
| 11 | +</template> | ||
| 12 | + | ||
| 13 | +<script> | ||
| 14 | +export default { | ||
| 15 | + props: { | ||
| 16 | + rules: { | ||
| 17 | + type: Array, | ||
| 18 | + default: () => [], | ||
| 19 | + }, | ||
| 20 | + }, | ||
| 21 | + data() { | ||
| 22 | + return {}; | ||
| 23 | + }, | ||
| 24 | + computed: {}, | ||
| 25 | + created() {}, | ||
| 26 | + mounted() {}, | ||
| 27 | + methods: { | ||
| 28 | + handleInput(event) { | ||
| 29 | + // v-bind="$attrs" v-on="$listeners" | ||
| 30 | + this.$emit("input", event); | ||
| 31 | + }, | ||
| 32 | + handleFocus(event) { | ||
| 33 | + this.$emit("focus", event); | ||
| 34 | + }, | ||
| 35 | + handleBlur(event) { | ||
| 36 | + this.$emit("blur", event); | ||
| 37 | + }, | ||
| 38 | + handleChange(event) { | ||
| 39 | + this.$emit("change", event); | ||
| 40 | + }, | ||
| 41 | + }, | ||
| 42 | +}; | ||
| 43 | +</script> | ||
| 44 | +<style lang='scss'> | ||
| 45 | + | ||
| 46 | +</style> |
src/components/YlTable/column.vue
0 → 100644
| 1 | +<script> | ||
| 2 | +/** | ||
| 3 | + * 动态渲染 el-table-column | ||
| 4 | + */ | ||
| 5 | +export default { | ||
| 6 | + name: 'column', | ||
| 7 | + props: { | ||
| 8 | + attrs: { | ||
| 9 | + type: Object, | ||
| 10 | + default: () => ({}), | ||
| 11 | + required: true | ||
| 12 | + } | ||
| 13 | + }, | ||
| 14 | + render: function(h) { | ||
| 15 | + let attrs = this.attrs; | ||
| 16 | + let scopedSlots = {}; | ||
| 17 | + if (attrs.render) { | ||
| 18 | + scopedSlots.default = scope => attrs.render(h, scope); | ||
| 19 | + } | ||
| 20 | + return h('el-table-column', { | ||
| 21 | + attrs, | ||
| 22 | + scopedSlots | ||
| 23 | + }); | ||
| 24 | + } | ||
| 25 | +}; | ||
| 26 | +</script> |
src/components/YlTable/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="table-container"> | ||
| 3 | + <el-row | ||
| 4 | + v-if="attrs.btnCofig.isBtn" | ||
| 5 | + style="margin-bottom: 15px" | ||
| 6 | + id="group-btn" | ||
| 7 | + > | ||
| 8 | + <el-col> | ||
| 9 | + <span | ||
| 10 | + v-for="(item, i) in attrs.btnCofig.btnGroup" | ||
| 11 | + :key="item.btnName" | ||
| 12 | + :class="i == 0 ? 'first-span' : 'span'" | ||
| 13 | + > | ||
| 14 | + <el-button | ||
| 15 | + :type="item.type" | ||
| 16 | + :icon="item.icon" | ||
| 17 | + :round="item.round" | ||
| 18 | + :size="item.size" | ||
| 19 | + :loading="item.loading" | ||
| 20 | + @click="handleClick(item, i)" | ||
| 21 | + v-if="item.btnName !== '导入' && item.btnName !== '增加'" | ||
| 22 | + >{{ item.btnName }}</el-button | ||
| 23 | + > | ||
| 24 | + <el-upload | ||
| 25 | + v-else | ||
| 26 | + ref="upload" | ||
| 27 | + :action="item.action" | ||
| 28 | + :fileName="item.fileName" | ||
| 29 | + :http-request="toUpload" | ||
| 30 | + :on-remove="onRemoveUpload" | ||
| 31 | + :limit="item.limit" | ||
| 32 | + :accept="item.accept" | ||
| 33 | + :show-file-list="false" | ||
| 34 | + class="upload" | ||
| 35 | + > | ||
| 36 | + <el-button | ||
| 37 | + :type="item.type" | ||
| 38 | + :icon="item.icon" | ||
| 39 | + :round="item.round" | ||
| 40 | + :size="item.size" | ||
| 41 | + :loading="item.loading" | ||
| 42 | + >{{ item.btnName }}</el-button | ||
| 43 | + > | ||
| 44 | + </el-upload> | ||
| 45 | + </span> | ||
| 46 | + </el-col> | ||
| 47 | + </el-row> | ||
| 48 | + <el-table | ||
| 49 | + :max-height="attrs.maxHeight" | ||
| 50 | + :empty-text="emptyText" | ||
| 51 | + v-bind="attrs" | ||
| 52 | + v-loading="loadingTable" | ||
| 53 | + :data="tableData" | ||
| 54 | + @selection-change="selectionChange" | ||
| 55 | + ref="tableRef" | ||
| 56 | + row-key="id" | ||
| 57 | + :header-cell-class-name="headerCellClassName" | ||
| 58 | + > | ||
| 59 | + <template v-if="columns.length"> | ||
| 60 | + <template v-for="item in columns"> | ||
| 61 | + <column v-if="!item.hidden" :key="item.id" :attrs="item"></column> | ||
| 62 | + </template> | ||
| 63 | + </template> | ||
| 64 | + <slot name="column" v-else></slot> | ||
| 65 | + </el-table> | ||
| 66 | + <!-- 分页 --> | ||
| 67 | + <div | ||
| 68 | + v-if="pageConfig.isPagination" | ||
| 69 | + id="pagination" | ||
| 70 | + class="pagination-container" | ||
| 71 | + :style="{ textAlign: pageConfig.position || 'right' }" | ||
| 72 | + ref="paginationRef" | ||
| 73 | + > | ||
| 74 | + <el-pagination | ||
| 75 | + background | ||
| 76 | + :hide-on-single-page="false" | ||
| 77 | + :current-page="pageConfig.pageData.page" | ||
| 78 | + :page-sizes="[10, 15, 20, 25, 30, 35, 40]" | ||
| 79 | + :page-size="pageConfig.pageData.size" | ||
| 80 | + layout="total,prev, pager, next, jumper, ->, sizes" | ||
| 81 | + :total="pageConfig.total" | ||
| 82 | + @size-change="handleSizeChange" | ||
| 83 | + @current-change="handleCurrentChange" | ||
| 84 | + > | ||
| 85 | + </el-pagination> | ||
| 86 | + </div> | ||
| 87 | + </div> | ||
| 88 | +</template> | ||
| 89 | + | ||
| 90 | +<script> | ||
| 91 | +import Sortable from "sortablejs"; | ||
| 92 | +import { objectMerge, debounce } from "@/utils"; | ||
| 93 | +import column from "./column"; | ||
| 94 | +export default { | ||
| 95 | + props: { | ||
| 96 | + attrs: { | ||
| 97 | + type: Object, | ||
| 98 | + default: { | ||
| 99 | + border: true, | ||
| 100 | + isDragSort: false, | ||
| 101 | + btnCofig: { | ||
| 102 | + isBtn: true, | ||
| 103 | + btnGroup: [ | ||
| 104 | + { | ||
| 105 | + type: "primary", // text、primary、danger | ||
| 106 | + icon: "el-icon-search", // el-icon-edit 、el-icon-delete、el-icon-plus、el-icon-download、el-icon-upload el-icon--right | ||
| 107 | + btnName: "搜索", | ||
| 108 | + size: "mini", // medium / small / mini | ||
| 109 | + round: false, | ||
| 110 | + loading: false, | ||
| 111 | + event: "searchBtn", | ||
| 112 | + }, | ||
| 113 | + ], | ||
| 114 | + }, | ||
| 115 | + }, | ||
| 116 | + }, | ||
| 117 | + emptyText: { | ||
| 118 | + type: String, | ||
| 119 | + default: "暂无数据", | ||
| 120 | + }, | ||
| 121 | + loadingTable: { | ||
| 122 | + type: Boolean, | ||
| 123 | + default: false, | ||
| 124 | + }, | ||
| 125 | + columns: { | ||
| 126 | + type: Array, | ||
| 127 | + default: () => [], | ||
| 128 | + }, | ||
| 129 | + tableData: { | ||
| 130 | + type: Array, | ||
| 131 | + default: () => [], | ||
| 132 | + }, | ||
| 133 | + pageConfig: { | ||
| 134 | + type: Object, | ||
| 135 | + default: { | ||
| 136 | + isPagination: true, | ||
| 137 | + }, | ||
| 138 | + required: true, | ||
| 139 | + }, | ||
| 140 | + }, | ||
| 141 | + components: { | ||
| 142 | + column, | ||
| 143 | + }, | ||
| 144 | + data() { | ||
| 145 | + return { | ||
| 146 | + dropCol: objectMerge({}, this.columns), | ||
| 147 | + trHeight: 4, | ||
| 148 | + }; | ||
| 149 | + }, | ||
| 150 | + computed: { | ||
| 151 | + _attrs() { | ||
| 152 | + //默认table 参数 | ||
| 153 | + const defaultParams = {}; | ||
| 154 | + return Object.assign(defaultParams, this.attrs); | ||
| 155 | + }, | ||
| 156 | + isHasAttr() {}, | ||
| 157 | + }, | ||
| 158 | + created() { | ||
| 159 | + if (this.attrs.isDragSort) { | ||
| 160 | + // 有没有复选框、有没有render | ||
| 161 | + // this.columns | ||
| 162 | + } | ||
| 163 | + }, | ||
| 164 | + | ||
| 165 | + mounted() { | ||
| 166 | + //阻止火狐拖拽新建新页面 | ||
| 167 | + document.body.addEventListener( | ||
| 168 | + "drop", | ||
| 169 | + (event) => { | ||
| 170 | + event.preventDefault(); | ||
| 171 | + event.stopPropagation(); | ||
| 172 | + }, | ||
| 173 | + false | ||
| 174 | + ); | ||
| 175 | + this.getTrCurrentHeight(); | ||
| 176 | + window.addEventListener("resize", this.getTrCurrentHeight); | ||
| 177 | + }, | ||
| 178 | + destroyed() { | ||
| 179 | + if (this.tableData.length) { | ||
| 180 | + window.removeEventListener("resize", this.getTrCurrentHeight); | ||
| 181 | + } | ||
| 182 | + }, | ||
| 183 | + | ||
| 184 | + methods: { | ||
| 185 | + getTrCurrentHeight: debounce(function () { | ||
| 186 | + this.$nextTick(() => { | ||
| 187 | + // const trEl = | ||
| 188 | + // this.$refs.tableRef.$refs.bodyWrapper.children[0].children[1] | ||
| 189 | + // .children[0]; | ||
| 190 | + // console.log(trEl) | ||
| 191 | + // if (trEl) { | ||
| 192 | + // this.trHeight = trEl.clientHeight; | ||
| 193 | + // } | ||
| 194 | + }); | ||
| 195 | + }, 800), | ||
| 196 | + // 给表头列添加className | ||
| 197 | + headerCellClassName({ row, column, rowIndex, columnIndex }) { | ||
| 198 | + if (columnIndex !== 0) { | ||
| 199 | + return "el-table_1_column"; | ||
| 200 | + } | ||
| 201 | + }, | ||
| 202 | + useTableFunc(FuncName, ...params) { | ||
| 203 | + if (!this.$refs["el-table"]) { | ||
| 204 | + return console.warn("访问不到el-table"); | ||
| 205 | + } | ||
| 206 | + if (!FuncName) { | ||
| 207 | + return console.error("请传入tabel方法名字"); | ||
| 208 | + } | ||
| 209 | + this.$refs["el-table"][FuncName](params[0]); | ||
| 210 | + }, | ||
| 211 | + // table复选框事件 | ||
| 212 | + selectionChange(e) { | ||
| 213 | + console.log(e); | ||
| 214 | + this.$emit("selectionEvent", e); | ||
| 215 | + }, | ||
| 216 | + // 条数变化 | ||
| 217 | + handleSizeChange(e) { | ||
| 218 | + this.$emit("sizeChange", e); | ||
| 219 | + }, | ||
| 220 | + // 页码变化 | ||
| 221 | + handleCurrentChange(e) { | ||
| 222 | + this.$emit("currentChange", e); | ||
| 223 | + }, | ||
| 224 | + // btn点击事件注册 | ||
| 225 | + handleClick(item, i) { | ||
| 226 | + this.$emit(item.event, item, i); | ||
| 227 | + }, | ||
| 228 | + // 拖拽行更新排序 | ||
| 229 | + rowDrop() { | ||
| 230 | + const wrapperTr = document.querySelector(".el-table__header-wrapper tr"); | ||
| 231 | + // console.log("wrapperTr:", wrapperTr); | ||
| 232 | + this.sortable = Sortable.create(wrapperTr, { | ||
| 233 | + sort: this.attrs.isDragSort, | ||
| 234 | + animation: 100, | ||
| 235 | + delay: 0, | ||
| 236 | + handle: ".move", // 只有带move类名的元素才能拖动,多选框禁止拖动 | ||
| 237 | + onEnd: (evt) => { | ||
| 238 | + // 因为手动加了一个多选框, 不在表头循环数组内, 所以这里减1 | ||
| 239 | + let oldIndx = evt.oldIndex - 1; | ||
| 240 | + let newIndx = evt.newIndex - 1; | ||
| 241 | + const oldItem = this.dropCol[oldIndx]; | ||
| 242 | + // 真正改变列数据--变化列头,就能实现列拖动 列数据按列头索引取值 {{ scope.row[dropCol[index].prop] }} | ||
| 243 | + this.dropCol.splice(oldIndx, 1); // 删除旧一行 删除为1 | ||
| 244 | + this.dropCol.splice(newIndx, 0, oldItem); // 插入新一行 插入为0 | ||
| 245 | + }, | ||
| 246 | + }); | ||
| 247 | + }, | ||
| 248 | + // 拖拽列更新排序 | ||
| 249 | + columnDrop() { | ||
| 250 | + const tbody = document.querySelector(".el-table__body-wrapper tbody"); | ||
| 251 | + const _this = this; | ||
| 252 | + Sortable.create(tbody, { | ||
| 253 | + sort: this.attrs.isDragSort, | ||
| 254 | + animation: 100, | ||
| 255 | + delay: 0, | ||
| 256 | + onStart(evt) { | ||
| 257 | + // console.log("onStart:", evt); | ||
| 258 | + evt.oldIndex; | ||
| 259 | + }, | ||
| 260 | + onEnd({ newIndex, oldIndex }) { | ||
| 261 | + // console.log("onEnd:", newIndex, oldIndex); | ||
| 262 | + const currRow = _this.tableData.splice(oldIndex, 1)[0]; | ||
| 263 | + _this.tableData.splice(newIndex, 0, currRow); | ||
| 264 | + }, | ||
| 265 | + }); | ||
| 266 | + }, | ||
| 267 | + // 选择上传 | ||
| 268 | + toUpload(options) { | ||
| 269 | + this.$refs.upload.map((item) => { | ||
| 270 | + item.clearFiles(); //上传成功之后清除历史记录 | ||
| 271 | + }); | ||
| 272 | + this.$emit("upload", options); | ||
| 273 | + }, | ||
| 274 | + //移除上传 | ||
| 275 | + onRemoveUpload(file, fileList) { | ||
| 276 | + this.$emit("rmfile", { file, fileList }); | ||
| 277 | + }, | ||
| 278 | + }, | ||
| 279 | + watch: { | ||
| 280 | + data() { | ||
| 281 | + this.$nextTick(() => { | ||
| 282 | + this.useTableFunc("doLayout"); | ||
| 283 | + }); | ||
| 284 | + }, | ||
| 285 | + tableData() { | ||
| 286 | + if (this.tableData.length && this.attrs.isDragSort) { | ||
| 287 | + // 拖拽行更新排序 | ||
| 288 | + // this.rowDrop(); | ||
| 289 | + // 拖拽列更新排序 | ||
| 290 | + this.columnDrop(); | ||
| 291 | + } | ||
| 292 | + }, | ||
| 293 | + }, | ||
| 294 | +}; | ||
| 295 | +</script> | ||
| 296 | +<style lang="scss"> | ||
| 297 | +.el-table { | ||
| 298 | + th { | ||
| 299 | + padding: 0; | ||
| 300 | + } | ||
| 301 | + td { | ||
| 302 | + padding: 0; | ||
| 303 | + } | ||
| 304 | +} | ||
| 305 | +.first-span, | ||
| 306 | +.span { | ||
| 307 | + display: inline-block; | ||
| 308 | +} | ||
| 309 | +.span { | ||
| 310 | + margin-left: 6px; | ||
| 311 | +} | ||
| 312 | +</style> |
-
Please register or login to post a comment