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>











  • 相关阅读:
    不同进程间消息互发
    不同进程间消息互发
    div滤镜结合ajax,实现登录
    网页自适应不同浏览器和分辨率[转]
    DIV样式汇总
    用CSS中的Alpha实现渐变
    JavaScript中的null和undefined
    CSS教程:div垂直居中的N种方法[转]
    浏览器不兼容原因及解决办法
    JavaScript验证时间格式
  • 原文地址:https://www.cnblogs.com/wuqilang/p/12593268.html
Copyright © 2011-2022 走看看