vue2.0组件的prop验证中的Function类型怎么使用(向子组件传递函数对象的正确方法)?

2017.08.15 11:37更新:
应@惊尘落羽要求写了一个demo放在了github上,关于vue有很多的地方都需要学习,过程中也发现了自己在原生函数的很多不足,接下来会继续学习。

2017.08.11 16:11更新:
虽然不想再编辑题目但应回答者要求添加一张图片吧,虽然官方文档中prop验证包含的Function,但是写的时候直接return一个匿名函数还是报 undefined 的错误,下附截图。
2017.08.10 14:05更新:
想一想其实promise只是解决回调,我这里完全没有必要用这个方式,根据答案指点在组件中写上确定取消函数,如果传递则使用传递函数,不传递使用默认函数。

2017.09.09 16:42更新:

  1. 回答中有提到$emit来做这个事,想了一下还是不能用这种方法,原因在于这样的话需要在父组件methods中添加方法,但是我预期的效果是尽量不在父组件中做任何改变,现在已经使用了父组件中的data,不希望再占用methods中的方法;
  2. dialogDics 这个对象名是没有问题的,挂载到父组件上的标签名是使用 连接的。

  1. 今天准备自己写一个模态对话组件,设想的是点击确定取消函数都由父组件传递,其他的都已经完成差不多了,目前遇到的问题是在子组件中确定取消上的click事件无法在子组件中设置默认函数,必须在页面初始化传递函数,否则页面会报错(父组件中的enterback注释掉就报错):

clipboard.png

看官方文档在prop验证里面是有Function这个类型的,自己写了但是无效,求解正确方式,或者关于这方面的文章也可以,百度没有找到关于验证函数类型的。

clipboard.png
新增报错截图:

clipboard.png

代码截图:
一. 父组件:

clipboard.png

clipboard.png

二. 子组件:

clipboard.png

clipboard.png

阅读 19.2k
5 个回答

不支持默认function的啊?不清楚


不过这个解决也简单

@click='method'

method(){
  props的fn ? props的fn   : 本组件的fn
}

你传值 :dialogDics="dislogDics", prop接收的应该是 dialog-dics

传事件方法用$emit.
vm.$emit( event, […args] )
参数:
{string} event
[...args]
触发当前实例上的事件。附加参数都会传给监听器回调。

这个问题暂时就先关闭吧,目前有三种方法来实现目的:

  1. 使用当前贴图的方法。缺点是父组件初始化时必须先传递一个默认函数,否则会报错,而且父组件要先定义好很多东西,不太便利。
  2. 使用 $emit 。缺点是父组件要先定义一个函数挂载到组件上,当页面多个模态不同的回调时不灵活。
  3. 当前框架最常用的:promise。缺点是当相同的模态在不同位置被使用是需要写多次。

还是跟着框架来走吧:使用promise来处理确定和取消,这种方式也是最好接入的方法,虽然需要多次书写但是不需要修改父组件。

在此感谢各位的回答,谢谢!

首先说明,下边的回答是不正确的,我也是最近开始看 vue,都是根据文档来的,然后在讨论的过程中发现了问题,可以确认的是 vue props 设置的默认值和类型检查之类的只检测第一层,而里层的内容是不检测的,具体可以看这里
如下所示,只能检测传过来的 propC propC 的类型和默认值,而不会检测 propD 的属性 Da、Db 的值

Vue.component('example', {
  props: {
    propC: {
      type: String,
      required: true
    },
    // 上边的是可以的,而下边的是不可以的
    propD: {
       Da:{
          type: Number,
          default: 100
       },
       Db:{
          type: String,
          default: ''
       }
     }
  }
})

-----以下是原答案-----
先抄一段文档:

Vue.component('example', {
  props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    propA: Number,
    // 多种类型
    propB: [String, Number],
    // 必传且是字符串
    propC: {
      type: String,
      required: true
    },
    // 数字,有默认值
    propD: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }
})

所以可以用自定义验证函数,另外我查了下是支持Function的:

type 可以是下面原生构造器: String Number Boolean Function Object Array Symbol
type 也可以是一个自定义构造器函数,使用 instanceof 检测。
当 prop 验证失败,Vue 会在抛出警告 (如果使用的是开发版本)。注意 props 会在组件实例创建之前进行校验,所以在 default 或 validator 函数里,诸如 data、computed 或 methods 等实例属性还无法使用。

所以你的问题在于default的定义,从propE里的示例就可以看出来,如果 default 的值是 function 类型,那么是取其返回值的,你的报错显示的也很清楚,click 的函数是undefined,就是因为没有返回值的原因,所以 default 写法如下:
经过看源代码,发现下边这两种写法是错误的,特别强调一下,下边是错误的。Type 是 Function 的时候不用再用 function 包一层,源码在这里

enterback:{
    type: Function,
    default(){
        return ()=>{console.log('enterback')}
    }
}
//es5 写法
enterback:{
    type: Function,
    default: function () {
        return function () {
            console.log('enterback')
        }
    }
}

ps: 我没有跑过代码,根据文档猜的,应该可以,详见 文档

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题