vue3(五)组件,Props, 事件

148 阅读2分钟

组件全局注册

我们可以使用 Vue 应用实例的 app.component() 方法,让组件在当前 Vue 应用中全局可用。

import { createApp } from 'vue'
import MyComponent from './App.vue'

const app = createApp({})

app.component(
  // 注册的名字
  'MyComponent',
  // 组件的实现
  MyComponent
)

如果使用单文件组件,你可以注册被导入的 .vue 文件:

import MyComponent from './App.vue'

app.component('MyComponent', MyComponent)

组件局部注册

局部注册需要使用 components 选项:

<script>
import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  }
}
</script>

<template>
  <ComponentA />
</template>

Props 组件传值

虽然理论上你也可以在向子组件传递 props 时使用 camelCase 形式 (使用 DOM 模板时例外),但实际上为了和 HTML attribute 对齐,我们通常会将其写为 kebab-case 形式为:greeting-message

<MyComponent greeting-message="hello" />

静态 vs. 动态 Prop

// 静态
<BlogPost title="My journey with Vue" />
// 动态
<BlogPost :title="post.title" />

使用一个对象绑定多个 prop

如果你想要将一个对象的所有属性都当作 props 传入,你可以使用没有参数的 v-bind,即只使用 v-bind 而非 :prop-name。例如,这里有一个 post 对象:

js

export default {
  data() {
    return {
      post: {
        id: 1,
        title: 'My Journey with Vue'
      }
    }
  }
}

以及下面的模板:

template

<BlogPost v-bind="post" />

而这实际上等价于:

template

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

Prop 校验

export default {
  props: {
    // 基础类型检查
    //(给出 `null` 和 `undefined` 值则会跳过任何类型检查)
    propA: Number,
    // 多种可能的类型
    propB: [String, Number],
    // 必传,且为 String 类型
    propC: {
      type: String,
      required: true
    },
    // Number 类型的默认值
    propD: {
      type: Number,
      default: 100
    },
    // 对象类型的默认值
    propE: {
      type: Object,
      // 对象或者数组应当用工厂函数返回。
      // 工厂函数会收到组件所接收的原始 props
      // 作为参数
      default(rawProps) {
        return { message: 'hello' }
      }
    },
    // 自定义类型校验函数
    propF: {
      validator(value) {
        // The value must match one of these strings
        return ['success', 'warning', 'danger'].includes(value)
      }
    },
    // 函数类型的默认值
    propG: {
      type: Function,
      // 不像对象或数组的默认,这不是一个工厂函数。这会是一个用来作为默认值的函数
      default() {
        return 'Default function'
      }
    }
  }
}

运行时类型检查#

校验选项中的 type 可以是下列这些原生构造函数:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

事件的触发与监听

子组件:MyComponent

<!-- MyComponent  -->
<button @click="$emit('increaseBy', 1)">
  Increase by 1
</button>


$emit() 方法在组件实例上也同样以 this.$emit() 的形式可用:

<button @click="submit">click me</button>


export default {
  methods: {
    submit() {
      this.$emit('increaseBy', 1)
    }
  }
}

父组件:


<MyButton @increase-by="increaseCount" />



export default {
  methods: {
    increaseCount(n) {
      this.count += n
    }
  }
}

即: 点击子组件 click me 按钮 触发 父组件传给子组件的 increaseBy 参数,即 increaseCount 事件。父组件 的 count 属性变更