自定義事件
除了系統自帶的原生 DOM 自帶的事件以外,有時候咱們須要用到這些自帶的事件以外,咱們就必需要自定義事件了。vue
事件名
不一樣於組件和 prop,事件名不存在任何自動化的大小寫轉換。而是觸發的事件名須要徹底匹配監聽這個事件所用的名稱。舉個例子,若是觸發一個 camelCase 名字的事件,咱們仍是接着昨天的項目繼續往下寫,在 TestCom.vue
使用 button
按鈕點擊事件分發一個 click-event
事件,不一樣於組件和 prop,事件名不會被用做一個 JavaScript 變量名或 property 名,因此就沒有理由使用 camelCase 或 PascalCase 了。而且 v-on
事件監聽器在 DOM 模板中會被自動轉換爲全小寫 (由於 HTML 是大小寫不敏感的),因此 @myEvent
將會變成 @myevent
——致使 myEvent
不可能被監聽到。web
<template>
<div class="test-com-wrap">
{{ title }}
<button @click="click">按鈕</button>
</div>
</template>
<script>
export default {
name: "TestCom",
props: {
title: {
type: String,
default: "",
},
},
created() {
console.log(this.$attrs)
},
methods: {
click(e) {
this.$emit('click-event', e)
}
}
};
</script>
而後咱們在 TemplateM.vue
來接收這個事件:數組
<template>
<div class="template-m-wrap">
<test-com
title="這個是組件"
data-status="active"
@click-event="clickEvent"
></test-com>
</div>
</template>
<script>
import TestCom from "./TestCom";
export default {
name: "TemplateM",
components: {
TestCom,
},
data() {
return {};
},
methods: {
clickEvent(e) {
console.log("e===>", e.target)
}
},
};
</script>
查看瀏覽效果:微信
定義自定義事件
繼續上面的代碼,能夠經過 emits
選項在組件上定義已經發出的事件:併發
<template>
<div class="test-com-wrap">
{{ title }}
<button @click="click">按鈕</button>
</div>
</template>
<script>
export default {
name: "TestCom",
props: {
title: {
type: String,
default: "",
},
},
emits: ['click-event'],
created() {
console.log(this.$attrs)
},
methods: {
click(e) {
this.$emit('click-event', e)
}
}
};
</script>
驗證拋出的事件
與 prop 類型驗證相似,若是使用對象語法而不是數組語法定義發出的事件,則能夠驗證它。app
要添加驗證,將爲事件分配一個函數,該函數接收傳遞給 $emit
調用的參數,並返回一個布爾值以指示事件是否有效,在 main.js
寫下以下代碼:編輯器
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import App from './App.vue'
import router from './router'
import store from './store'
let app = createApp(App)
app.use(store).use(router).mount('#app')
app.component('custom-form', {
template: `<div>
<input v-model="email" type="text" placeholder="輸入郵箱"/>
<input v-model="password" type="password" placeholder="輸入密碼"/>
<button @click="submitForm({email, password})">提交</button>
</div>`,
data() {
return {
email: '',
password: ''
}
},
emits: {
// 沒有驗證
click: null,
// 驗證submit 事件
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Invalid submit event payload!')
return false
}
}
},
methods: {
submitForm() {
this.$emit('submit', { email: this.email, password: this.password })
}
}
})
在 TemplateM.vue
寫下代碼:函數
<template>
<div class="template-m-wrap">
<custom-form @submit="submit"></custom-form>
</div>
</template>
<script>
export default {
name: "TemplateM",
components: {
},
data() {
return {};
},
methods: {
submit(options) {
console.log(options)
}
},
};
</script>
咱們查看效果以下:flex
v-model
參數
在本例中,子組件將須要一個 foo
prop 併發出 update:foo
要同步的事件,仍是在 main.js
:this
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import App from './App.vue'
import router from './router'
import store from './store'
let app = createApp(App)
app.use(store).use(router).mount('#app')
app.component('my-component', {
props: {
foo: String
},
template: `
<input
type="text"
:value="foo"
@input="$emit('update:foo', $event.target.value)">
`
})
默認狀況下,組件上的 v-model
使用 modelValue
做爲 prop 和 update:modelValue
做爲事件。咱們能夠經過向 v-model
傳遞參數來修改這些名稱:
<template>
<div class="template-m-wrap">
<my-component v-model:foo="bar"></my-component>
</div>
</template>
<script>
export default {
name: "TemplateM",
components: {
},
data() {
return {
bar: 'dsdsdd'
};
},
methods: {
submit(options) {
console.log(options)
}
},
};
</script>
查看效果以下:
多個 v-model
綁定
經過利用以特定 prop 和事件爲目標的能力,正如咱們以前在 v-model
參數中所學的那樣,咱們如今能夠在單個組件實例上建立多個 v-model 綁定。
每一個 v-model 將同步到不一樣的 prop,而不須要在組件中添加額外的選項:
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import App from './App.vue'
import router from './router'
import store from './store'
let app = createApp(App)
app.use(store).use(router).mount('#app')
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
template: `
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)">
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)">
`
})
在 TemplateM.vue
:
<template>
<div class="template-m-wrap">
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
</div>
</template>
<script>
export default {
name: "TemplateM",
components: {
},
data() {
return {
firstName: 'dsdsdd',
lastName: 'Ken'
};
},
methods: {
submit(options) {
console.log(options)
}
},
};
</script>
效果以下:
本文分享自微信公衆號 - 人生代碼(lijinwen1996329ken)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。