企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
[TOC] ### 1. 表格中插槽的使用 ~~~ <el-table :data="allDataSource" style="width: 100%" height="100%" stripe border> <el-table-column label="时间" min-width="20%"> <template slot-scope="scope"> <p>修改时间:{{ scope.row.lastTime }}</p> <p>注册日期:{{ scope.row.createTime }}</p> <!-- <span style="margin-left: 10px"></span> --> </template> </el-table> //若不使用插槽 <el-table-column prop="createTime" label="时间" min-width="20%"> ~~~ ### 2. 修改饿了么ui中的默认样式 ~~~ 1. 在控制台找到 元素对应的类名 2. 复制类名在代码中进行修改样式(使用less进行css样式编写,使用嵌套,能够优化渲染效率) 3. 复制出来的类名是所有相同元素的(全局样式)。解决方式:通过div将元素包裹,使用/deep/来实现定制化样式 ~~~ ### 3. 在component中定义了很多组件中页面中使用组件一个一个引用很麻烦 #### 解决方式: 1. 在component中新建一个index.js文件 2. 文件内容: ~~~ import Vue from 'vue' // 检索目录下的模块 const req = require.context('.', true, /\.vue$/) req.keys().forEach(fileName => { // require模块 const componentConfig = req(fileName) const name = fileName.name || fileName .replace(/^\.\/.*\//, '') .replace(/\.vue$/, '') .toLowerCase() Vue.component(name, componentConfig.default || componentConfig) }) ~~~ 3. 使用模板及传递参数(在模板中定义参数类型,值再要使用的页面传递) ~~~ <!-- 模型类型弹框 --> <dme-dir-manage dialogTitle="模型目录管理" :typeData="modelTypes" :visibleType="dialogTypeVisible" :handleAdd="addModelType" :handleDelete="deleteModelType" :handleEdit="updateModelType" :handleRefresh="refreshType" @handle-close="handleCloseType" ></dme-dir-manage> ~~~ 模板文件如下: ~~~ <!-- * @Description: 类型/小型弹框 * @Author: liangqq * @LastEditors: Liangqq * @Date: 2019-03-05 14:58:44 * @LastEditTime: 2019-04-28 15:15:55 --> <template> <div class="type-container"> <!-- 类型框 --> <el-dialog :title="dialogTitle" :visible.sync="visible" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false" id="type-dialog" width="400px" > <div class="dialog-type-body"> <div class="close-dialog"><span class="el-icon-close" @click="handleClose"></span></div> <div class="dialog-body-content" ref="dialogBody"> <el-tree class="tree-type" :data="typeList" :props="defaultProps" :default-expand-all="true" @node-contextmenu="handleRightClick" @node-click="handleLeftClick" > <span class="custom-tree-node" slot-scope="{ node }"> <span> <i class="iconfont icon-file"></i> {{ node.label }} </span> </span> </el-tree> <div ref="popover" class="popover-container"> <el-popover placement="right" width="150px" trigger="manual" v-model="popoverVisible"> <div @click="addType"><i class="iconfont icon-add"></i>添加</div> <div @click="deleteType"><i class="iconfont icon-delete"></i>删除</div> <div @click="editType"><i class="iconfont icon-edit"></i>编辑</div> </el-popover> </div> <div class="tip-dialog-container"> <el-dialog title="提示" class="popover-tip-dialog" :visible.sync="tipVisible" :close-on-click-modal="false" :close-on-press-escape="false" :append-to-body="true" width="260px" > <div class="dialog-choose-body"> <!-- 删除 --> <div class="delete-single" v-if="oper === 'delete'"><p>确认删除?</p></div> <!-- 添加类型 --> <div class="add-type" v-if="oper === 'add'"> <span>目录名称:</span> <el-input type="text" size="mini" v-model="addTypeName"></el-input> </div> <!-- 编辑类型名称 --> <div class="edit-type" v-if="oper === 'edit'"> 目录名称: <el-input type="text" size="mini" v-model="updateTypeName"></el-input> </div> <span slot="footer" class="dialog-footer"> <el-button size="small" @click="tipVisible = false">取 消</el-button> <el-button size="small" type="primary" @click="confirm">确 定</el-button> </span> </div> </el-dialog> </div> </div> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="handleClose">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { name: 'dme-dir-manage', props: { // type 框名称 dialogTitle: String, // type 数据 typeData: Array, // 控制 type 框 visibleType: Boolean, // 添加接口 handleAdd: Function, // 删除接口 handleDelete: Function, // 编辑接口 handleEdit: Function, // 刷新类型接口 handleRefresh: Function }, inheritAttrs: false, data() { return { // type 数据 typeList: null, visible: false, // 目录弹窗是否弹出 popoverVisible: false, // 右键菜单 tipVisible: false, // 提示框 oper: null, // 操作类型 currentNodeData: null, // 当前操作节点数据 addTypeName: null, // 添加模型类型 updateTypeName: null, // 更行模型类型 // 数据默认字段 defaultProps: { label: 'name', children: 'children' } } }, created() { this.typeList = this.typeData }, watch: { typeData(newVal) { this.typeList = newVal }, visibleType(newVal) { this.visible = newVal } }, mounted() {}, methods: { // 左键关闭popover handleLeftClick() { this.popoverVisible = false }, // 右键控制popover位置 handleRightClick(event, data) { this.popoverVisible = true this.currentNodeData = data const poTop = event.clientY - this.getElementTop(this.$refs.dialogBody) const poLeft = event.clientX - this.getElementLeft(this.$refs.dialogBody) this.$refs.popover.style.left = `${poLeft}px` this.$refs.popover.style.top = `${poTop}px` }, // 获取容器的绝对位置Left getElementLeft(element) { let actualLeft = element.offsetLeft let current = element.offsetParent while (current !== null) { actualLeft += current.offsetLeft current = current.offsetParent } return actualLeft }, // 获取容器的绝对位置Top getElementTop(element) { let actualTop = element.offsetTop let current = element.offsetParent while (current !== null) { actualTop += current.offsetTop current = current.offsetParent } return actualTop }, // 弹框顶端关闭按钮 handleClose() { this.$emit('handle-close') }, // 添加类型 addType() { this.tipVisible = true this.oper = 'add' }, // 删除类型 deleteType() { this.tipVisible = true this.oper = 'delete' }, // 编辑类型 editType() { this.tipVisible = true this.oper = 'edit' }, // 确认操作 confirm() { let data = null // 取得数据 switch (this.oper) { case 'add': if (!this.addTypeName) { break } console.log(data) data = { parentId: this.currentNodeData.id, name: this.addTypeName, previousId: this.currentNodeData.id, nextId: this.currentNodeData.id + 1 } this.handleAdd(data).then(() => { this.$message({ message: '添加类型成功', type: 'success' }) this.handleRefresh() }) break case 'delete': data = this.currentNodeData.sysCode console.log(data) this.handleDelete(data).then(() => { this.$message({ message: '删除类型成功', type: 'success' }) this.handleRefresh() }) break case 'edit': if (!this.updateTypeName) { break } data = { sysCode: this.currentNodeData.sysCode, newName: this.updateTypeName } console.log(data) this.handleEdit(data).then(() => { this.$message({ message: '修改名称成功', type: 'success' }) this.handleRefresh() }) break default: break } this.tipVisible = false this.popoverVisible = false // 顺便关闭右键菜单 } } } </script> <style lang="scss" scoped> .type-container { #type-dialog { /deep/ .el-dialog { .el-dialog__header { background: #0085f6; span { color: #ffffff; } } .el-dialog__body { padding: 5px 0px; .dialog-type-body { .close-dialog { position: absolute; top: 5px; right: 5px; &:hover { color: #ffffff; } span { font-size: x-large; } } .dialog-body-content { position: relative; .el-tree.tree-type { height: 400px; overflow-y: scroll; .custom-tree-node { span { &:hover { color: white; background: #0085f6; } i { color: #fbd076; } } } } .popover-container { position: absolute; .el-popover { div { padding: 5px 10px; i { margin-right: 10px; } &:hover { color: #ffffff; background: #0085f6; cursor: pointer; } } } } } } } .el-dialog__footer { padding: 0px; .dialog-footer { display: inline-block; width: 100%; .el-button { width: 100%; margin: 0; border-radius: 0; } } } } } } </style> ~~~ ### 4. input输入框中通过回车触发事件 ~~~ <el-input placeholder="请输入内容" suffix-icon="el-icon-search" v-model="input1" @keyup.enter.native="searchMode()" > </el-input> ~~~ ### 5. 点击显示与隐藏性能优化(vue中操作dom节点) ~~~ 1. 通过给父元素一个min-height 2. 当点击时使height:auto实现显示隐藏 <div class="more" @click="handleMore(item.moreCode)">显示更多</div> handleMore(e) { // console.log(e) // console.log('this.modelsAll',this.modelsAll) const contentHeight = document.getElementsByClassName('page-cover-content') const moreText = document.getElementsByClassName('more') if (moreText.length !== 1) { if (moreText[e].innerHTML === '显示更多') { contentHeight[e].style.cssText = 'height:auto' moreText[e].innerHTML = '收起更多' } else { contentHeight[e].style.cssText = 'height:236px' moreText[e].innerHTML = '显示更多' } } if (moreText.length === 1) { if (moreText[0].innerHTML === '显示更多') { contentHeight[0].style.cssText = 'height:auto' moreText[0].innerHTML = '收起更多' } else { contentHeight[0].style.cssText = 'height:236px' moreText[0].innerHTML = '显示更多' } } }, ~~~ ### 6. 表格中实现选框 ### 7. 表格中实现排序 ### 8. 原生布局实现一排摆放几个div(bootstarp实现原理) ~~~ 1. 最外层container容器使用margin-right: auto;margin-left: auto;实现自适应实现等间距排列 2. row行使用伪元素清楚浮动 3. 子元素通过%实现宽度,然后通过浮动实现布局 4. 最终实现响应式 5. 在实际开发中不使用原生的实现方案,过于繁琐,开发实现方案: 5.1 使用bootstrap(用的少) 5.2 使用前端UI库中的layout布局组件实现响应式 ~~~ ### 9.响应式布局比较 ~~~ 1. flex可实现响应式,缺点是多出来的元素排两边有点难看 2. grid可以实现响应式,缺点在元素个数未知的情况下不能定义行数自适应 3. 使用前端UI库能很好的实现 ~~~ ### 10. 饿了么中tree结构问题(实现,自定义) ~~~ <el-tree ref="modelTree" //每个节点对应key唯一 node-key="id" //默认展开的数节点的key值可以是变量(数组),然后在下面代码中添加值 :default-expanded-keys="[111111]" highlight-current //要渲染的数结构数据 :data="allDataSourceType" //修改树结构中默认的值(重点,项目中的数据不能跟默认的相同,通过这个属性实现数据名的替换)(defaultProps: {label: 'name',children: 'children' }, // el-tree组件执行数据名) :props="defaultProps" //默认是否全部展开 :default-expand-all="false" :render-after-expand="false" //节点点击事件 @node-click="onClickNodes" > //tree中默认的是将data中的数据进行显示,如果要定制化则使用卡槽实现定制化:使用方法如下 <span class="custom-tree-node" slot-scope="{ node }"> <span> <i :class="node.icon"></i> {{ node.label }} </span> </span> </el-tree> ~~~