一,组件的分类
我们会把组件分成两个类型,一个是通用型组件,一个是业务型组件。
通用型组件就是各大组件库的组件风格,包括按钮、表单、弹窗等通用功能。业务型组件包含业务的交互逻辑,包括购物车、登录注册等,会和我们不同的业务强绑定。
二,创建一个vue3的组件
🐇defineProps组件间传递数据
以一个按钮组件为例:
//MyButton.vue
<template>
<div class="button-box">
<button class="button-content" :style="bgColor">
{{ buttonName }}
</button>
</div>
</template>
<script setup>
import { defineProps, computed } from "vue";
let props = defineProps({
buttonName: {
type: String,
default: "按钮",
required: true
},
bgColorType: {
type: String,
default: "white"
}
});
const bgObj = {
black: "#00",
white: "#fff",
red: "#f5222d",
orange: "#fa541c",
yellow: "#fadb14",
green: "#73d13d",
blue: "#40a9ff"
};
const bgColor = computed(() => {
return `background-color:${bgObj[props.bgColorType]};`;
});
</script>
<style>
.button-content {
border: 1px solid lightskyblue;
}
</style>
使用时:
<template>
<div class="box"></div>
<MyButton buttonName="桃花依旧笑春风"></MyButton>
</template>
<script setup>
import MyButton from "../components/MyButton.vue";
</script>
<style></style>
实现的效果:
也就是vue2中的props变成了defineProps来创建。创建后,其内的属性可以直接使用。也可以利用返回的对象.属性值的方式使用。如这里的props.buttonName
🐇组件的事件绑定
在 Vue 中,我们使用 emit 来对外传递事件,这样父元素就可以监听MyButton组件内部的变化。在vue2中使用emit来抛出事件。而在vue3中,我们需要先利用defineEmits先注册要抛出的事件数组,返回一个emit对象。然后利用它来抛出事件。
组件中:
<button
class="button-content"
:style="bgColor"
@click="buttonClick(buttonName)"
@mouseover="mouseHover"
>
{{ buttonName }}
</button>
....其他代码
import { defineProps, defineEmits, computed, ref } from "vue";
let emits = defineEmits(["buttonClick", "mouseHover"]); // // 注册要抛出的事件数组,返回emits
function buttonClick(val) {
//点击触发这个事件,于是调用emit,来抛出事件
let name = val === "桃花依旧笑春风" ? "人面不知何去处" : "桃花依旧笑春风";
emits("buttonClick", name);
}
function mouseHover() {
emits("mouseHover");
}
....其他代码
父组件的使用:
<template>
<div class="box"></div>
<MyButton
:buttonName="buttonContent"
:bgColorType="bgtype"
@buttonClick="myButtonClick"
@mouseHover="myBtnHover"
></MyButton>
</template>
<script setup>
import MyButton from "../components/MyButton.vue";
import { ref } from "vue";
let bgtype = ref("white");
let buttonContent = ref("桃花依旧笑春风");
function myButtonClick(val) {
buttonContent.value = val;
}
function myBtnHover() {
bgtype.value = "orange";
setTimeout(() => {
bgtype.value = "white";
}, 1000);
}
</script>
<style></style>
🐇组件间的数据传递v-model
前两点,一个是父组件向子组件传值,另一个是子组件给父组件传值。上文中这种要实现的实际上是数据的双向绑定问题,可以使用v-model来简化。
子组件:
<button
class="button-content"
:style="bgColor"
@click="buttonClick(buttonName)"
@mouseover="mouseHover"
>
{{ buttonName }}
</button>
import { defineProps, defineEmits, computed, ref } from "vue";
let props = defineProps({
buttonName: {
type: String,
default: "按钮"
},
bgColorType: {
type: String,
default: "white"
}
});
let emits = defineEmits(["update:buttonName", "mouseHover"]);
function buttonClick(val) {
let newval = val === "桃花依旧笑春风" ? "人面不知何去处" : "桃花依旧笑春风";
emits("update:buttonName", newval);//依旧是要用emit抛出,只是用v-model,让父组件少了一步定义函数,然后更新数据罢了。
}
父组件:
<template>
<div class="box"></div>
<MyButton
v-model:buttonName="buttonContent"
:bgColorType="bgtype"
@mouseHover="myBtnHover"
></MyButton>
</template>
<script setup>
import MyButton from "../components/MyButton.vue";
import { ref } from "vue";
let bgtype = ref("white");
let buttonContent = ref("桃花依旧笑春风");
// function myButtonClick(val) {
// buttonContent.value = val;
// }//相较而言,只是少了这一步而已
function myBtnHover() {
bgtype.value = "orange";
setTimeout(() => {
bgtype.value = "white";
}, 1000);
}
</script>
<style></style>
🐇插槽
插槽写法和vue2没啥差别,就不说了。