zoukankan      html  css  js  c++  java
  • element-ui中select下拉框,选择后赋值成功,但是框上不显示的坑

    这个是今天遇到一个坑,因为也是第一次使用vue+element-ui开发,所以记录一下自己遇到的一些问题。
    这个问题是在开发省市区三级联动组件的时候遇到的,具体的情况如下发的gif图,虽然解决了问题,但是还是没有懂是为什么这样,有人说是element的bug,不过我觉得不像,可能是用法的问题吧,希望知道原因的博友们可以告知,现在先上下代码;

    1.首先address.json的格式是:

    [
    { "name": "北京", "city":[{"name":"北京", "area":["东城区","西城区","崇文区","宣武区","朝阳区","丰台区","石景山区","海淀区","门头沟区","房山区","通州区","顺义区","昌平区","大兴区","平谷区","怀柔区","密云县","延庆县"]}]},
    
    { "name": "天津", "city":[{"name":"天津", "area":["和平区","河东区","河西区","南开区","河北区","红桥区","塘沽区","汉沽区","大港区","东丽区","西青区","津南区","北辰区","武清区","宝坻区","宁河县","静海县","蓟  县"]}]}
    ]
    

    1.然后就是组件的代码了,功能很简单,也加了一些注释

    <template>
        <div class="ad-box">
            <el-select v-model="province" placeholder="选择省" style=" 150px;">
                <el-option :label="item.name" @click.native="provinceChange(item)" :key="item.name" v-for="item in data" :value="item.name"></el-option>
            </el-select>
            <el-select v-model="city" placeholder="选择市" style=" 150px;">
                <el-option :label="item.name" v-for="item in citylist" @click.native="cityChange(item)" :key="item.name" :value="item.name"></el-option>
            </el-select>
            <el-select v-model="area" placeholder="选择区/乡镇" style=" 150px;">
                <el-option :label="item" @click.native="emitData" v-for="item in arealist" :key="item" :value="item"></el-option>
            </el-select>
        </div>
    </template>
    <script>
        // 获取地址JSON
        import addressJSON from './address.json';
        export default {
            data() {
                return {
                    onecetime: true,
                    province: '',
                    city: '',
                    area: '',
                    data: addressJSON,
                    citylist: [],
                    arealist: [],
                }
            },
            props: {
                address: {
                    type: Object,
                    default: function () {
                        return { 
                            province: '',
                            city: '',
                            area: ''
                        }
                    }
                }
            },
            watch: {
                'address.province': function(val, oldVal) {
                    if (val && this.onecetime) {
                        this.data.map(item => {
                            if (item.name == this.address.province) {
                                this.citylist = item.city;
                                if (this.address.city) {
                                    this.citylist.map(item => {
                                        if (item.name == this.address.city) {
                                            this.arealist = item.area;
                                        }
                                    })
                                }
                                return false;
                            }
                        })
    
                        this.area = this.address.area;
                        this.city = this.address.city;
                        this.province = this.address.province;
    
                        this.onecetime = false;
                    }
                },
            },
            // 通过默认值获取初始的三栏下拉列表
            created() {
                this.area = this.address.area;
                this.city = this.address.city;
                this.province = this.address.province;
            },
            methods: {
                // 选择省份后清空市和区
                provinceChange(item) {
                    this.city = '';
                    this.area = '';
                    this.getList('citylist', item, 'city')
                    this.emitData();   //因为需求是可以不用填写完整的,所以每填一栏上传一次结果
                },
                // 选择市后情况区/县
                cityChange(item) {
                    this.area = '';
                    this.getList('arealist', item, 'area')
                    this.emitData();
                        
                },
                // 联动获取下一栏中的选项列表,参考地址的JSON格式
                getList(prop, data, name) {
                    this[prop] = data[name];
                },
                // 向父级组件发送自定义事件,提交选择结果
                emitData() {
                    let data = {
                        province: this.province,
                        city: this.city,
                        area: this.area
                    };
                    this.$emit('getAddress', data);
                }
            }
        }
    </script>
    <style scoped lang="scss">
        .ad-box {
            display: inline-block;
        }
    </style>
    

    1.组件的使用方式:

    //先注入组件后:
    <address3 @getAddress="changeAddress" :address="{province: '福建', city: '漳州', area: '芗城区'}"></address3>
    

    其实是很简单的一个组件,为什么要写这博客记录呢,其实就是跟标题说的一样,element-ui中的select的赋值问题:

    如果 el-select 上 v-model="" 绑定的这个字段没有事先定义好的话,而且你的option是通过请求到的数组v-for出来的话(如果option是写死的就不会有这个问题),就会出现选择后,select元素上无法展示,但是其实数值已经绑定上去了的后果

    举个例子:
    比如 我有个 用户信息编辑页面, this.info通过请求获取, banklist也是通过请求获取银行列表的

     <el-select v-model="info.bankId" placeholder="选择开户银行">
        <el-option :label="item.bankName" :key="item.bankId" v-for="item in banklist" :value="item.bankId"></el-option>
    </el-select>
    //这时候,就会出现标题上的坑,选择选项后,从vue dev-tools看发现值已经赋进去了,但是select上就是不显示选中的label
    //处理的方法还是 在 data中事先申明一个属性,不要再v-model中绑定不存在的属性就不会出现这种情况,但是现实开发中这样又很麻烦,要多赋值一遍
    

    2017.08.30:
    回复之前的赋值无效的问题,因为之前的方式是从props拿到值后,就直接赋值给对应的属性,但是当props是异步请求回去的,那么他的第一次的值就为我们定义的初始值,没定义就是undefined,等异步亲贵回来之后,它早在第一次的时候,就把初始值赋值过了,请求回来后不再执行赋值了,所以就赋值不了返回后的结果,现已更改为使用watch来监听props的改变,这里有个注意点:props绑定的父级属性不能是返回结果后改变的属性,比如说
    ···
    <address @success="callback" :address="defaultVal">

    //父级methods中
    callback(val) {
        this.defaultVal = val;     //这样是不对的, 因为你再子组件中watch了address相当于是defaultVal,如果你再callback中讲子组件传过来的值又赋值回去给defaultVal,就相当于又触发了watch,
        this.addressVal = val;   //这样才对。
    }
  • 相关阅读:
    CLR via C#深解笔记三
    CLR via C#深解笔记二
    CLR via C#深解笔记一
    C#参考:Linq 概述
    JavaScript
    jQuery
    JavaScript
    云原生
    python模块----optparse模块、argparse模块 (命令行解析模块)
    python模块----pymysql模块 (连接MySQL数据库)
  • 原文地址:https://www.cnblogs.com/milo-wjh/p/7384713.html
Copyright © 2011-2022 走看看