向组件添加自定义事件

已完成

接下来,通过添加一个窗体来完成应用程序的构建。 该窗体有一个供用户选择客舱的下拉列表,还有一个用于预订巡航的按钮。 你会将此窗体设置为新组件,并为该按钮创建一个事件。 最后,通过从 Host.vue 调用此新组件。

创建组件

首先创建组件。

  1. 在 Visual Studio Code 中,在 src/components 中创建一个名为 BookingForm.vue 的文件。

  2. 在 BookingForm.vue 中键入 vue,然后从代码片段菜单中选择“<vue> with default.vue”。

    Screenshot of the snippets menu with the snippet selected.

    该代码片段将创建默认结构。

为组件添加代码

现在,我们来添加组件将使用的代码,包括用于注册属性、发射、数据和方法的代码。

  1. 打开 src/components/BookingForm.vue(如果它尚未打开的话)。

  2. export default 的大括号 ({ }) 内,添加以下代码来配置组件:

    props: {
        cabins: Array,
    },
    emits: ['bookingCreated'],
    data() {
        return {
            cabinIndex: -1
        }
    },
    methods: {
        bookCabin() {
            if(this.cabinIndex < 0) return;
            this.$emit('bookingCreated', this.cabinIndex);
            this.cabinIndex = -1;
        },
    }
    

    此代码首先创建一个用于显示可用客舱的列表的 cabins 属性。 我们使用 emits 公开一个名为 bookingCreated 的事件。 再创建一个名为 cabinIndex 的数据项来存储选定的客舱索引。

    最后,创建一个名为 bookCabin 的方法。 此方法将检查 cabinIndex 的值,并且仅当该值为 0 或更大值(表示用户选择了客舱)时才运行。 如果此验证通过,我们发射返回选定的 cabinIndex 的事件,然后将 cabinIndex 重置为 -1。

添加显示模板

添加代码后,可以将注意力转移到显示方面。 我们希望有一个用于选择客舱的下拉列表,以及一个用于预订该旅行的按钮。 该按钮将调用你之前创建的 bookCabin 函数。

  1. 打开 src/components/BookingForm.vue(如果它尚未打开的话)。

  2. <template> 标记内添加以下代码创建显示内容:

    <section>
    <h2>Book now!</h2>
    <form>
        <div class="row">
            <label for="cruise-cabin">Select class:</label>
            <select id="cruise-cabin" v-model="cabinIndex">
                <option disabled value="-1">Select a cabin</option>
                <option v-for="(cabin, index) in cabins" :value="index" :key="index">
                    {{ cabin.name }} $ {{ cabin.price.toLocaleString('en-US') }}
                </option>
            </select>
        </div>
        <div class="row">
            <button class="button" type="button" @click="bookCabin">Book now!</button>
        </div>
    </form>
    </section>
    

    该 HTML 创建窗体。 我们使用 v-for 创建下拉列表,从而循环访问 cabins 属性。 将 select 标记模型绑定到 cabinIndex,用户选择客舱并选择该按钮时,会返回该模型。 然后,将按钮设置为在被选定时调用 bookCabin

将 BookingForm 添加到页面

完成后,将新创建的 BookingForm 添加到应用程序,方法是将其添加到 Host.vue。

  1. 打开 src/components/Host.vue。

  2. TODO: Register next component 注释后添加以下代码以导入 BookingForm

    import BookingForm from './BookingForm.vue';
    
  3. 通过在 TODO: Add next component 注释后添加以下代码,将 BookingForm 添加到可用组件列表中:

    BookingForm
    
  4. 通过在 TODO: Add methods 注释后添加以下代码来添加用于处理 bookingCreated 自定义事件的方法:

    methods: {
        addBooking(cabinIndex) {
            const cabin = this.cruise.cabins[cabinIndex];
            const booking = {
                cabin: cabin.name,
                price: cabin.price
            }
            this.bookings.push(booking);
        }
    }
    

    addBooking 函数使用索引检索选定的客舱。 然后,该函数使用 cabin.namecabin.price 新建一个 booking 对象。 接下来,将 booking 添加到 bookings 数组中。

  5. 使用 booking-form 组件,使用方法为在 TODO: Add booking-form 注释后添加以下代码:

    <booking-form @booking-created="addBooking" :cabins="cruise.cabins"></booking-form>
    

    我们将 addBooking 函数连接到 booking-created 事件,并传递要显示的客舱列表。

显示客舱类型

让我们修改模板来显示预订信息。 我们将显示每个预订的客舱类型,而不是我们在上一练习中显示的“示例”预订消息。

  1. 打开 src/components/BookingList.vue。

  2. <template> 元素中,将 div 中的字段名称从 booking.name 更改为 booking.cabin

    <div class="row" v-for="(booking, index) in bookings" :key="index">
        <div>{{ booking.cabin }} </div>
    </div>
    

测试页面

所有代码都已添加,现在来测试页面!

  1. 选择“文件”>“全部保存”,以保存所有文件。

  2. 转到 http://localhost:8080 并刷新页面。

  3. 从下拉列表中选择一个客舱,然后选择按钮。

    将显示新预订。

    Screenshot of the final application with the form shown on the left and list on the right.

你现已创建并调用了包含自定义事件的组件!