• 在组件放使用v-model和slot插槽的简单实用


    封装的组件(SelectDefault.vue文件):

    <template>
        <div class="select-default">
            <label>{{title}}</label>
            <div class="textwarm">
                <input type="text"
                       @click="showPicker"
                       v-model="inputText"
                >
                <span class="iconfont">&#xe60a;</span>
            </div>
            <!--v-model属性用来控制是vant&ndash;&gt; Popup弹出层是否显示-->
            <van-popup v-model="isShow" position="bottom" :overlay="true">
                <van-picker
                        show-toolbar
                        :title="title"
                        :columns="columns"
                        @cancel="onCancel"
                        @confirm="onConfirm"
                />
            </van-popup>
        </div>
    </template>
    
    <script>
        import { Picker,Popup } from 'vant';
        export default {
            name: "SelectDefault",
            components: {
                [Picker.name]:Picker,
                [Popup.name]:Popup
            },
            data() {
                return {
                    // columns: ['杭州', '宁波', '温州', '嘉兴', '湖州'],
                    isShow: false,
                    //设置输入框默认值
                    inputText: this.dataArr[0].name
                }
            },
            props: {
                value: {
                    type: String, //属性的类型
                    // required: false, //// true 必须传 false 不是必须传递的
                    default: '1'// 默认值
                },
                title: {
                    type: String
                },
                //选择器展示的数据
                dataArr: {
                    type: Array,
                    required: true
                }
            },
            //转换为选择器想要的columns数据格式
            computed: {
                columns: function () {
                    let listArr = [];
                    this.dataArr.forEach((item, index)=>{
                        // console.log(item, index);
                        listArr.push(item.name);
                    });
                    // console.log(listArr);
                    return listArr;
                }
            },
            methods: {
                //显示选择器
                showPicker(){
                    this.isShow = true;
                },
                //选择器确定
                onConfirm(value, index) {
                    console.log(`当前值:${value}, 当前索引:${index}`);
                    //隐藏选择器
                    this.isShow = false;
                    //改变输入框的值
                    this.inputText = value;
                    //传给使用此组件上的v-model
                    let userID = this.dataArr[index].user_id.toString();
                    this.$emit('input', userID);
                },
                //选择器取消
                onCancel() {
                    console.log('取消');
                    this.isShow = false;
                }
            },
            created(){
                //设置默认值
                let userID = this.dataArr[0].user_id.toString();
                this.$emit('input', userID);
            }
        }
    </script>
    
    <style scoped lang="stylus">
        .select-default
            display:flex;
            justify-content:space-around;
            align-items: center;
            padding:15px 0;
            >.textwarm
                position: relative;
                span
                    position: absolute;
                    top:50%;
                    right:19px;
                    font-size:12PX;
                    color:#d8d8d8;
                    transform: translateY(-50%);
            label
                150px;
                font-size:28px;
                color:rgba(26,26,26,1);
                line-height:40px;
                font-weight:400;
            input
                514px;
                padding: 24px 22px;
                font-size:30px;
                color:rgba(26,26,26,1);
                font-weight:400;
                border-radius:10px;
                border:1PX solid rgba(204,204,204,1);
                box-sizing: border-box;
            .picker
                position fixed
                left 0
                bottom 0
                width 100vw
                background-color: red
                z-index 222
    </style>

    在其他.vue文件中使用:

    <template>
        <div class="add-admin-user">
            <p class="p-row1">
                <span>用户名</span>
                <span>{{userName}}</span>
            </p>
            <p class="p-row2">
                <inputs v-model="name"><label slot="label-name">真实姓名</label></inputs>
            </p>
            <p class="p-row3">
                <span>所属部门:</span>
                <span>
                    <select v-model="department">
                          <option v-for="item, index in departmentArr" :value ="item.id">{{ item.name }}</option>
                    </select>
                </span>
            </p>
            <p class="p-row4">
                <span>职位:</span>
                <span>
                    <select v-model="role">
                          <option v-for="item, index in roleArr" :value ="item.id" >{{ item.role_name }}</option>
                    </select>
                </span>
            </p>
            <p class="p-row5">
                <inputs v-model="mobile"><label slot="label-name">联系手机号</label></inputs>
            </p>
            <p class="p-row6">
                <inputs v-model="wechat"><label slot="label-name">微信</label></inputs>
            </p>
            <p class="p-row7">
                <inputs v-model="email"><label slot="label-name">邮箱</label></inputs>
            </p>
    
    <<--本例演示关键代码-->>
            <p class="test">
                <SelectDefault v-model="test" title="所属部门" :data-arr="departmentArr"></SelectDefault>
            </p>
    
    <<--本例演示关键代码END-->>
    
            <div class="btn-group">
                <span class="cancel-btn" @click="handleCancel">取消</span>
                <span class="confirm-btn" @click="handleConfirm">确定</span>
            </div>
    
        </div>
    </template>
    
    <script>
        import Api from "@/api/modules/adminUser"
        import Input from "../components/basic/Input.vue"
       
    /*<<--本例演示关键代码-->>*/
    
        import SelectDefault from "../components/basic/SelectDefault"
    
    /*<<--本例演示关键代码END-->>*/
    
        export default {
            name: "AddAdminUser",
            components:{
                inputs:Input,
                selects:Select,
                SelectDefault:SelectDefault ///*<<--本例演示关键代码-->>*/
            },
            data(){
                return{
                    userName: "",
                   // /*<<--本例演示关键代码-->>*/
                    departmentArr: [
                            {user_id: 1, name: "老板"},
                            {user_id: 2, name: "秘书"},
                            {user_id: 3, name: "老板娘"},
                            {user_id: 4, name: "会计"},
                            {user_id: 5, name: "模特"}
                         ],
                    // departmentArr: [],
       
                   /*<<--本例演示关键代码END-->>*/
    
    
                    roleArr: [],
                    //以下用户输入信息
                    name: "",
                    department: "1",
                    role: "1" ,
                    mobile: "",
                    wechat: "",
                    email: "",
                    test: ""
                }
            },
            watch: {
                test: function (val, oldVal) {
                  console.log(val);
              }
            },
            methods: {
                //初始化页面数据
                initView(){
                    Api.getUserName().then((res)=>{
                        // console.log(res);
                        this.userName = res.data.user_name;
                    });
                    Api.departmentListAll().then((res)=>{
                         // console.log(res);
                        this.departmentArr = res.data.list;
                    });
                    Api.roleListAll().then((res)=>{
                        // console.log(res);
                        this.roleArr = res.data;
                    })
                },
    
                //确定
                handleConfirm(){
                    //验证表单
                    let self = this;
                    if(!/^1(3|4|5|7|8)d{9}$/.test(self.mobile)){
                        console.log('手机号格式不正确');
                        return;
                    }
                    if(!/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/.test(self.email)){
                        console.log('Email格式不正确');
                        return;
                    }
                    // 发送请求
                    let param =  {
                        username: this.userName.toString(),
                        name: this.name,
                        department_id: this.department,
                        role_id: this.role,
                        contact_mobile: this.mobile,
                        wechat: this.wechat,
                        email: this.email,
                    };
                    console.log(param);
                    Api.addAdminUser(param).then((res)=>{
                        console.log(res);
                        // alert(res.msg);
                    });
                },
                // 取消
                handleCancel(){
                    console.log(22);
                    this.$router.go(-1);
                }
    
            },
            created(){
                // this.initView();
            }
    
        }
    </script>
    
    <style scoped lang="stylus">
        p,div
            box-sizing border-box
        .add-admin-user
            font-family:PingFangSC-Regular;
            width 100vw
            height 100vh
            position relative
            font-size 32px
            text-align center
            p
                padding 0 30px
                height 90px
                .self-input label
                    text-align left
            .p-row1
                display flex
                span
                    line-height 90px
                span:nth-child(1)
                    font-size:28px;
                    font-weight:400;
                    color:rgba(26,26,26,1);
                    width 181px
                    text-align left
                    text-indent 5px
                span:nth-child(2)
                    font-size:30px;
                    font-weight:400;
                    color:rgba(153,153,153,1);
                    flex 1
                    text-align left
        select
            width 300px
        .btn-group
            position absolute
            display flex
            left 0
            bottom 0
            height 80px
            width 100%
            background-color gray
            span
                flex 1
    </style>    

    上面实例的效果:

    再附上一个solt插槽的简单实用。v-model在组件上使用时,子组件要写的代码。通过@$emit(input,"要传给v-model的值");给组件上的v-model

  • 相关阅读:
    多线程02
    多线程01
    CSS
    Mybatis CRUD中万能Map的用法及优势
    Tomcat配置
    Node.js+Vue+Webpack
    Java的几种常见排序算法
    maven插件 mybatis逆向工程
    ssm依赖
    mybatis spring整合依赖配置
  • 原文地址:https://www.cnblogs.com/taohuaya/p/10306808.html
Copyright © 2020-2023  润新知