iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
Vue.js

這是我的 Vue.js 筆記,不知道有沒有機會幫到你系列 第 23

我的 Vue.js 筆記(23) - 在元件與元件之間使用 v-model

  • 分享至 

  • xImage
  •  

前言

之前提到,元件如果要接收資料,必須用 props
元件如果要向外傳資料,則是定義 emit 事件

假設我們的元件有個 <input> 標籤,我們希望元件內部的 <input> 可以跟外部的資料做到雙向綁定,那們根據之前提到的寫法,可能會這樣寫:

const app = Vue.createApp({
  setup() {
    const message = Vue.ref("hello");

    const updateMsg = (val) => {
      message = val;
    };

    return {
      message,
      updateMsg,
    };
  },
});

app.component("my-component", {
  // :value 把 prop 綁到 input 的 value
  // 透過 @input 事件把使用者輸入的資料往外傳
  template: `
    <input :value="msg"
    @input="$emit('update', $event.target.value)"
  />
      `,
  props: ["msg"],
  emits: ["update"],
});

app.mount("#app");

並且模板中需要綁定資料(:msg="message"),同時宣告事件(@update="updateMsg"):

<div id="app">
  <my-component :msg="message" @update="updateMsg"></my-component>
  {{ message }}
</div>

提到表單事件,不得不提 v-model 功能。

上面的需求,Vue 可以讓我們用 v-model 來綁定元件。

元件中的 v-model

如果元件只需要處理一個 v-model 資料綁定,元件的 props 請定義成 modelValue,emit 則定義成 update:modelValue

app.component("my-component", {
  template: `
    <input :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
      `,
  props: ["modelValue"],
  emits: ["update:modelValue"],
});

Vue 實體則是寫這個內容,預計要把 message 跟內部表單綁在一起:

const app = Vue.createApp({
  setup() {
    const message = Vue.ref("hello");
    return {
      message,
    };
  },
});

接著在外層使用元件時,就可以直接使用 v-model 把資料傳進去了:

<div id="app">
  <my-component v-model="message"></my-component>
  {{ message }}
</div>

語法看起來很複雜,但概念其實很單純

就是在外部宣告狀態,讓外部的狀態可以跟「元件內部」的表單綁定。

完整的範例可以到這裡看

外部多個狀態,綁定到多個元件表單

剛才的寫法,是元件只有一個表單時,預設使用名稱為 modelValue 的 prop , 與 update:modelValue 的 emit

如果有多個表單需要被綁定外部狀態的話,可以這樣寫

app.component("my-component", {
  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)"
  />
      `,
  props: ["firstName", "lastName"],
  emits: ["update:firstName", "update:lastName"],
});

外層就可以綁定多個狀態了:

<div id="app">
  <h1>{{ first }} {{ last }}</h1>
  <my-component v-model:first-name="first" v-model:last-name="last">
  </my-component>
</div>

記得要宣告綁定的狀態:

const app = Vue.createApp({
  setup() {
    const first = Vue.ref("John");
    const last = Vue.ref("Doe");

    return {
      first,
      last,
    };
  },
});

完整的程式碼可以到這裡試試


上一篇
我的 Vue.js 筆記(22) - 元件之間的溝通:emit
下一篇
我的 Vue.js 筆記(24) - 動態元件 is 與 keep-alive
系列文
這是我的 Vue.js 筆記,不知道有沒有機會幫到你30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言