### elementUI中涉及到組件嵌套的時候如何進行傳值-slot插槽作用域
```vue <template> <zujian> <template slot-scope="props"> <p>{{props.row.屬性}}</p> </template> </zujian> </template> ```
### 商家列表-shoplist
①mock下新建shop.js,利用mock定義后端接口 /shopmanage/shoplist:
import Mock from "mockjs"; let shopData=Mock.mock({ "data|40":[ { "id|+1":1001, "shopName":"@csentence(3, 5)", "shopAddress":"@city(true)", "shopTel":/^1(3|5|7|8|9)\d{9}$/, "shopDesc":"@csentence", "tag":()=>{ let arr=[ { text:"水煮魚", type:"success" },{ text:"酸菜魚", type:"info" },{ text:"燉大鵝", type:"danger" },{ text:"紅燒排骨", type:"warning" } ]; let n=parseInt(1+Math.random()*arr.length); return arr.slice(0,n); }, } ] }) Mock.mock(/\/shopmanage\/shoplist/,"get",(options)=>{ let {limit,page}=JSON.parse(options.body); let arr=[]; /* 分頁: 當page為1時,i為0~9 當page為2時,i為10~19 ... */ for(let i=limit*(page-1);i<limit*page;i++){ arr.push(shopData.data[i]); } return { dataList:arr, total:shopData.data.length }; })
②引入:
mock/index.js中:import "./shop.js";
main.js中:import "@mock/index.js";
③api/request.js中定義請求方法 shopListApi:
/* 商家列表 */ export const shopListApi = (shopInfo) => { return http({ method:"get", url:"/shopmanage/shoplist", data:shopInfo }) }
④pages/ShopManage/BusinessList/index.vue中請求數據,將limit和page傳過去:
import { shopListApi } from "@api/request.js"; export default { name: "BusinessList", data() { return { tableData: [], shopInfo:{ limit:10, page:1 }, total:0 }; }, methods: { async getShopList(shopInfo){ let data=await shopListApi(shopInfo); this.tableData=data.dataList; this.total=data.total; } }, created() { this.getShopList(this.shopInfo); }, };
⑤pages/ShopManage/BusinessList/index.vue中渲染數據:
<el-table-column label="ID" prop="id"></el-table-column> <el-table-column label="店鋪名稱" prop="shopName"></el-table-column> <el-table-column label="店鋪地址" prop="shopAddress"></el-table-column> <el-table-column label="聯系電話" prop="shopTel"></el-table-column> <el-table-column label="店鋪簡介" prop="shopDesc"></el-table-column> <el-table-column label="推薦菜品" prop="tag"></el-table-column> <el-table-column label="操作"> <el-button size="small">編輯</el-button> <el-button size="small">刪除</el-button> </el-table-column>
### 商家列表-table表格固定列和表頭
<el-table></el-table>標簽加上 height="500" 可以固定表頭 <el-table-column></el-table-column>標簽加上 fixed="left" 或 fixed="right" 可以固定列,但是要注意它的兄弟元素要加上width="300",全部兄弟元素的寬度加起來要大於父元素的寬度
### 商家列表-tag標簽
pages/ShopManage/BusinessList/index.vue中:
<el-table-column label="推薦菜品" prop="tag" width="300"> <template slot-scope="props"> <div class="tag-group"> <el-tag v-for="(item,index) in props.row.tag" :key="index" :type="item.type" effect="light" >{{item}}</el-tag> </div> </template> </el-table-column>
注意:
1、elementUI中組件中嵌套其他組件,先寫template標簽
2、三元嵌套定義type: :type="parseInt(Math.random()*4)==0?'success':parseInt(Math.random()*4)==1?'info':parseInt(Math.random()*4)==2?'danger':parseInt(Math.random()*4)==3?'warning':''"
配置項:
effect 主題:默認是light,dark表示有背景色,plain表示無背景色
### 商家列表-分頁
①pages/ShopManage/BusinessList/index.vue中給需要加分頁的頁面添加上分頁的元素,綁定 current-change 事件:
<el-pagination background layout="prev, pager, next" :total="total" @current-change="handleChange"></el-pagination>
②pages/ShopManage/BusinessList/index.vue中書寫 handleChange 方法:
handleChange(page){ this.shopInfo.page=page; this.getShopList(this.shopInfo); }
注意:事件函數不要帶括號,事件函數的參數就是當前頁數,將這個頁數拿到重新請求數據即可。
### 商家列表-對話框-刪除當前數據
①pages/ShopManage/BusinessList/index.vue中為刪除按鈕綁定click事件:
<el-table-column label="操作" fixed="right" width="150"> <template slot-scope="props"> <div> <el-button size="small" type="primary">編輯</el-button> <el-button size="small" type="danger" @click="handleDel(props.row)">刪除</el-button> </div> </template> </el-table-column>
注意:這里的傳值需要用template標簽將編輯和刪除按鈕包裹,template標簽添加slot-scope="props",在事件函數中可以通過props.row將當前整條信息傳給函數。
②pages/ShopManage/BusinessList/index.vue中書寫 handleDel 方法,利用MessageBox彈框:
handleDel(currentData) { this.$confirm(`此操作將永久刪除<${currentData.shopName}>,是否繼續?`,"提示",{confirmButtonText: "確定",cancelButtonText: "取消",type: "warning"}) .then(() => { /* 這里拿到當前數據currentData,主要是拿到id再向后端發送請求刪除當前數據 */ console.log(currentData); this.$message({ type: "success", message: "刪除成功!" }); }) .catch(() => { this.$message({ type: "info", message: "已取消刪除" }); }); }
### 商家列表-對話框-編輯當前數據
對話框組件ShopDialog默認有個屬性:visible.sync="dialogVisible"控制對話框的顯示和隱藏。
父組件中給子組件ShopDialog傳遞自定義屬性dialogVisible默認為false,點擊編輯按鈕給將dialogVisible改為true,這樣點擊按鈕即可顯示對話框。
關閉對話框:給<el-dialog>標簽設置 :before-close="handleClose" ,該函數中觸發父組件的自定義事件close,並且將false傳遞過去,在父組件中定義close的事件函數,再將dialogVisible的值設置為傳來的false,就可以關閉對話框了。
①components下新建對話框:ShopDialog.vue(粘貼dialog的代碼)
②pages/ShopManage/BusinessList/index.vue中引入並注冊:
import ShopDialog from "@components/ShopDialog/index.vue";
components: { ShopDialog },
③pages/ShopManage/BusinessList/index.vue中渲染時傳入自定義屬性dialogVisible、dialogData:
<ShopDialog :dialogVisible="dialogVisible" :dialogData="dialogData"></ShopDialog>
④自定義屬性在data中的默認值分別是false、{}
⑤給編輯按鈕添加點擊事件:
<el-table-column label="操作" fixed="right" width="150"> <template slot-scope="props"> <div> <el-button size="small" type="primary" @click="handleEdit(props.row)">編輯</el-button> <el-button size="small" type="danger" @click="handleDel(props.row)">刪除</el-button> </div> </template> </el-table-column>
對應的方法:
handleEdit(currentData) { this.dialogData = currentData; // 顯示對話框 this.dialogVisible = true; }
⑥components/ShopDialog.vue中可以通過props拿到dialogVisible和dialogData,但是因為單項數據流,所以這里通過watch將這兩個值分別賦給dialogFlag和dialogInfo,在使用的時候用dialogFlag和dialogInfo:
data() { return { /* 單項數據流:子組件不能更改父組件傳來的值 解決辦法: 用dialogFlag替代dialogVisible 用dialogInfo替代dialogData */ dialogFlag: false, dialogInfo: {} }; }, props: { dialogVisible: { type: Boolean, default: false }, dialogData: { type: Object, default: {} } }, watch: { dialogVisible(newValue, oldValue) { this.dialogFlag = newValue; }, dialogData(newValue, oldValue) { this.dialogInfo = newValue; } }
⑦在關閉對話框的時候會出現不能再打開的bug,解決辦法:
先在<el-dialog>標簽中設置 :before-close="handleClose"
對應的方法:(觸發父組件中的close事件)
methods: { // 關閉之前觸發父組件的自定義事件close,將dialogVisible的值改為此處傳過去的false,這樣當關閉對話框之后還可以重新打開 handleClose() { this.$emit("close", false); } }
然后在父組件中定義自定義事件close:
<ShopDialog :dialogVisible="dialogVisible" :dialogData="dialogData" @close="handleClose"></ShopDialog>
對應的方法:(將dialogVisible屬性再設置為false)
handleClose(flag) { this.dialogVisible = flag; }
在對話框組件中添加一個取消按鈕就直接用點擊事件,事件函數和:before-close一樣:
<el-button @click="handleClose">取消</el-button>
⑧修改時的確認按鈕:
<el-button type="primary" @click="confirm(dialogInfo)">確認</el-button>
對應的方法:
confirm(dialogInfo) { console.log(dialogInfo); /* 成功 */ this.$message({ message: "修改成功", type: "success", onClose:()=>{ this.$emit("close", false); } }); }
### 商家列表-對話框-推薦菜品 tag標簽-動態編輯標簽
①components/ShopDialog.vue中粘貼tag標簽-動態編輯標簽的代碼:
<el-form-item label="推薦菜品:"> <!-- 默認數據 --> <el-tag v-for="(item,index) in dialogInfo.tag" :key="index" closable :disable-transitions="false" @close="handleTagClose(index)" >{{item.text}}</el-tag> <!-- 添加數據 --> <el-input class="input-new-tag" v-if="inputVisible" v-model="inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm" ></el-input> <!-- 新增按鈕 --> <el-button v-else class="button-new-tag" size="small" @click="showInput">添加推薦菜品</el-button> </el-form-item>
②data中定義inputVisible: false,inputValue: ""
③事件函數:
// 刪除tag handleTagClose(i) { this.dialogInfo.tag.splice(i,1); }, // 點擊添加顯示input並聚焦 showInput() { this.inputVisible = true; this.$nextTick(_ => { this.$refs.saveTagInput.$refs.input.focus(); }); }, // 按下回車或者input失焦時觸發 handleInputConfirm() { let inputValue = this.inputValue; if (inputValue) { this.dialogInfo.tag.push({text:inputValue,type:"success"}); } this.inputVisible = false; this.inputValue = ""; }
此時,點擊確認按鈕可以拿到完整的修改過的數據。
### 商家列表-搜索
①el-form下el-form-item下放el-input或者el-search,注意:組件內嵌套需要用到template:
<el-form inline :model="search_model"> <el-form-item label="商家名稱"> <el-input v-model="search_model.shopName" @input="handleShopNameChange"></el-input> </el-form-item> <el-form-item label="菜品推薦"> <!-- 組件內嵌套需要用到template --> <template> <el-select v-model="search_model.shopRecommendVal" placeholder="請選擇" @change="handleShopRecommendChange"> <el-option v-for="item in search_model.shopRecommend" :key="item.text" :label="item.text" :value="item.text" ></el-option> </el-select> </template> </el-form-item> <el-form-item label="銷量"> <template> <el-select v-model="search_model.volumeVal" placeholder="請選擇"> <el-option v-for="(item,index) in search_model.volume" :key="index" :label="item" :value="item" ></el-option> </el-select> </template> </el-form-item> <el-form-item> <el-button>搜索</el-button> </el-form-item> </el-form>
②對應的data數據:
search_model:{ shopName:"", shopReco mmendVal:"", volumeVal:"降序", shopRecommend:[ { text:"水煮魚", type:"success" },{ text:"酸菜魚", type:"info" },{ text:"燉大鵝", type:"danger" },{ text:"紅燒排骨", type:"warning" } ], volume:["升序","降序"] }
③事件函數:
// 菜品推薦change事件 handleShopRecommendChange(value){ // 進行數據請求,后端進行關鍵字查詢,返回查詢結果 console.log(value) }, // 商品名稱input事件 handleShopNameChange(value){ // 進行數據請求,后端進行關鍵字查詢,返回查詢結果 console.log(value) }
### Moment.js
時間戳--->日期格式化
### 用戶列表-userlist
①elementUI中粘貼一段table組件,改啵改啵:
<el-table :data="tableData" style="width: 100%" height="500" border> <el-table-column type="selection" width="55"></el-table-column> <el-table-column fixed prop="id" label="用戶ID" width="150"></el-table-column> <el-table-column prop="username" label="停用/啟用" width="120"> <template> <el-switch v-model="value1" active-text="啟用" inactive-text="停用"></el-switch> </template> </el-table-column> <el-table-column prop="name" label="登錄賬號" width="120"></el-table-column> <el-table-column prop="fullname" label="真實姓名" width="120"></el-table-column> <el-table-column prop="province" label="用戶角色" width="120"></el-table-column> <el-table-column prop="firstTimeDate" label="注冊時間" width="160"></el-table-column> <el-table-column prop="address" label="郵箱地址" width="300"></el-table-column> <el-table-column prop="lastTimeDate" label="最近登錄時間" width="160"></el-table-column> <el-table-column label="操作" width="200" fixed="right"> <template> <div> <el-button size="small">永久刪除</el-button> <el-button size="small">權限設置</el-button> </div> </template> </el-table-column> </el-table>
②data數據支持:(value1是給啟用/停用用的,tableData是table所依賴的數據,userInfo是給后端傳遞的請求參數)
data() { return { value1:true, tableData: [], userInfo: { limit: 10, page: 1 }, total:0 }; }
③mock下新建user.js:(mock數據:模擬后端請求數據,寫完之后在index.js中引入以下:import "./user.js";)
import Mock from "mockjs"; let userData=Mock.mock({ "data|100":[ { "id|+1":100, "status":()=>{ if(Math.random()>0.5){ return true; }else{ return false; } }, "username":"@email()", "fullname":"@cname", "auth":()=>{ let arr=["超級管理員","管理員","普通用戶","部門主管"]; let n=parseInt(Math.random()*4); return arr[n]; }, "firstTimeDate":"@date(yyyy-MM-dd hh:mm:ss)", "email":"@email()", "lastTimeDate":"@date(yyyy-MM-dd hh:mm:ss)" } ] }) /* 用戶列表 */ Mock.mock(/\/usermanage\/userlist/,"get",(options)=>{ let {limit,page}=JSON.parse(options.body); let arr=[]; /* 分頁: 當page為1時,i為0~9 當page為2時,i為10~19 ... */ for(let i=limit*(page-1);i<limit*page;i++){ arr.push(userData.data[i]); } return { dataList:arr, total:userData.data.length }; })
④api/request.js中聲明用戶列表的接口userListApi:
/* 用戶列表 */ export const userListApi = (userInfo) => { return http({ method:"get", url:"/usermanage/userlist", data:userInfo }) }
⑤UserList.vue中引入接口並請求數據(userInfo參數是data中定義的,后面寫分頁只需要切換page的值):
import {userListApi} from "@api/request.js"; methods: { async getUserList(userInfo){ let data=await userListApi(userInfo); console.log(data) this.tableData=data.dataList; } }, created() { this.getUserList(this.userInfo); }
注意:停用/啟用的狀態,去掉el-table-column標簽中的prop屬性,在template中用slot-scope="props"傳值
<el-table-column label="停用/啟用" width="120"> <template slot-scope="props"> <el-switch v-model="props.row.status" active-text="啟用" inactive-text="停用"></el-switch> </template> </el-table-column>
el-table-column標簽里沒有嵌套子組件的時候,這個標簽直接用prop屬性讀取數據
如果有嵌套子組件,就要用template標簽把子組件包裹,template標簽上slot-scope="props"固定寫法,然后子組件中用props.row.屬性 去讀取屬性
### 用戶列表-分頁
①pages/UserManage/UserList.vue中添加分頁器,聲明current-change事件,事件函數不要帶括號:
<el-pagination background layout="prev, pager, next" :total="total" @current-change="handleChange"></el-pagination>
②事件函數:
handleChange(page){ this.userInfo.page=page; this.getUserList(this.userInfo); }
③在getUserList()方法中,將獲取的total的值賦給data中total:
this.total=data.total;
### 用戶列表-啟用/停用的處理
①給當前組件添加change事件:
<el-table-column label="停用/啟用" width="150"> <template slot-scope="props"> <el-switch v-model="props.row.status" active-text="啟用" inactive-text="停用" @change="handleStatusChange(props.row)"></el-switch> </template> </el-table-column>
②事件處理函數:
handleStatusChange(data){ console.log(data) console.log(data.status) // 這里做請求 }
### 用戶列表-全選和非全選
①給<el-table></el-table>組件綁定@selection-change事件:
<el-table :data="tableData" style="width: 100%" height="500" border @selection-change="handleSelectionChange">
②對應的事件函數,每次做點擊都會有個arr表示當前已勾選數據,接下來進行數據請求:
handleSelectionChange(dataList){ // 一般用來做批量刪除 }
### 商品列表-steps步驟條
①pages/ShopManage/BusinessManage/index.vue中引入elementUI中的Steps“居中的步驟條”:
<div class="businessManage"> <el-steps :active="active" align-center> <el-step title="個人基本信息" description="請正確填寫您的基本信息"></el-step> <el-step title="手機號驗證" description="確保用戶的安全請綁定手機號微信號"></el-step> <el-step title="銀行卡綁定" description="收入金額請綁定銀行卡"></el-step> <el-step title="權限驗證" description="操作請進行權限驗證"></el-step> </el-steps> <div> <el-button @click="prev">上一步</el-button> <el-button @click="next">下一步</el-button> <el-button @click="submit">提交</el-button> </div> <keep-alive> <component :is="conName"></component> </keep-alive> </div>
注意:active是當前高亮
②pages/ShopManage/BusinessManage下新建components文件夾,新建One、Two、Three、Four四個組件:
<template> <div> one <el-form :model="oneModel"> <el-form-item> <el-input type="text" v-model="oneModel.inputVal"></el-input> </el-form-item> </el-form> </div> </template> <script> export default { data() { return { oneModel:{ inputVal:"" } } }, } </script>
③pages/ShopManage/BusinessManage/index.vue中引入四個組件並對應的邏輯:
<script> import One from "./components/One.vue"; import Two from "./components/Two.vue"; import Three from "./components/Three.vue"; import Four from "./components/Four.vue"; export default { name: "BusinessManage", data() { return { conName:"One", active:0 } }, components:{One,Two,Three,Four}, methods: { prev(){ if(this.active==0){ this.active=0; }else{ this.active--; } this.handleToggle(); }, next(){ if(this.active==4){ this.active==4; }else{ this.active++; } this.handleToggle(); }, submit(){ }, handleToggle(){ switch(this.active){ case 1: this.conName="One"; break; case 2: this.conName="Two"; break; case 3: this.conName="Three"; break; case 4: this.conName="Four"; break; default: this.conName="One"; } } }, }; </script>