vue3中组件prop和emit的使用

组件是带有自定义名称的可复用实例,prop向下传递,emit向上传递。

prop向下传递,emit向上传递

组件prop

通过组件prop可以实现父组件向子组件传递数据

命名规则

HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用DOM中的模板时,camelCase (驼峰命名法) 的prop名需要使用其等价的kebab-case (短横线分隔命名) 命名。

在JavaScript中使用camelCase

const app = Vue.createApp({})

app.component('blog-post', {
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})

在HTML中使用kebab-case

<blog-post post-title="hello!"></blog-post>

静态动态数据

prop传入一个静态的值:

<blog-post title="这是个静态数据"></blog-post>

通过v-bind或简写:动态赋值:

<!-- 动态赋予一个变量的值 -->
<blog-post :title="post.title"></blog-post>

<!-- 动态赋予一个复杂表达式的值 -->
<blog-post :title="post.title + ' by ' + post.author.name"></blog-post>

类型检查

通常组件prop可以在组件中以简写的形式定义:

props: ['title', 'likes', 'isHot', 'categoryIds', 'author']

也可以对每个组件prop指定值的类型,组件prop的类型可以是下列原生构造函数中的一个,当组件prop验证失败的时候,vue将会产生一个控制台的警告。

nullundefined 值会通过任何类型验证

  • String 字符串
  • Number 数值
  • Boolean 布尔值
  • Array 数组
  • Object 对象
  • Date 日期
  • Function 函数
  • Symbol 唯一值
// blog-post子组件prop定义
props: {
  title: {
    type: String,
    required: true
  },
  likes: {
    type: Number,
    default: 0
  },
  isHot: {
    type: Boolean,
    default: false
  },
  category:  {
    type: String,
    required: true,
    validator(value) {
      return ['frontend', 'backend', 'devops'].includes(value)
    }
  },
  author: {
    type: Object,
    default() {
      return { name: '佚名', country: '未知' }
    }
  },
  commentIds: {
  	type
  }
}

<!-- 父组件调用blog-post -->
<blog-post :title="post.title" :category:="post.category"
  :author="{
    name: 'Xiguapengpeng',
    country: 'China'
  }"
></blog-post>

自定义事件emit

通过自定义事件可以实现子组件向父组件传递数据

<!-- info-modal子组件定义 -->
<template>
   <div id="center" v-if="isOpen">
     <input type="text" :value="inputName"/>
     <input type="text" :value="age"/>
     <button @click="closeModal">关闭模态框</button>
   </div>
</template>
export default defineComponent({
	name: 'info-modal',
    data: function () {
      return {
        isOpen: false
      }
    },
    props: {
        inputName: {
          type: String,
          required: true
        },
        age: {
          type: Number,
          required: true
        }
    },
    emits: ['close', 'update:inputName', 'update:age'],
    setup(props, context) {
        const closeModal = () => {
            context.emit('close', !isOpen)
            context.emit('update:inputName', props.inputName)
            context.emit('update:age', props.age)
        }
        return {
            closeModal
        }
    }
})

<!-- 父组件调用info-modal -->
<template>
    <!-- v-model的作用是父子组件变量双向绑定 -->
    <!-- v-model可以创建多个绑定 -->
	<info-modal v-model:input-name="username" v-model:age="age" @close="closeClick"></info-modal>
</template>
export default defineComponent({
	components: {
        InfoModal
    },
    data () {
      return {
        username: "xiguapengpeng",
        age: 18
      }
    },
    setup(props, context) {
        const closeClick = () => {
          alert('i am closed')
        }
        return {
            closeClick
        }
    }
})

v-model绑定

子组件可以进行事件通知以外,还可以使用v-model形成父子组件双向绑定来更新数据,例子参照上面代码

Logo

前往低代码交流专区

更多推荐