【青训营】深入组件

56 阅读1分钟

这是我参与「第四届青训营 」笔记创作活动的的第9天

  • 深入props
  • 组件事件

深入props

父子组件之间的数据传递,除了直接传入写好的静态数据,还可以通过v-bind:或简写:来进行传递data中的数据变量。以下是不同类型的数据通过v-bind进行数据传递的例子:

props动态数据传递

Number

<!-- 虽然 `42` 是个常量,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :likes="42" />


<!-- 根据一个变量的值动态传入 -->
<BlogPost :likes="post.likes" />

Boolean

<!-- 仅写上 prop 但不传值,会隐式转换为 `true` -->
<BlogPost is-published />

<!-- 虽然 `false` 是静态的值,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :is-published="false" />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :is-published="post.isPublished" />

Array

<!-- 虽然这个数组是个常量,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :comment-ids="[234, 266, 273]" />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :comment-ids="post.commentIds" />

Object

<!-- 虽然这个对象字面量是个常量,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost
  :author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
  }"
 />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :author="post.author" />

<!-- 也可直接传入整个对象,相当于:object.key=object.value -->


<BlogPost v-bind="post" />

<BlogPost :id="post.id" :title="post.title" />

props单向数据流

props数据是单向流动的,对于子组件而言,props是只读的,修改props会让数据流变得混乱,难以理解。 一般有两种情况可能修改数据:

<!--prop 被用于传入初始值;而子组件想在之后将其作为一个局部数据属性**。在这种情况下,最好是新定义一个局部数据属性,从 props 上获取初始值即可-->
export default {
  props: ['initialCounter'],
  data() {
    return {
      // 计数器只是将 this.initialCounter 作为初始值
      // 像下面这样做就使 prop 和后续更新无关了
      counter: this.initialCounter
    }
  }
}

<!--需要对传入的 prop 值做进一步的转换**。在这种情况中,最好是基于该 prop 值定义一个计算属性-->
export default {
  props: ['size'],
  computed: {
    // 该 prop 变更时计算属性也会自动更新
    normalizedSize() {
      return this.size.trim().toLowerCase()
    }
  }
}

Prop 校验

基本结构:

props: {属性名:属性类型}

注意:

  • 所有 prop 默认都是可选的,除非声明了 required: true
  • 除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined
  • Boolean 类型的未传递 prop 将被转换为 false。你应该为它设置一个 default 值来确保行为符合预期。
  • 如果声明了 default 值,那么在 prop 的值被解析为 undefined 时,无论 prop 是未被传递还是显式指明的 undefined,都会改为 default 值。

组件事件

触发自定义事件

父子之间可以通过子组件使用$emit('自定义事件名')来抛出自定义事件,父组件通过@事件名="事件方法"来进行抛出事件的处理 如:

子组件:

<button @click="$emit('someEvent')">click me</button>

父组件:

<MyComponent @some-event="callback" />

如果含有参数:

子组件:@事件名="$emit('自定义事件名',参数1,参数2...)"

父组件可以通过箭头函数或者组件方法来处理