【Element UI】使用問題記錄
轉載:https://www.cnblogs.com/yangchongxing/p/10750994.html
下載地址:
https://unpkg.com/browse/element-ui@2.11.1/
https://unpkg.com/element-ui@2.11.1/lib/index.js
https://unpkg.com/element-ui@2.11.1/lib/theme-chalk/index.css
=============================================================
17、表格樹 el-table-tree-column 問題
=============================================================
a. 顯示無法清空
<el-cascader ref="mycascader" :options="dataArray" v-model="selectData" :show-all-levels="false" expand-trigger="click" clearable change-on-select> </el-cascader>
定義一個 ref ,使用 clearValue 方法清空
let obj = {}; obj.stopPropagation = () =>{}; this.$refs.mycascader.clearValue(obj);
clearValue 源碼如下,此處clearValue需要傳入一個事件對象 這里是自己模擬一個事件對象來避免報錯
clearValue: function clearValue(ev) { ev.stopPropagation(); this.handlePick([], true); }
b. 每一層都選擇
追加 change-on-select 屬性,去掉則只能選擇葉子結點
c. 選中指定的值
let position = []; position.push(value); this.$refs.mycascader.handlePick(position);
d. 顯示和隱藏菜單
this.$refs.mycascader.showMenu(); this.$refs.mycascader.hideMenu();
e. 實現可輸入可選擇
<template> <el-cascader filterable ref="cstmInputDepartmentDascader" :options="departmentCascader" v-model="departmentValue" :props="{ checkStrictly: true }" :show-all-levels="showAllLevels" :size="showSize" :debounce="500" style="width: 100%" :before-filter="beforeFilterDepartment" @blur="blurDepartment" @focus="focusDepartment" @change="changeDepartment" @visible-change="visibleChange" :placeholder="showPlaceholder" clearable ></el-cascader> </template> <script> import {deepClone} from '@/util/util'; import {getCascaderAttach} from '@/api/admin/department'; export default { name: "input-department-cascader", props: { value: {}, showAllLevels: { type: Boolean, default: false }, showSize: { type: String, default: 'medium' }, showPlaceholder: { type: String, default: '' } }, data() { return { departmentList: [], departmentCascader: [], departmentCascaderBack: [], departmentCascaderLength: undefined, departmentValue:[], inputDepartmentName: undefined, increment: 1 } }, created() { this.getDepartmentCascader(); }, mounted() { this.init(); }, methods: { getDepartmentCascader() { getCascaderAttach().then(response => { // 部門列表數據 id,parentId,treePosition, 根節點parentId是0,treePosition沒有 this.departmentList = response.data.attachData; // 部門級聯數據 label,value,children,disabled this.departmentCascader = response.data.cascaderData; this.departmentCascaderLength = this.departmentCascader.length; // 部門級聯數據備份 this.departmentCascaderBack = deepClone(this.departmentCascader); this.init(); }) }, init() { if (!this.value) return; let value = []; let list = deepClone(this.departmentCascaderBack); let department = this.getDepartmentById(this.value); // 沒有找到就認為是輸入的數據 if (!department) { list.push(this.getItem(this.value)); value.push(this.value); } else { if (department.treePosition) { value = department.treePosition.substr(1).split('&'); } value.push(this.value); } this.departmentCascader = list; this.departmentValue = value; }, getDepartmentById(id) { let department = undefined; if (this.departmentList && id) { for (let item of this.departmentList) { if (id === item.id) { department = deepClone(item); break; } } } return department; }, getItem(name) { return { value: name, label: name, children: undefined, disabled: false } }, beforeFilterDepartment: function(value) { this.inputDepartmentName = value; return false; }, blurDepartment() { if (!this.inputDepartmentName) return; this.inputDepartmentName = this.inputDepartmentName.trim(); if (this.inputDepartmentName === "") return; this.$set(this.departmentCascader, this.departmentCascaderLength, this.getItem(this.inputDepartmentName)); this.departmentValue = [this.inputDepartmentName]; this.inputDepartmentName = undefined; this.changeDepartment(this.departmentValue); }, focusDepartment() { this.$refs.cstmInputDepartmentDascader.$refs.input.$refs.input.select(); }, changeDepartment(v) { if (v && v.length > 0) { this.$emit('input', v[v.length - 1]); } else { this.$emit('input', ''); } }, visibleChange(flag) { if (flag) return; if (this.departmentValue && this.departmentValue.length > 0) { let departmentId = this.departmentValue[this.departmentValue.length - 1]; let departmentName = ''; let department = this.getDepartmentById(departmentId); if (department) { departmentName = department.name; } else { departmentName = departmentId; } this.$emit('departmentChange', departmentId, departmentName); } else { this.$emit('departmentChange', '', ''); } }, setDepartmentValue(v) { this.departmentValue = v; } } } </script> <style scoped> </style>
filterable 開啟過濾,也就是變成可輸入
before-filter 篩選之前的鈎子,參數為輸入的值,若返回 false 或者返回 Promise 且被 reject,則停止篩選
blur 失去焦點
f、獲取當前的 label
<el-cascader ref="myCascader" :options="myList" v-model="myPosition" @change="myChange" size="small"></el-cascader> getMyList(){ this.myList = []; // 查詢結果 getMyListFromDB().then(response => { this.myList = response.data; if(this.myList.length > 0){ let v = []; this.getDefault(v, this.myList);//取出默認第一個的數組 this.myPosition = v;//選中第一個 if (v.length > 0) { let selectValue = v[v.length - 1]; let selectLabel = this.currentLabels(v); } } }) }, getDefault(result, list) { if (list) { result.push(list[0].value); this.getDefault(result, list[0].children); } }, currentLabels(v) { let options = this.myList; let labels = []; v.forEach(value => { const targetOption = options && options.filter(option => option['value'] === value)[0]; if (targetOption) { labels.push(targetOption['label']); options = targetOption['children']; } }); // 拼接標簽數組 let label = this.$refs.myCascader.showAllLevels ? labels.join('/') : labels[labels.length - 1]; return label; }, myChange(v){ if (v.length > 0) { let selectValue = v[v.length - 1]; let selectLabel = this.currentLabels(v); } }
g、選中可輸入級聯中的所有值
this.$refs.mycascader.$refs.input.$refs.input.select();
validate
對整個表單進行校驗的方法,參數為一個回調函數。該回調函數會在校驗結束后被調用,並傳入兩個參數:是否校驗成功和未通過校驗的字段。若不傳入回調函數,則會返回一個 promise
Function(callback: Function(boolean, object))
例:this.$refs['myForm'].validate((valid, obj) => {});
validateField
對部分表單字段進行校驗的方法
Function(props: array | string, callback: Function(errorMessage: string))
例:this.$refs['myForm'].validateField('myField', errorMsg => {});
resetFields
對整個表單進行重置,將所有字段值重置為初始值並移除校驗結果
例:this.$refs['myForm'].resetFields();
clearValidate
移除表單項的校驗結果。傳入待移除的表單項的 prop 屬性或者 prop 組成的數組,如不傳則移除整個表單的校驗結果
Function(props: array | string)
例:
this.$refs['myForm'].clearValidate();
this.$refs['myForm'].clearValidate(["myField1","myField2"]);
表單定義 ref="myForm"
Form Methods 表單方法
validate 對整個表單進行校驗的方法,參數為一個回調函數。該回調函數會在校驗結束后被調用,並傳入兩個參數:是否校驗成功和未通過校驗的字段。若不傳入回調函數,則會返回一個 promise Function(callback: Function(boolean, object))
validateField 對部分表單字段進行校驗的方法 Function(props: array)
清除表單值和校驗信息
this.$refs['myForm'].resetFields();
清除表單校驗信息
this.$refs['myForm'].clearValidate();
校驗單校
this.$refs['myForm'].validate(valid => {
if(valid) {
// 檢驗成功,沒有問題
} else {
// 校驗失敗,有錯誤
}
});
校驗字段
this.$refs['myForm'].validateField('name', errorMsg => {
if (!errorMsg) {
} else {
callback(new Error("請輸入姓名"));
}
});
跟規則校驗,nameEnable == 0時不校驗,其他時候校驗
const checkName = (rule, value, callback) => { if (/^[\u4e00-\u9fa5]{2,4}$/.test(value)) { callback(); } else { callback(new Error('請輸入漢字')); } }; settingRules: { name: [ {required: true, message: '請輸入姓名'}, {validator: checkName, trigger: ['blur','change']} ], } <el-form-item label="姓名" prop="name" ref="nameField" :rules="nameEnable == 0 ? [] : userRules.name"> <el-input v-model="user.name" maxlength="4"></el-input> </el-form-item>
this.$forceUpdate();
在vue中並不是每次數據改變都會觸發更新dom,而是將這些操作都緩存在一個隊列,在一個事件循環結束之后,刷新隊列,統一執行dom更新操作。 而如果想在DOM狀態更新后做點什么,則需要用到nextTick。在vue生命周期的created()鈎子函數進行的DOM操作要放在Vue.nextTick()的回調函數中,因為created()鈎子函數執行的時候DOM並未進行任何渲染,而此時進行DOM操作是徒勞的,所以此處一定要將DOM操作的JS代碼放進Vue.nextTick()的回調函數中。
通過下面的方式設置光標
this.$nextTick(() => { this.$refs['viewFocus'].focus(); });
userRules: { name: [ {required: true, message: '請輸入名稱'} {validator: checkName, trigger: ['blur','change']} ] } const checkName = (rule, value, callback) => { isNameExist(name: name}).then(response => { if (response.status == 200 && response.data) { callback(new Error(response.message)); return; } }); callback(); };
全局匹配非數字,/[^\d]/g.test(value) true說明有非數字需要提示錯誤,false說明都是數字驗證通過
正常:border-color: #dcdfe6;
焦點:border-color: #409EFF;
出錯:border-color: #f56c6c;
input::-webkit-input-placeholder { color: #C0C4CC; font-size: 14px; } input:-moz-placeholder { color: #C0C4CC; font-size: 14px; } input:-ms-input-placeholder { color: #C0C4CC; font-size: 14px; } .imageNameInput { margin-top: 2px; -webkit-appearance: none; background-color: #fff; background-image: none; border-radius: 4px; border: 1px solid #dcdfe6; -webkit-box-sizing: border-box; box-sizing: border-box; color: #606266; display: inline-block; color: #303133; font-size: 14px; height: 40px; line-height: 40px; outline: 0; padding: 0 15px; -webkit-transition: border-color .2s cubic-bezier(.645,.045,.355,1); transition: border-color .2s cubic-bezier(.645,.045,.355,1); width: 160px; } .imageNameInput input[type=text]:focus{ outline: 1px solid #409EFF; }
直接給prop綁定為數組下的名稱
參考文章:https://www.cnblogs.com/beileixinqing/p/10969828.html
model: { images: undefined, imageArray: [] } imageArray的屬性{name: undefined, url: undefined, del: false} <el-form-item label="圖片" prop="images"> <el-input v-model="model.images"></el-input> <div v-for="(o,i) in model.imageArray" class="image-uploader"> <el-form-item :prop="`imageArray[${i}].name`" :rules="{ required: true, message: '圖片名稱', trigger: 'blur' }"> <img :src="o.url" class="image-add"> <el-input v-model="o.name" maxlength="20"></el-input> </el-form-item> </div> </el-form-item>
給視頻指定樣式即可
參考文檔:https://blog.csdn.net/wuqingyou_w/article/details/51671356
video { width: 100%; height: 100%; object-fit:fill; }
選中行
給 el-table 定義 ref="menuTable" :data="menuList"
this.$refs.menuTable.toggleRowSelection(this.menuList[0]);
列內容過長隱藏
el-table-column show-overflow-tooltip 當內容過長被隱藏時顯示 true/false 例::show-overflow-tooltip="true" el-table tooltip-effect 控制顏色 dark/light 例:tooltip-effect="light"
a.設置樹選中行的顏色
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content { background-color: #a6d1ff; }
b.選中樹結點
// 通過 key 設置某個節點的當前選中狀態,使用此方法必須設置 node-key 屬性 // (key) 待被選節點的 key,若為 null 則取消當前高亮的節點 this.$refs.myTree.setCurrentKey(myKey); // 通過 node 設置某個節點的當前選中狀態,使用此方法必須設置 node-key 屬性 this.$refs.myTree.setCurrentNode(myNode);
選中單個
this.$refs['catalogTree'].setChecked(catalogId, true, false);
清空選中
this.$refs['catalogTree'].setCheckedKeys([])
設置黃色背景變成白色背景
input:-webkit-autofill { box-shadow: 0 0 0px 1000px white inset !important; } input:-webkit-autofill:focus { box-shadow: 0 0 0px 1000px white inset !important; }
設置透明:
input:-internal-autofill-previewed, input:-internal-autofill-selected { -webkit-text-fill-color: #FFFFFF !important; transition: background-color 5000s ease-in-out 0s !important; }
不要混合用、親測有效
<template> <el-cascader filterable ref="cstmInputDepartmentDascader" :options="departmentCascader" v-model="departmentValue" :props="{ checkStrictly: true }" :show-all-levels="showAllLevels" :debounce="500" style="width: 100%" :before-filter="beforeFilterDepartment" @blur="blurDepartment" @focus="focusDepartment" @change="changeDepartment" ></el-cascader> </template> <script> import {deepClone} from '@/util/util'; import {getCascaderAttach} from '@/api/admin/department'; export default { name: "input-department-cascader", props: { value: {}, showAllLevels: { type: Boolean, default: false } }, data() { return { departmentList: [], departmentCascader: [], departmentCascaderBack: [], departmentCascaderLength: undefined, departmentValue:[], inputDepartmentName: undefined, increment: 1 } }, created() { this.getDepartmentCascader(); }, mounted() { this.init(); }, methods: { getDepartmentCascader() { getCascaderAttach().then(response => { // 部門列表數據 id,parentId,treePosition, 根節點parentId是0,treePosition沒有 this.departmentList = response.data.attachData; // 部門級聯數據 label,value,children,disabled this.departmentCascader = response.data.cascaderData; this.departmentCascaderLength = this.departmentCascader.length; // 部門級聯數據備份 this.departmentCascaderBack = deepClone(this.departmentCascader); this.init(); }) }, init() { if (!this.value) return; let value = []; let list = deepClone(this.departmentCascaderBack); let department = this.getDepartmentById(this.value); // 沒有找到就認為是輸入的數據 if (!department) { list.push(this.getItem(this.value)); value.push(this.value); } else { if (department.treePosition) { value = department.treePosition.substr(1).split('&'); } value.push(this.value); } this.departmentCascader = list; this.departmentValue = value; }, getDepartmentById(id) { let department = undefined; if (this.departmentList && id) { for (let item of this.departmentList) { if (id === item.id) { department = deepClone(item); break; } } } return department; }, getItem(name) { return { value: name, label: name, children: undefined, disabled: false } }, beforeFilterDepartment: function(value) { this.inputDepartmentName = value; return false; }, blurDepartment() { if (!this.inputDepartmentName) return; this.$set(this.departmentCascader, this.departmentCascaderLength, this.getItem(this.inputDepartmentName)); this.departmentValue = [this.inputDepartmentName]; this.inputDepartmentName = undefined; this.changeDepartment(this.departmentValue); }, focusDepartment() { this.$refs.cstmInputDepartmentDascader.$refs.input.$refs.input.select(); }, changeDepartment(v) { if (v && v.length > 0) { this.$emit('input', v[v.length - 1]); } else { this.$emit('input', ''); } } } } </script> <style scoped> </style>
this.$refs['catalogTree'].store.currentNode.expanded = true this.$refs['catalogTree'].store.nodesMap["id"].expanded = true
<!-- 日期 --> <el-date-picker v-model.trim="mydate" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" placeholder="請選擇日期"></el-date-picker> <!-- 時間 --> <el-time-picker v-model.trim="mytime" value-format="HH:mm:ss" format="HH:mm:ss" placeholder="請選擇時間"></el-time-picker> <!-- 時間戳 --> <el-date-picker v-model.trim="mydatetime" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss" type="datetime" placeholder="請選擇時間戳"></el-date-picker>
value-format 控制值的格式,format 控制顯示的格式,這兩個可以不同,根據具體情況選擇控制
17、表格樹 el-table-tree-column 問題
<el-table-tree-column fixed 是否固定 :expand-all="false" 是否展開 :indent-size="20" 子層相對於父層的縮進px child-key="children" 子層級數據(數組形式) levelKey="level" 層級1,2,3代表第幾層 treeKey="value" 當前層級的ID, 子層級的parentKey與父層級treeKey一致 parentKey="parentId" 父層級的ID, 與父層級treeKey一致 prop="label" 顯示的屬性 label="名稱" 表頭文字 >
注意:treeKey可以不指定,默認使用對象的ID屬性,若沒有ID屬性則需要使用treeKey明確指定屬性,否則會出現各個層級被同時操作的問題(都展開或關閉)。levelKey在沒有時子層和父層之間沒有縮進。
問題代碼
<el-dialog ref="taskDialog" title="標題" :fullscreen="true" :visible.sync="dialogTaskVisible" :close-on-click-modal="closeOnClickModal" @close="closeTaskDialog"> <iframe ref="taskIframe" :style="{height: iframeHeight}" :src="this.currentTask.url" class="iframe" @load="iframeLoad"></iframe> <div slot="footer" class="dialog-footer"> <el-button @click="closeTaskDialog">取消</el-button> </div> </el-dialog>
iframe 的 style 設置 height:100% 沒有撐開 el-dialog__body 部分
解決方式是給 iframe 動態設置具體的高
定義 iframeHeight,給 el-dialog 定義 ref="taskDialog", 綁定 @load="iframeLoad" 加載完成事件,在事件方法中計算高度並設置,
監聽窗口大小變化,在事件方法中計算高度並設置
data() { return { screenWidth: document.documentElement.clientWidth, screenHeight: document.documentElement.clientHeight, iframeHeight: '100%' }; }, watch:{ 'screenWidth':function(val){ //監聽屏幕寬度變化 }, 'screenHeight':function(val){ //監聽屏幕高度變化 this.iframeLoad(); } }, mounted() { var _this = this; window.onresize = function(){ // 定義窗口大小變更通知事件 _this.screenWidth = document.documentElement.clientWidth; //窗口寬度 _this.screenHeight = document.documentElement.clientHeight; //窗口高度 }; }, methods: { iframeLoad() { this.$nextTick(()=>{ this.iframeHeight = this.$refs['taskDialog'].$el.offsetHeight - 130 + 'px'; // 用 dialog 總高減去 頭部和底部的高,總寬 offsetWidth }) }, }
-