欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3中組件事件和defineEmits示例代碼

 更新時間:2023年10月07日 09:42:43   作者:ps酷教程  
這篇文章主要給大家介紹了關(guān)于vue3中組件事件和defineEmits的相關(guān)資料,組件事件是Vue組件之間進(jìn)行通信的一種方式,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下

1. 事件基礎(chǔ)

  • 子組件有時候需要與父組件進(jìn)行交互,子組件需要通知父組件做一些事(比如:prop是單向數(shù)據(jù)量,子組件不應(yīng)該直接修改prop綁定的值,而是應(yīng)該拋出一個事件來通知父組件做出改變)
  • 為了解決這個問題,組件實例提供了一個自定義事件系統(tǒng),父組件可以通過v-on或 @ 來選擇性地監(jiān)聽子組件上拋的事件,就像監(jiān)聽原生 DOM 事件那樣,當(dāng)監(jiān)聽到子組件上拋出的事件時,就會執(zhí)行對應(yīng)事件綁定的監(jiān)聽函數(shù)
    • 子組件可以通過調(diào)用內(nèi)置的 $emit 方法,通過傳入事件名稱來拋出一個事件
    • 子組件使用內(nèi)置的 $emit 方法中,可以使用 $event作為事件參數(shù)
    • 我們可以通過 emits 選項來聲明需要拋出的事件(emits聲明選項不是必須的)
      • 這聲明了一個組件可能觸發(fā)的所有事件,還可以對事件的參數(shù)進(jìn)行驗證
      • 還可以讓 Vue 避免將它們作為原生事件監(jiān)聽器隱式地應(yīng)用于子組件的根元素。
        • 如果子組件中聲明了emits:[‘click’]選項,然后在某個按鈕下使用了$emit(‘click’)去觸發(fā)click事件,則父組件中使用該子組件時,使用@click=‘handleClick’去監(jiān)聽click事件時,不會認(rèn)為這是原生dom的點擊事件,只有當(dāng)子組件使用$emit(‘click’)觸發(fā)click事件時,才會觸發(fā)hanleClick函數(shù)。如果不加emits:[‘click’]選項,則只要點擊就會觸發(fā)handleClick事件。

示例

Blog.vue

<template>
    <div :style="{ fontSize: postFontSize + 'em' }">
        <BlogPost 
            v-for="post in posts" 
            :key="post.id" 
            :title="post.title"
            @enlarge-text="postFontSize += 0.1"/>
    </div>
</template>
<script >
import BlogPost from './BlogPost.vue'
export default {
    name: 'Blog',
    components: {
        BlogPost
    },
    data() {
        return {
            posts: [
                { id: 1, title: 'My journey with Vue' },
                { id: 2, title: 'Blogging with Vue' },
                { id: 3, title: 'Why Vue is so fun' }
            ],
            postFontSize: 1
        }
    }
}
</script>
<style lang="scss"></style>

BlogPost.vue

<template>
    <div class="blog-post">
        <h4>{{ title }}</h4>
        <button @click="$emit('enlarge-text')">Enlarge text</button>
    </div>
</template>
<script>
export default {
    name: 'BlogPost',
    props: ['title'],
    // 這個emits聲明選項不是必須的
    emits: ['enlarge-text']
}
</script>
<style lang="scss"></style>

2. 觸發(fā)與監(jiān)聽事件

2.1 觸發(fā)事件

在組件的模板表達(dá)式中,可以直接使用 $emit 方法觸發(fā)自定義事件

$emit() 方法在組件實例上也同樣以 this.$emit() 的形式可用:

<templte>
	<button @click="$emit('someEvent')">click me</button>
</template>
<script>
	export default {
	  methods: {
	    submit() {
	      this.$emit('someEvent')
	    }
	  }
	}
</script>

2.2 監(jiān)聽事件

  • 父組件可以通過 v-on (縮寫為 @) 來監(jiān)聽事件
  • 組件的事件監(jiān)聽器也支持 .once 修飾符-  觸發(fā)事件時建議使用camelCase 形式 (駝峰命名,首字母小寫), 父組件監(jiān)聽是可以使用kebab-case 形式 (短橫線分隔,推薦)
  • 組件觸發(fā)的事件沒有冒泡機制,你 只能監(jiān)聽直接子組件觸發(fā)的事件 。
    • 平級組件或是跨越多層嵌套的組件間通信,應(yīng)使用一個 外部的事件總線 
    • 或者使用一個 全局狀態(tài)管理方案 。
<MyComponent @some-event="callback" />
<MyComponent @some-event.once="callback" />

3. 事件參數(shù)

  • 有時候會需要在觸發(fā)事件時附帶一個特定的值(事件參數(shù))
  • 可以寫一個內(nèi)聯(lián)的箭頭函數(shù)作為監(jiān)聽器,此函數(shù)會接收到事件附帶的參數(shù)
  • 也可以用一個組件方法來作為事件處理函數(shù),該方法也會接收到事件所傳遞的參數(shù)
  • 所有傳入 $emit() 的額外參數(shù)都會被直接傳向監(jiān)聽器。
    • 舉例來說,$emit(‘foo’, 1, 2, 3) 觸發(fā)后,監(jiān)聽器函數(shù)將會收到這三個參數(shù)值。

3.1 示例1

Blog.vue

<template>
    {{ count }}
    <BlogPost @increase-by="(n) => count += n" />
    <BlogPost @increase-by="increaseCount" />
</template>
<script >
import BlogPost from './BlogPost.vue'
export default {
    name: 'Blog',
    components: {
        BlogPost
    },
    data() {
        return {
            count: 0
        }
    },
    methods: {
        increaseCount(n,m,e) {
            console.log(n,m,e); // 1, 2, PointerEvent {isTrusted: true, _vts: 1682821628803, pointerId: 1, width: 1, height: 1, …}
            this.count += n
        }
    }
}
</script>
<style lang="scss"></style>

BlogPost.vue

<template>
    <div class="blog-post">
        <button @click="$emit('increaseBy', 1, 2, $event)">
            Increase by 1
        </button>
    </div>
</template>
<script>
export default {
    name: 'BlogPost',
}
</script>
<style lang="scss"></style>

3.2 示例2(defineEmits)

子組件可以觸發(fā)自定義事件,父組件使用該子組件時,可以監(jiān)聽該組件的事件,并為監(jiān)聽的事件綁定事件處理函數(shù), 當(dāng)該子組件觸發(fā)了該事件時,父組件對應(yīng)的事件處理函數(shù)就會執(zhí)行。

MyComponent.vue

<template>
    <!-- 在組件的模板表達(dá)式中,可以直接使用 $emit 方法觸發(fā)自定義事件 -->
    <!-- 可以通過 v-on (縮寫為 @) 來監(jiān)聽事件, 即:@click -->
    <!-- 這里可以使用駝峰命名形式觸發(fā)的事件名稱, 而在父組件中使用短橫線命名形式監(jiān)聽 -->
    <!-- 傳入3個參數(shù), 則在父組件中監(jiān)聽函數(shù)中, 也應(yīng)至少有3個參數(shù), 
         否則按參數(shù)個數(shù)賦值,也可以在這里傳個對象過去,就只需要一個參數(shù)了,
         并且可以使用$event, 將當(dāng)前事件傳過去 -->
    <!-- 參數(shù)也可以使用模板中拿到的參數(shù), 比如v-for循環(huán)里拿到的每一項數(shù)據(jù) -->
    <button v-on:click="$emit('doUpdate',$event,1,2)">觸發(fā)doUpdate事件</button> <br/>
    <button v-on:click="$emit('refresh', {name:'zzhua',age:Math.floor(Math.random() * 20)})">觸發(fā)refresh事件</button>
    子組件中person: {{ person }}<br/>
    <!-- 可以使用事件修飾符, once表示該事件只會觸發(fā)1次 -->
    <button v-on:click.once="handleClick()">觸發(fā)click事件</button>
</template>
<script lang="ts" setup>
    import { ref,reactive,onUpdated } from 'vue'
    /* 1. defineEmits() 宏不能在子函數(shù)中使用。它必須直接放置在 <script setup> 的頂級作用域下 */
    /* 2. 顯式地使用了 setup 函數(shù)而不是 <script setup>,則事件需要通過 emits 選項來定義,emit 函數(shù)也被暴露在 setup() 的上下文對象上 */
    const emit = defineEmits(['doUpdate']) /* 可以不需要定義doUpdate, 但建議定義doUpdate, 以此來聲明此組件可以被觸發(fā)的事件 */
     function handleClick () {
        console.log('click');
        emit('doUpdate',e,3,4) /* 使用emit,手動觸發(fā)doUpdate事件 */
    }
    const props = defineProps(['person'])
    onUpdated(()=>{
        console.log('---組件渲染更新了---') /* 當(dāng)通過觸發(fā)子組件事件, 父組件監(jiān)聽到該組件的該事件, 修改了person的ref值, 從而組件會更新 */
    })
</script>
<style lang="scss">
    button {
        margin: 5px;
    }
</style>

Test.vue

<template>
    <!-- 可以使用短橫線形式監(jiān)聽當(dāng)前這個組件的事件,并指定事件處理函數(shù) -->
    <my-component :person="person" v-on:do-update="handleUpdate" @refresh="handleRefresh" ></my-component><br/>
    父組件中person: {{ person }}
</template>
<script lang="ts" setup>
    import { ref,reactive,computed } from 'vue'
    import MyComponent from './MyComponent.vue';
    const person = ref({ name: 'demoName', age: NaN})
    function handleUpdate(event,payload1,payload2) {
        console.log(event); // PointerEvent {isTrusted: true, _vts: 1678062697219, pointerId: 1, width: 1, height: 1, …}
        console.log(payload1, payload2);
    }
    function handleRefresh( p) {
        console.log(p); // {name: 'zzhua', age: 18}
        person.value = p
    }
</script>
<style lang="scss">
</style>

4. 聲明觸發(fā)的事件

  • 組件可以顯式地通過 emits 選項來聲明它要觸發(fā)的事件
  • 這個 emits 選項還支持對象語法,它允許我們對觸發(fā)事件的參數(shù)進(jìn)行驗證
  • 盡管事件聲明是可選的,我們還是推薦完整地聲明所有要觸發(fā)的事件。同時,事件聲明能讓 Vue 更好地將事件和透傳 attribute 作出區(qū)分,從而避免一些由第三方代碼觸發(fā)的自定義 DOM 事件所導(dǎo)致的邊界情況。
    • 如果一個原生事件的名字 (例如 click) 被定義在 emits 選項中,則監(jiān)聽器只會監(jiān)聽組件觸發(fā)的 click 事件而不會再響應(yīng)原生的 click 事件。

5. 事件校驗

  • 和對 props 添加類型校驗的方式類似,所有觸發(fā)的事件 可以使用字符串 ,也 可以使用對象形式
  • 要為事件添加校驗,那么事件 可以被賦值為一個函數(shù) ,接受的參數(shù)就是拋出事件時傳入 this.$emit 的內(nèi)容, 返回一個布爾值來表明事件是否合法

示例1

Blog.vue

<template>
    {{ count }}
    <BlogPost @submit="handleSubmit" />
</template>
<script >
import BlogPost from './BlogPost.vue'
export default {
    name: 'Blog',
    components: {
        BlogPost
    },
    data() {
        return {
            count: 0
        }
    },
    handleSubmit(payload) {
        console.log(payload);
    }
}
</script>
<style lang="scss"></style>

BlogPost.vue

<template>
    <div class="blog-post">
        <button @click="$emit('submit', {password:'123456'})">
            submit
        </button>
    </div>
</template>
<script>
export default {
    name: 'BlogPost',
    emits: {
        // 沒有校驗
        click: null,
        // 校驗 submit 事件
        submit: ({ email, password }) => {
            if (email && password) {
                return true
            } else {
                console.warn('Invalid submit event payload!')
                return false
            }
        }
    },
    methods: {
        submitForm(email, password) {
            this.$emit('submit', { email, password })
        }
    }
}
</script>
<style lang="scss"></style>

示例2(defineEmits)

MyComponent.vue

<template>
    <button @click="submitForm(123,456)">觸發(fā)submitForm事件</button>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
const emit = defineEmits({
    // 沒有校驗
    click: null,
    // 校驗 submit 事件
    submit: ({ email, password }) => {
        if (email && password) {
            console.log(email, password);
            return true
        } else {
            console.warn('Invalid submit event payload!')
            return false
        }
    }
})
function submitForm(email, password) {
    emit('submit', { email, password })
}
</script>
<style lang="scss">
button {
    margin: 5px;
}
</style>

Test.vue

<template>
    <MyComponent></MyComponent>
</template>
<script lang="ts" setup>
    import { ref,reactive,computed } from 'vue'
    import MyComponent from './MyComponent.vue';
</script>
<style lang="scss">
</style>

總結(jié) 

到此這篇關(guān)于vue3中組件事件和defineEmits的文章就介紹到這了,更多相關(guān)vue3組件事件和defineEmits內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue組件更新數(shù)據(jù)v-model不生效的解決

    Vue組件更新數(shù)據(jù)v-model不生效的解決

    這篇文章主要介紹了Vue組件更新數(shù)據(jù)v-model不生效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue el-table 動態(tài)添加行與刪除行的實現(xiàn)

    vue el-table 動態(tài)添加行與刪除行的實現(xiàn)

    這篇文章主要介紹了vue el-table 動態(tài)添加行與刪除行的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue-cli-service不是內(nèi)部或外部命令,也不是可運行的程序或批處理文件問題

    vue-cli-service不是內(nèi)部或外部命令,也不是可運行的程序或批處理文件問題

    在Vue項目構(gòu)建過程中,如果遇到無法識別'vue-cli-service'命令的錯誤提示,通常是因為沒有全局安裝vue-cli,解決這個問題的步驟主要包括:首先檢查Vue版本,如果未安裝則先安裝Vue;其次全局安裝vue-cli;若在安裝過程中遇到cnpm命令找不到的情況
    2024-10-10
  • Vue實現(xiàn)上拉加載下一頁效果的示例代碼

    Vue實現(xiàn)上拉加載下一頁效果的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Vue實現(xiàn)上拉加載下一頁效果,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Vue有一定幫助,需要的可以參考一下
    2022-08-08
  • Vue中input被賦值后,無法再修改編輯的問題及解決

    Vue中input被賦值后,無法再修改編輯的問題及解決

    這篇文章主要介紹了Vue中input被賦值后,無法再修改編輯的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Element Popover 彈出框的使用示例

    Element Popover 彈出框的使用示例

    這篇文章主要介紹了Element Popover 彈出框的使用示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • vue-cli3 DllPlugin 提取公用庫的方法

    vue-cli3 DllPlugin 提取公用庫的方法

    這篇文章主要介紹了vue-cli3 DllPlugin 提取公用庫 ,需要的朋友可以參考下
    2019-04-04
  • Vue中的事件綁定問題

    Vue中的事件綁定問題

    這篇文章主要介紹了Vue中的事件綁定問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 最新評論