elementUI-day02----elementUI中涉及到組件嵌套的時候如何進行傳值-slot插槽作用域、商家列表(shoplist、table表格固定列和表頭、tag標簽、分頁、對話框-刪除當前數據、對話框-編輯當前數據、對話框-推薦菜品 tag標簽-動態編輯標簽、搜索)、用戶列表(userlist、分頁、全選和非全選、steps步驟條)


### 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>












免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM