(o゜▽゜)o☆ 青椒味的Hello World
沒有項(xiàng)目工程柔逼,沒有vue腳手架蒋譬,就一個(gè)HTML頁面;沒有干貨愉适,純畫頁面羡铲,沒有后臺(tái),數(shù)據(jù)寫死儡毕,堆了些簡單的Element UI控件,實(shí)現(xiàn)了前端table的增刪改查的點(diǎn)點(diǎn)點(diǎn)操作
1.界面展示
普普通通的界面和功能
2.Table本身
2.1 el-table的數(shù)據(jù)源
會(huì)綁定一個(gè)數(shù)據(jù)源data扑媚,data的格式是數(shù)組腰湾,所以之后在操作這個(gè)數(shù)組時(shí),數(shù)組的下標(biāo)(行索引)就比較重要了
:data="tableData"
tableData = [{
line: 1,
date: '2016-05-02',
name: '赫敏',
address: '上海市普陀區(qū)金沙江路 1518 弄',
age: 23,
num: 500,
str1: null,
str2: null,
str2laber: null,
str2dis: false,
str3: null,
str3laber: null,
str3dis: false,
str4: null
},
{
line: 2,
date: '2016-05-04',
name: '皮卡丘',
address: '上海市普陀區(qū)金沙江路 1517 弄',
age: 42,
num: 70000,
str1: null,
str2: 20,
str2laber: '我的貂蟬在哪里',
str2dis: true,
str3: null,
str3laber: null,
str3dis: false,
str4: null
}]
2.2 el-table的相關(guān)樣式
一些基礎(chǔ)的樣式比如Table帶邊框疆股,有斑馬紋,固定表頭,固定列锈至,Table高度自適應(yīng)部脚,列寬按比例 這些都是Element UI自己就支持的,查一下官方的代碼就知道怎么寫
但是官方Table的行高两残,默認(rèn)是比較高的永毅,需要自己去調(diào)整CSS樣式,這里主要是內(nèi)邊距屬性值的調(diào)整
/* 合計(jì)行的樣式(每個(gè)單元格的樣式) */
.tabledata td {
padding: 0;
font-size: 13px;
}
/* 設(shè)置表頭樣式 */
.tabledata .el-table__header th {
padding: 0;
background-color: #F5F7FA;
}
2.3 el-table的合計(jì)
在el-table標(biāo)簽中加入 show-summary 即可實(shí)現(xiàn)合計(jì)人弓;使用 :summary-method="getSummaries" 讓其返回一個(gè)數(shù)組沼死,這個(gè)數(shù)組中的各項(xiàng)就會(huì)顯示在合計(jì)行的各列中,就可以實(shí)現(xiàn)自定義的合計(jì)崔赌;當(dāng)然我這里的合計(jì)顯示還是有bug的意蛀,比如日期列也會(huì)合計(jì),但是我不想調(diào)了
用到的JS函數(shù)的說明(摘自菜鳥教程):
map() 函數(shù)返回一個(gè)新數(shù)組健芭,數(shù)組中的元素為原始數(shù)組元素調(diào)用函數(shù)處理后的值县钥。
Number() 函數(shù)把對(duì)象的值轉(zhuǎn)換為數(shù)字。如果對(duì)象的值無法轉(zhuǎn)換為數(shù)字慈迈,那么返回 NaN若贮。
every() 函數(shù)用于檢測數(shù)組所有元素是否都符合指定條件。
isNaN() 函數(shù)用于檢查其參數(shù)是否是非數(shù)字值。
reduce() 函數(shù)接收一個(gè)函數(shù)作為累加器兜看,數(shù)組中的每個(gè)值(從左到右)開始縮減锥咸,最終計(jì)算為一個(gè)值。
getSummaries方法的參數(shù)param如圖所示
// 合計(jì) /代碼中注釋的代碼 因?yàn)椴患嫒軮E瀏覽器细移,替換成現(xiàn)在的代碼并注視掉了
getSummaries: function (param) {
// const { columns, data } = param;
// const sums = [];
var _param = param,
columns = _param.columns,
data = _param.data;
var sums = [];
columns.forEach(
// (column, index) => {
// if (index === 0) {
// sums[index] = '合計(jì)';
// return;
// }
// const values = data.map(item => Number(item[column.property]));
// if (!values.every(value => isNaN(value))) {
// sums[index] = values.reduce((prev, curr) => {
// const value = Number(curr);
// if (!isNaN(value)) {
// return prev + curr;
// } else {
// return prev;
// }
// }, 0);
// sums[index] += '';
// } else {
// sums[index] = '';
// }
// }
function (column, index) {
if (index === 0) {
sums[index] = '合計(jì)';
return;
}
const values = data.map(
//item => Number(item[column.property]);
function (item) { return Number(item[column.property]); }
);
if (!values.every(
//value => isNaN(value)
function (value) { return isNaN(value) }
)) {
sums[index] = values.reduce(
// (prev, curr) => {
// const value = Number(curr);
// if (!isNaN(value)) {
// return prev + curr;
// } else {
// return prev;
// }
// }
function (prev, curr) {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}
, 0);
sums[index] += '';
} else {
sums[index] = '';
}
}
);
return sums;
}
2.4 el-table的分頁
這里用到的是分頁的完整功能搏予,分頁功能是獨(dú)立于el-table,只是操作些數(shù)據(jù)去調(diào)整el-table的數(shù)據(jù)源弧轧,我覺得差不多可以這樣理解
<div class="block" align="right">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageindex"
:page-sizes="[10, 20, 30, 40]" :page-size="100" layout="total, sizes, prev, pager, next, jumper"
:total="tableData.length">
</el-pagination>
</div>
handleSizeChange: function (val) {
console.log('每頁 ${val} 條');
},
handleCurrentChange: function (val) {
console.log('當(dāng)前頁碼: ${val}');
},
2.5 el-table的事件
這里用到了 行的單擊事件(row-click)(雙擊實(shí)現(xiàn)編輯) / 行的雙擊事件(cell-dblclick)(單擊其他行取消編輯)/ 復(fù)選框選擇事件(selection-change)(當(dāng)選擇項(xiàng)發(fā)生變化時(shí)會(huì)觸發(fā)該事件)
<el-table class="tabledata" :data="tableData" :summary-method="getSummaries" show-summary
@row-dblclick="RowDblclick" @row-click="RowClick" @selection-change="SelectFun" stripe border
style="width: 100%">
<el-table-column type="selection" align="center" width="60"></el-table-column><!-- type="selection" 復(fù)選框 -->
2.6 el-table的插槽
這個(gè)很重要雪侥,在el-table要獲得每一行的數(shù)據(jù),那么就需要使用插槽(<template slot-scope="scope"></template>)
網(wǎng)上貌似還有一種插槽 slot精绎,但還是推薦這種 slot-scope
獲取當(dāng)前行數(shù)據(jù):scope.row
獲取當(dāng)前行的xxx字段數(shù)據(jù):scope.row.xxx
獲取當(dāng)前行的索引:scope.$index
<el-table-column label="自定義列2" width="270%">
<template slot-scope="scope"><!-- 插槽 -->
<el-select v-show="doubleclick==scope.row.line" v-model="scope.row.str2" :disabled="scope.row.str2dis"
filterable remote reserve-keyword placeholder="請(qǐng)選擇你的英雄" :remote-method="RemoteMethod"
@change="SelectStr2(scope.row.str2,scope.$index)" size="mini" clearable>
<el-option v-for="item in options_st2" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
<el-button v-show="doubleclick==scope.row.line" :disabled="scope.row.str2dis" icon="el-icon-search"
@click="dialogTable=true" size="mini"></el-button>
<span v-show="doubleclick!=scope.row.line">{{scope.row.str2laber}}</span>
</template>
</el-table-column>
2.7 el-table實(shí)現(xiàn)行編輯
這個(gè)是雙擊行觸發(fā)編輯速缨,然后是 el-table-column 中會(huì)有一個(gè)顯示標(biāo)簽和編輯的控件標(biāo)簽,用雙擊記錄的當(dāng)前行索引去對(duì)比當(dāng)前行的索引代乃,滿足則顯示編輯的控件標(biāo)簽旬牲,不滿足則顯示顯示標(biāo)簽;當(dāng)單擊其它行的時(shí)候搁吓,把記錄當(dāng)前行索引的變量置為空原茅,這樣就取消編輯了。這是整體的思路堕仔,網(wǎng)上也有說用鼠標(biāo)焦點(diǎn)什么的擂橘,但是沒有嘗試成功
2.8 el-table查找框處理
在 el-table 中用了一些常用的控件標(biāo)簽,比如日期框摩骨,數(shù)值框通贞,下拉選擇框,Switch 開關(guān)恼五,文本框昌罩,按鈕,以及這個(gè)下拉選擇框+按鈕組合的查找框
在Element UI中下拉選擇框很智能唤冈,可以設(shè)置成百度搜索框那樣的自動(dòng)完成功能峡迷,用 el-selec t和 el-option 組合使用,官方也有說明怎樣使用
Element UI官方提供了一個(gè)遠(yuǎn)程搜索方法 remote-method你虹,這個(gè)我寫了绘搞,但是發(fā)現(xiàn)我寫不寫貌似都會(huì)進(jìn)行搜索,但是我的搜索是基于已經(jīng)有的數(shù)據(jù)源(就是el-option綁定的數(shù)組)去進(jìn)行搜索傅物,所以這個(gè)遠(yuǎn)程搜索方法還沒有太明白夯辖,而且這個(gè)方法是每輸入一個(gè)字就會(huì)被觸發(fā),所以感覺慎用
再說回到這個(gè)查找框董饰,就是下拉選擇框+按鈕蒿褂,下拉選擇框上面已經(jīng)說了官方有示例圆米,是可以自動(dòng)完成的;而點(diǎn)擊按鈕時(shí)是會(huì)彈出一個(gè) el-dialog啄栓,上面會(huì)有 el-input 查找框娄帖、el-table 展示數(shù)據(jù)及按鈕操作
el-dialog
這里遇到了四個(gè)樣式的問題:
一、點(diǎn)擊灰色部分時(shí)需要不關(guān)閉此彈框(這個(gè)是在 el-dialog 中加上 :before-close="HandleClose" 這個(gè)關(guān)閉的回調(diào)函數(shù)昙楚,然后直接return false; 就好了)
二近速、右上角的?號(hào)需要隱藏(在加上了上面的方法之后,右上角的?號(hào)就失去作用了堪旧,點(diǎn)擊了也不會(huì)關(guān)閉削葱,且在 el-dialog 中加上 show-close=false 也還是會(huì)顯示,所以不得已用了CSS樣式去控制)
/* 彈出英雄框不顯示右上角X號(hào)按鈕 */
.el-dialog__headerbtn .el-dialog__close {
display: none;
}
三淳梦、灰色的遮罩層在當(dāng)前主題會(huì)顯示為白色析砸,然后就和 el-dialog 融為一體了,視覺效果很不好爆袍,所以這里修改了CSS樣式
/* 彈出英雄選擇框的背景遮罩 */
.v-modal {
background-color: rgba(0, 0, 0, 0.8);
}
四首繁、在el-table中想實(shí)現(xiàn)選中行(這里會(huì)有變量在單擊行的時(shí)候記錄行索引),高亮陨囊,然后點(diǎn)擊確定的操作蛮瞄,el-table 自己是支持選中的時(shí)候高亮的,但是顏色不太明顯谆扎,所以這里用CSS修改了選中行的樣式
/*彈出英雄框點(diǎn)擊選中行的背景樣式*/
.el-table__body tr.current-row>td {
background-color: #b8d0ecc9;
}
3.增刪改查操作
3.1 新增
這里的新增就是在 el-table 中新增一行空的數(shù)據(jù),也就相當(dāng)于在 el-table 綁定的數(shù)組中新增一組空的數(shù)據(jù)芹助,并將記錄當(dāng)前編輯行的變量賦值為新添加的行的索引
// 添加一行
AddRow: function () {
var data = {
line: this.tableData.length + 1,
date: null,
name: null,
address: null,
age: null,
num: null,
str1: null,
str2: null,
str2laber: null,
str3: null,
str4: null
}
this.tableData.push(data);
this.doubleclick = this.tableData.length;
},
3.2 刪除
這里的刪除會(huì)有兩個(gè)操作的入口
3.2.1 el-table 中的單行刪除堂湖,刪除的時(shí)候會(huì)有確認(rèn)框彈出(觸發(fā) Popover 的元素,使用 slot="reference" 的具名插槽)但是這里有個(gè)問題就是,刪除了一行之后状土,下一行的 el-popover 依舊會(huì)彈出无蜂,可能使用官方的自定義指令 v-popover 能夠解決這個(gè)問題,但是還不會(huì)用??
單行刪除
<el-table-column label="操作" width="137%" align="center" fixed="right">
<template slot-scope="scope">
<el-popover trigger="click" placement="top" width="160">
<p>Are you sure to delete?</p>
<div align="center">
<el-button size="mini" type="danger" icon="el-icon-delete" circle @click="DeleteData(scope.$index, tableData)"></el-button>
</div>
<!-- slot="reference" 觸發(fā) Popover 的元素,使用 slot="reference" 的具名插槽 -->
<el-button size="mini" type="danger" slot="reference">刪除</el-button>
</el-popover>
<!-- slot-scope="scope" 通過 Scoped slot 可以獲取到 row, column, $index 和 store(table 內(nèi)部的狀態(tài)管理)的數(shù)據(jù)-->
<el-button size="mini" type="primary" @click="HandleEdit(scope.$index, scope.row)">編輯</el-button>
</template>
</el-table-column>
3.2.2 el-table 中的批量刪除蒙谓,通過前面勾選復(fù)選框斥季,點(diǎn)擊頭上的刪除按鈕實(shí)現(xiàn)
批量刪除
復(fù)選框也是 el-table 中的一列,不需要綁定數(shù)據(jù)累驮,選擇事件是 selection-change 酣倾,參數(shù)是選中行的數(shù)組對(duì)象
<el-table class="tabledata" :data="tableData" :summary-method="getSummaries" show-summary
@row-dblclick="RowDblclick" @row-click="RowClick" @selection-change="SelectFun" stripe border
style="width: 100%">
<!-- type="selection" 復(fù)選框 -->
<el-table-column type="selection" align="center" width="60px"></el-table-column>
3.3 修改
整體的思路在上面 2.7 el-table實(shí)現(xiàn)行編輯 已經(jīng)說了,這里貼一些示例代碼把
v-show="doubleclick==scope.row.line" 就是判斷雙擊事件記錄的行索引是否等于當(dāng)前的行索引谤专,而單擊行的時(shí)候會(huì)判斷是否是單擊的當(dāng)前行躁锡,如果不是,則清空雙擊事件記錄的行索引置侍,從而實(shí)現(xiàn)編輯和不編輯
<el-table-column label="數(shù)值" width="120%" align="right">
<template slot-scope="scope">
<el-input v-show="doubleclick==scope.row.line" type="Number" placeholder="請(qǐng)輸入內(nèi)容"
v-model.number="scope.row.num" size="mini" clearable>
</el-input>
<span v-show="doubleclick!=scope.row.line">{{scope.row.num}}</span>
</template>
</el-table-column>
4.Element UI 主題風(fēng)格
Element UI默認(rèn)的主題風(fēng)格是比較鮮艷活潑的映之,但是我想要比較克制拦焚,有灰度的主題風(fēng)格(就是實(shí)現(xiàn)換主題風(fēng)格)以適應(yīng)之后工作上的需求,于是再一次偶然之中發(fā)現(xiàn)官網(wǎng)上可以自定義配置 Element UI 主題風(fēng)格
5.Element UI 圖標(biāo)
由于沒有項(xiàng)目工程杠输,沒有vue腳手架赎败,引用的 Element UI 中的樣式很多是需要有圖標(biāo)的,所以百度了很久都不知道要怎么加進(jìn)來圖標(biāo)蠢甲,直到有一天僵刮,看見別人說在請(qǐng)求的URL中發(fā)現(xiàn)了關(guān)于圖標(biāo)的線索,我才知道怎么去加 Element UI 圖標(biāo)
圖標(biāo)地址
6.踩過的坑
6.1 行的索引
行的索引對(duì)于el-table的數(shù)據(jù)交互很重要峡钓,但是除了 slot-scope="scope" 插槽可以獲得行的索引妓笙,或者官方某些少數(shù)的方法提供行索引參數(shù)外,其它的很難獲取行索引能岩,所以在此表格中 line 列就是提供了行索引的功能寞宫,但是在刪除和新增操作之后,是需要?jiǎng)討B(tài)及時(shí)的去調(diào)整的拉鹃,如下代碼
watch: {
// deep: true深度監(jiān)聽heroData(是彈出來的選擇英雄框的el-table數(shù)據(jù)源)變化后重新計(jì)算行索引
heroData: {
handler: function (val, oldval) {
this.heroData = val;
for (var i = 0; i < this.heroData.length; i++) {
this.heroData[i].hero = i + 1;
}
},
deep: true
}
}
6.2 日期時(shí)間格式問題
選擇時(shí)間標(biāo)簽辈赋,選擇完時(shí)間后,返回的時(shí)間格式不是想要的膏燕,然后就需要自己再去轉(zhuǎn)換時(shí)間格式
// 日期框的日期格式轉(zhuǎn)換
DateFormats: function (date) {
if (date != null) {
var ss = typeof (date);
if (ss == 'string') {
return date;
}
var fmt = "yyyy-MM-dd"
var o = {
"M+": date.getMonth() + 1,//月份
"d+": date.getDate(),//日
"h+": date.getHours(),//小時(shí)
"m+": date.getMinutes(),//分
"s+": date.getSeconds(),//秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds()//毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
}
6.3 IE兼容問題
在快要完成的時(shí)候钥屈,發(fā)現(xiàn)IE上面頁面是崩的,后來發(fā)現(xiàn)坝辫,是IE不兼容部分語法篷就,主要是ES6中的箭頭函數(shù),及VUE中的methods中的方法的定義的問題
不兼容箭頭函數(shù) =>
// 輸入字符選擇英雄時(shí)觸發(fā)事件,進(jìn)行模糊匹配 /遠(yuǎn)程搜索方法,此方法可廢除
RemoteMethod: function (query) {
if (query !== '') {
this.options_st2 = this.listStr2.filter(
// item => {
// return item.label.toLowerCase()
// .indexOf(query.toLowerCase()) > -1;
// }
function (item) {
return item.label.toLowerCase().indexOf(query.toLowerCase()) > -1;
}
);
}
else {
this.options_st2 = [];
}
}
methods中的方法必須用 : 去定義
// 選中table行的數(shù)據(jù)
SelectFun: function (val) {
this.deleteList = val;
},
6.4 loading轉(zhuǎn)圈問題
在加載數(shù)據(jù)的時(shí)候模擬等待了兩秒近忙,以顯示轉(zhuǎn)圈的效果竭业,結(jié)果把 this.loading = false; 寫在了 setTimeout 方法外面就沒有效果,寫在里面就是OK的
// 數(shù)據(jù)初始化 鉤子函數(shù)
mounted: function () {
setTimeout(() => { this.DataAdd(); this.loading = false; }, 2000);
}