目录

一、问题

二、问题详细描述

 三、解决方法

四、总结


一、问题

1.突然发现给options赋值了,但是下拉框没有数据,就很奇怪。

二、问题详细描述

1.直接用假数据(手动添加的数据)赋值给options,下拉框中的数据正常显示。

  1)代码如下:

<template>
    <template v-for="(contentItem, contentKey) of content">
      <el-select
        v-model="contentItem.value"
        :key="contentKey"
        placeholder="请选择人员"
      >
        <el-option
          v-for="(item, itemKey) of contentItem.options"
          :key="itemKey"
          :value="item[contentItem.matchKey]"
          :lable="item[contentItem.matchKey]"
        >
          <span>{{ item[contentItem.matchKey] }}</span>
          <span>{{ item[contentItem.lable] }}</span>
        </el-option>
      </el-select>
    </template>
</template>
<script>
export default {
  data() {
    return {
      //下拉框数据
      content: {
        person: {
          value: "",
          matchKey: "name",
          type: "select",
        },
      },
    },
   },
   mounted(){
      this.initData();
      this.content.person.value = "奇怪的事情";
   },
   methods:{
   initData(){
       this.getPerson();
    },
    //获取用户
    getPerson() {
      console.log("person---get");
      this.content.person.options = {
        0: {
          name: "小明",
          id: "01",
        },
        1: {
          name: "小华",
          id: "02",
        },
        2: {
          name: "小青",
          id: "1000000000000001",
        },
      };
   }
}
</script>

  2)效果如图1所示

图 1

2.调用接口添加数据

   1)代码如下:

  

<template>
    <template v-for="(contentItem, contentKey) of content">
      <el-select
        v-model="contentItem.value"
        :key="contentKey"
        placeholder="请选择人员"
      >
        <el-option
          v-for="(item, itemKey) of contentItem.options"
          :key="itemKey"
          :value="item[contentItem.matchKey]"
          :lable="item[contentItem.matchKey]"
        >
          <span>{{ item[contentItem.matchKey] }}</span>
          <span>{{ item[contentItem.lable] }}</span>
        </el-option>
      </el-select>
    </template>
</template>
<script>
import { _findPacuDoctorList } from "@/api/implemenceAPI";
export default {
  data() {
    return {
      //下拉框数据
      content: {
        person: {
          value: "",
          matchKey: "name",
          type: "select",
        },
      },
    },
  }
   mounted(){
      this.initData();
      this.content.person.value = "奇怪的事情";
   },
   methods:{
   initData(){
       this.getPerson();
    },
    //获取用户
    getPerson() {
      console.log("person---get");
      let params = {
        data: {
          type: 4,
          name: typeof inputContent === "string" ? inputContent : "",
        },
        size: "100",
        sortBy: "name",
      };
      _findPacuDoctorList(params)
        .then((result) => {
          if (result.status === 200) {
            console.log("result", result);
            this.content.person.options = result.data.content;
          }
        })
        .catch((error) => {
          console.log("error", error);
        });
   }
}
</script>

   2)效果如图2所示:

    调用了接口,并且有数据返回,但是   下拉框中没有数据

图 2

3.百思不得其解呀,明明就是类似的东西,只是一个是直接赋值,一个是调接口赋值而已,怎么会这样呢?

1)更奇葩的是我想复现上述1、2所示的情况时,发现1无法复现---即直接赋值也会 导致图2的效果,下拉框无数据。

a.仔细对比后,发现上述1所示现象的前提条件是 给下拉框数据options赋值前,对该下拉框出现的值 提前赋初始值(如代码1中mounted函数中的:      this.content.person.value = "奇怪的事情";
)

b.若删除代码1中的       this.content.person.value = "奇怪的事情";则会发现下拉框  如图2 所示,下拉框中没有数据

4.更神奇的事情,若 代码1和代码2合并,即先用假数据给options赋值,再用接口获取数据给options赋值。则会导致第一次点击下拉框数据是:假数据,并选中一个选项,如图3所示;之后点击下拉框数据是:调用接口获取的数据,如图4所示。

图 3 第一次点击下拉框并选中一个数据

图 4 之后点击下拉框

 三、解决方法

1.仔细检查才发现,上面的奇葩现象是因为我声明  data时  没有添加 options属性。options属性不是响应式的。

    如  二、问题详细描述 , 4中描述的情况:在mount时已经给 person赋值,data初始化完毕,第一次选择的时候,先用假数据给options赋值,下拉框有了数据,接着异步调用接口给options重新赋值,但因为options是非响应式的,没有更新。选择一个选项,触发点击事件的同时,还触发了 updatePopper事件,更新了下拉框的值.所以之后点击下拉框数据都是 调用接口返回的数据

图 5 执行点击事件后,最后执行了  updatePopper

  data() {
    return {
      //下拉框数据
      content: {
        person: {
          value: "",
          matchKey: "name",
          type: "select",
        },
      },
    },
   },

2.在data中添加 options属性即可: options:[]

  data() {
    return {
      //下拉框数据
      content: {
        person: {
          value: "",
          matchKey: "name",
          type: "select",
          options:[],
        },
      },
    },
   },

 上述所述的奇葩问题都没有了。

  1)直接用假数据赋值,下拉框有值

  2)直接用接口返回值赋值,下拉框有值

  3)先用假数据赋值,再用接口返回值赋值,下拉框有值(接口返回值)

四、总结

1.赋值后下拉框不显示数据,或下拉框数据需要先执行点击操作等才被更新等情况,请仔细检查 options是否在 data中声明过(是否是响应式的)。

2.以上是自己在写代码中踩得坑,之前也有一直看到响应式有关的内容,但并没有真正get到。这次算是认识了一点点。

/*

希望对你有帮助!

如有错误,欢迎指正!非常感谢!

*/

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐