一、组件的 props
props 是组件的自定义属性,组件的使用者可以通过props 把数据传递到子组件内部,供子组件内部进行使用。
props 的作用:父组件通过 props向子组件传递要展示的数据。
子组件接受父组件传递过来的值
<template>
<div>
<p>名言: {{ witticism }}</p>
<p>作者:{{ author }}</p>
</div>
</template>
<script>
export default {
name: "MyProp",
props: ["witticism", "author"], //通过定义props属性 接受传递过来的值
};
</script>
<style lang="less" scoped></style>
父组件传值
//App.vue
<template>
<div>
<h1>App 根组件</h1>
<hr />
//3.使用组件
<my-props
:witticism="info.witticism" //动态绑定 传入一个静态值
:author="'source' + info.author" //动态绑定 传入一个动态赋值
></my-props>
</div>
</template>
<script>
//1.引入组件
import MyProps from "./components/props/props.vue";
export default {
name: "App",
data() {
return {
info: {
witticism: "山前山后各有哀愁,有风无风都不自由",
author: "网络",
},
};
},
components: {
MyProps, //2.注册组件
},
};
</script>
在封装vue组件时,可以把动态的数据项声明为 props 自定义属性。
props 类型: 如果希望每个 prop 都有指定的值类型。可以以对象形式列出 props
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor }
可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。
propC:
{
type: String,
required: true
},
二、自定义事件
在封装组件时,为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件。
- 声明自定义事件
- 触发自定义事件
- 监听自定义事件
自定义组件封装的自定义事件,必须事先在 emits 节点中声明,不同于组件和 props,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。
这里借用两张Pink老师的图:
父向子:
上代码
//子组件
<template>
<div>
<p>count的值是:{{ number }}</p>
</div>
</template>
<script>
export default {
name: "MyCount",
props: ["number"], //通过props 接受父组件传过来的数据 number=父组件的count
};
</script>
<style lang="less" scoped></style>
父组件
App.vue
<template>
<div>
<h1>App 根组件----------{{ count }}</h1>
<button @click="count += 1">+1</button>
<hr />
<!-- 通过v-bind绑定 实现父向子传递数据 -->
<my-count v-bind:number="count"></my-count>
</div>
</template>
<script>
import MyCount from "./Count.vue";
export default {
name: "MyApp",
data() {
return {
count: 0,
};
},
components: {
MyCount,
},
};
</script>
<style lang="less" scoped></style>
子向父
在组件上使用v-model指令, 组件内外数据同步更新
<template>
<div>
<p>count的值是:{{ number }}</p>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: "MyCount",
props: ["number"], //通过props 接受父组件传过来的数据
emits: ["update:number"], //自定义事件名称
methods: {
add(e) {
//触发自定义事件
this.$emit("update:number", this.number + 1);
conslog.log('自定义事件被触发了---触发的值是:', e);
},
},
};
</script>
<style lang="less" scoped></style>
在 emits 节点下声明的自定义事件,可以通过this.$emit
('自定义事件的名称')方法进行触发,在调用this.$emit()
方法触发自定义事件时,可以通过第2个参数为自定义事件传参
父组件
//App.vue
<template>
<div>
<h1>App 根组件----------{{ count }}</h1>
<button @click="count += 1">+1</button>
<hr />
<!-- 通过v-model绑定 实现双向传递数据 -->
<my-count v-model:number="count"></my-count>
</div>
</template>
<script>
import MyCount from "./Count.vue";
export default {
name: "MyApp",
data() {
return {
count: 0,
};
},
components: {
MyCount,
},
};
</script>
<style lang="less" scoped></style>
三、将原生事件绑定到组件
想要在一个组件的根元素上直接监听一个原生事件。(例如自己封装了一个button按钮样式,在父组件中被应用,当按钮触发时需要监听button的原生事件,但实际过程中监听的是当前环境下的事件,会默认为该事件是父组件下面的)。
解决,有三种方法:
- 使用native修饰符
- 使用$emit分发事件
- 使用$listeners 官网不易理解 看下这里
四、.sync 修饰符
sync 修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值。 之所以称为修饰符,其实它是一个语法糖,优化简化了代码的复杂性。