Vue props in emit out 筆記

props

基本使用

vue可以利用 props 將外部傳入資料到內部,props為單向數據流

可以透過範例了解,建立一個子組件,將預傳入資料放在 props 陣列中,利用v-bind:photo-url傳入或是:photo-url,因在html中沒有區分大小寫駝峰命名需用 - 做連接。

<!-- 靜態引入-->
<photo photo-url="imgUrl"></photo>
<!-- 動態引入-->
<photo :photo-url="imgUrl"></photo>

<script type="module">
const app = Vue.createApp({
// ...
data() {
return {
imgUrl: "https://imgur.com/Lh3gOFn",
};
},
});

app.component("photo", {
props: ["photoUrl"],
template: `<img :src="superUrl" class="img-thumbnail" alt>`,
});
</script>

props 驗證以及預設值

可以設定傳入值的型別,或是預設值,若傳入的資料型別錯誤,在開發模式下會報錯。

export default {
props: {
// `null` 和 `undefined` 值將允許任何類型
propA: Number,
// 多種可能的類型
propB: [String, Number],
// 必需且為字符串
propC: {
type: String,
required: true,
},
// 型別為數字,預設值為100
propD: {
type: Number,
default: 100,
},
// 物件預設值
propE: {
type: Object,
default(rawProps) {
return { message: "hello" };
},
},
// 自定義驗證
propF: {
validator(value) {
// value必須為陣列之一
return ["success", "warning", "danger"].includes(value);
},
},
// 函式預設值
propG: {
type: Function,
// 默認值函式
default() {
return "Default function";
},
},
},
};

emits

基本使用

vue可以透過emits將子組件傳遞出去,

以下範例,子組件透過this.$emit觸發外層addNum事件,並傳入參數與 num 做相加

如在console出現以下錯誤,只需要在emits中聲明發出的事件

[Vue warn]: Extraneous non-emits event listeners (updatedcount) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.global.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<h3>Emits</h3>
{{ num }}
<button-add @add-num="addNum"></button-add>
</div>

<script type="module">
const app = Vue.createApp({
data() {
return {
num: 0,
};
},
methods: {
addNum(num) {
this.num = this.num += parseInt(num);
},
},
});

app.component("button-add", {
data() {
return {
num: 1,
};
},
methods: {
addNum() {
this.$emit("addNum", "1");
},
},
emits: ["addNum"],
template: `
<button type="button" @click="addNum">增加 num 的值</button>`,
});

app.mount("#app");
</script>
</body>
</html>

emits 驗證

將組件改寫,emits陣列變成使用物件定義發出的事件,返回一個boolean用來判斷事件是否有效。

app.component("button-add", {
data() {
return {
num: "1",
};
},
methods: {
addNum() {
this.$emit("addNum", this.num);
},
},
emits: {
addNum: (num) => {
if (typeof num !== "number") {
console.warn("num is not a number");
}
return true;
},
},
template: `
<button type="button" @click="addNum">增加 num 的值</button>`,
});