Vue父子组件的静态/动态传值

举报
前端老实人 发表于 2021/12/10 10:04:36 2021/12/10
【摘要】 组件_Prop 注册自定义特性组件默认只是写好结构、样式和行为,使用的数据应由外界传递给组件。如何传递?注册需要接收的prop,将数据作为一个自定义特性传递给组件。如:<div id="app"> <video-item title="羊村摇" poster="https://dev9537bc.jpg@320w_200h.webp" play="638000" ...

组件_Prop

注册自定义特性

组件默认只是写好结构、样式和行为,使用的数据应由外界传递给组件。

如何传递?注册需要接收的prop,将数据作为一个自定义特性传递给组件。

如:

<div id="app">
  <video-item 
    title="羊村摇" 
    poster="https://dev9537bc.jpg@320w_200h.webp" 
    play="638000" 
    rank="1207"
  ></video-item>
</div>
Vue.component('video-item', {
  props: ['title', 'poster', 'play', 'rank'],
})

在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样:

<div id="app">
  <video-item 
    title="羊村摇" 
    poster="https://developerw_200h.webp" 
    play="638000" 
    rank="1207"
  ></video-item>
</div>
Vue.component('video-item', {
  props: ['title', 'poster', 'play', 'rank'],
  template: `<div>{{ title }}</div>`
})

Prop的大小写

HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。故:当 传递的prop为 短横线分隔命名时,组件内 的props 应为 驼峰命名 。 如:

<div id="app">
   <!-- 在 HTML 中是 kebab-case 的 --> 
  <video-item sub-title="hello!"></video-item>
</div>
Vue.component('video-item', {
   // 在 JavaScript 中是 camelCase 的
  props: ['subTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})

要注意的是:如果使用的是字符串模板,那么这个限制就不存在了。

传递静态或动态 Prop

像这样,我们已经知道了可以给 prop 传入一个静态的值:

<video-item title="羊村摇"></video-item>

若想要传递一个动态的值,可以配合v-bind指令进行传递,如:

<video-item :title="title"></video-item>

传递一个对象的所有属性

如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind 。例如,对于一个给定的对象 person:

person: {
  name: 'shanshan',
  age: 18
}

传递全部属性:

<my-component v-bind="person"></my-component>

上述代码等价于:

<my-component
  :name="person.name"
  :age="person.age"
></my-component>

组件_Prop验证

我们可以为组件的 prop 指定验证要求,例如你可以要求一个 prop 的类型为什么。如果说需求没有被满足的话,那么Vue会在浏览器控制台中进行警告,这在开发一个会被别人用到的组件时非常的有帮助。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

Vue.component('my-component', {
  props: {
    title: String,
    likes: Number,
    isPublished: Boolean,
    commentIds: Array,
    author: Object,
    callback: Function,
    contactsPromise: Promise
  }
})

上述代码中,对prop进行了基础的类型检查,类型值可以为下列原生构造函数中的一种:StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数、或上述内容组成的数组。 需要注意的是null 和 undefined 会通过任何类型验证。 除基础类型检查外,我们还可以配置高级选项,对prop进行其他验证,如:类型检测、自定义验证和设置默认值。 如:

Vue.component('my-component', {
  props: {
    title: {
      type: String,  // 检查 prop 是否为给定的类型
      default: '杉杉最美',    // 为该 prop 指定一个默认值,对象或数组的默认值必须从一个工厂函数返回,如:default () { return {a: 1, b: 10} }, 
      required: true,  // 定义该 prop 是否是必填项
      validator (prop) {   // 自定义验证函数,该prop的值回作为唯一的参数代入,若函数返回一个falsy的值,那么就代表验证失败
        return prop.length < 140;
      }
    }
  }
})

为了更好的团队合作,在提交的代码中,prop 的定义应该尽量详细,至少需要指定其类型。

组件_单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

这里有两种常见的试图改变一个 prop 的情形:

这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用,在后续操作中,会将这个值进行改变。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:

props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

最后

如果对您有帮助,希望能给个👍评论收藏三连!

博主为人老实,无偿解答问题哦❤!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。