zoukankan      html  css  js  c++  java
  • 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=" 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=" 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>











  • 相关阅读:
    与众不同 windows phone (50)
    与众不同 windows phone (49)
    重新想象 Windows 8.1 Store Apps (93)
    重新想象 Windows 8.1 Store Apps 系列文章索引
    重新想象 Windows 8.1 Store Apps (92)
    重新想象 Windows 8.1 Store Apps (91)
    重新想象 Windows 8.1 Store Apps (90)
    重新想象 Windows 8.1 Store Apps (89)
    重新想象 Windows 8.1 Store Apps (88)
    重新想象 Windows 8.1 Store Apps (87)
  • 原文地址:https://www.cnblogs.com/wuqilang/p/12593268.html
Copyright © 2011-2022 走看看