Vue声明类型的Prop属性传入null不能应用默认值的问题?

问题描述

最近在写基础组件,同事一直反馈说组件总是提示警告:
[Vue warn]: Invalid prop: type check failed for prop "value". Expected String, Array, got Null

问题出现的环境背景及自己尝试过哪些方法

一开始以为是接收的问题,把定义的 props 加上了工厂函数后没有报异常就没再管了。

今天再去看的时候发现还是有报错,检查了一下组件代码没发现问题,在查看业务代码的时候发现同事喜欢给声明的变量默认赋值为 null,而不是声明正确的基础类型。

相关代码

父级组件:

<template>
  <el-form ref="elForm" :model="formData" :rules="formRules">
    ...
    <el-form-item label="类型">
      <DictSelect v-model="formData.type" dict-category="formData.category"
 />
    </el-form-item>
  </el-form>
</template>
import DictSelect from '@comp/DictSelect'

export default {
  name: "XXX",
  components: { DictSelect },
  data(){
    return {
      formData:{
         // ...
         category: null,
         type: null
      },
      formRules:{ 
        // ...
      }
    }
  }
}

子组件

<template>
  <el-select
    v-model="selectKeys"
    v-bind="$attrs"
    :remote-method="debounceRemoteMethod"
    :loading="loading"
    remote
    filterable
    reserve-keyword
    @change="onChange"
  >
    <el-option
      v-for="(dict,index) in options"
      :key="dict.id"
      :label="dict.label"
      :value="dict.value"
    />
  </el-select>
</template>
<script>
import debounce from 'lodash.debounce'
import { remoteSearchDict  } from '@api/system/dict'

export default {
  name: 'DictSelect',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: {
      type: [String, Array],
      default: () => ''
      // required: true,
    },
    dictCategory: {
      type: [String, Number],
      default: '',
      required: true,
    }
    ...
  },
  data() {
    return {
      selectKeys: [],
      options: [],
      loading: false
    }
  },
  methods: {
    ...
  }
}

你期待的结果是什么?实际看到的错误信息又是什么?

如果自定义组件的 formData.category 被默认设置为 null 了,应该怎么避免出现 [Vue warn]: Invalid prop: type check failed for prop "value". Expected String, Array, got Null 这个报错信息。


本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
阅读 6.1k
1 个回答

虽然 Vue 官方提供的文档中明确提到了:

nullundefined 会通过任何类型验证。

但是实际上如果你给 props 属性声明了必填(required) 的话,那么 null 将无法通过类型验证。

尤大也在相关的Issue里面说明了这个情况:

This is because your prop doesn’t have required: true. For optional props, null will bypass the type check.

所以要解决这个问题,只要把 required 声明去掉就可以了。但是如果我确实需要这个属性必填呢,那么就没办法了需要你在父级声明合法默认值或者直接不声明。
因为在没有声明具体属性的时会传入的时 undefined,而 undefined 是会使用预设的默认值的。

按照尤大的原话的话是,需要去了解一下 nullundefined 的区别。

null indicates the value is explicitly marked as not present and it should remain null.
undefined indicates the value is not present and a default value should be used if available.
required: true indicates neither null or undefined are allowed (unless a default is used)

源码层面也可以看到 value === undefined 时才会去获取声明的默认值。

所以其实这个提示为了提醒可能你绑定的变量并不一定存在。

本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题