選單
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

Vue 教程

Vue 首頁 Vue Intro Vue Directives Vue v-bind Vue v-if Vue v-show Vue v-for Vue Events Vue v-on Vue Methods Vue Event Modifiers Vue Forms Vue v-model Vue CSS Binding Vue Computed Properties Vue Watchers Vue Templates

Scaling Up

Vue 為什麼、如何以及設定 Vue 第一個 SFC 頁面 Vue 元件 Vue Props Vue v-for 元件 Vue $emit() Vue Fallthrough Attributes Vue Scoped Styling Vue Local Components Vue Slots Vue v-slot Vue Scoped Slots Vue Dynamic Components Vue Teleport Vue HTTP Request Vue Template Refs Vue Lifecycle Hooks Vue Provide/Inject Vue Routing Vue Form Inputs Vue Animations Vue Animations with v-for Vue Build Vue Composition API

Vue Reference

Vue Built-in Attributes Vue Built-in Components Vue Built-in Elements Vue Component Instance Vue Directives Vue Instance Options Vue Lifecycle Hooks

Vue 示例

Vue Examples Vue Exercises Vue Quiz Vue Server Vue Certificate

Vue v-model 指令


示例

使用 v-model 指令在 <input> 元素和一個數據屬性之間建立雙向繫結。

<template>
  <h1>v-model Example</h1>
  <p>Write something, and see the 'inputValue' data property update automatically.</p>
  <input type="text" v-model="inputValue"> 
  <p>inputValue property: "{{ inputValue }}"</p>
</template>
執行示例 »

更多示例請參見下方。


定義和用法

v-model 指令用於在表單輸入元素之間,或在 Vue 例項屬性和元件之間建立雙向繫結。


v-model 的表單輸入元素

可以與 v-model 一起使用的表單輸入元素包括 <input><select><textarea>

在表單輸入元素上使用 v-model 進行雙向繫結的工作方式如下:

  • 當 Vue 檢測到輸入值發生變化時,它會相應地更新對應的資料屬性。(HTML -> JavaScript)
  • 當 Vue 檢測到 Vue 例項屬性發生變化時,它會相應地更新對應的輸入值。(JavaScript -> HTML)

(參見上面的示例,以及下面的示例 1。)


v-model 的元件

v-model 用於元件時,元件介面必須透過 propsemits 正確設定,才能實現雙向繫結。

在元件上使用 v-model 進行雙向繫結的工作方式如下:

  • 當 Vue 檢測到父例項屬性發生變化時,新值將作為 prop 傳送到元件。
  • 當 Vue 檢測到子元件發生變化時,新值將作為一個 emit 事件向上傳送到父元件。

v-model 用於元件時,預設 prop 名稱是 'modelValue',預設 emit 事件名稱是 'update:modelValue'。(參見 示例 2示例 3。)

v-model 用於元件時,我們不必使用 Vue 例項資料屬性,而是可以使用計算屬性,並帶有 get()set() 方法。(參見示例 4

與預設的 'modelValue' 和 'update:modelValue' 不同的 prop 和 emit 名稱,可以使用 v-model: 進行設定。(參見示例 5

要將多個值作為雙向繫結連線到元件,我們必須為每個這樣的值定義自己的 v-model。(參見示例 6


修飾符

修飾符 詳情
.lazy Vue 使用 change 事件而不是 input 事件來進行同步。這意味著使用者必須先修改輸入,然後將焦點從輸入元素移開,例項屬性的值才會更新。(參見示例 7
.number 將輸入轉換為數字。使用 <input type="number"> 時會自動進行此操作。
.trim 刪除輸入開頭和結尾的空白字元。(參見示例 8
custom 要建立一個自定義的 v-model 修飾符,我們首先需要定義一個名為 'modelModifiers' 的 prop 來儲存新的修飾符。修飾符功能寫在一個方法中。如果設定了修飾符,則在將值 emit 回父元件之前,會在方法中執行相應的程式碼。(參見示例 9


更多示例

示例 1

使用滑塊(<input type="range">)來更改 'inputValue' 屬性值。因為 <input type="text"> 元素是透過 v-model 繫結到 'inputValue' 屬性的,所以它會自動更新。

<template>
  <h1>v-model Example</h1>
  <p>Drag the slider to change the 'inputValue' data property, and see the input text field update automatically because of the two-way binding from v-model.</p>
  <input type="range" min="-50" max="50" v-on:input="sliderChange" value="4">
  <p>inputValue property: "{{ inputValue }}"</p>
  <input type="text" v-model="inputValue"> 
</template>

<script>
export default {
  data() {
    return {
      inputValue: null
    };
  },
  methods: {
    sliderChange(evt) {
      this.inputValue = evt.target.value
    }
  }
}
</script>
執行示例 »

示例 2

在元件上使用 v-model,配合 propsemits,以便 <input> 元素的變化可以更新父級的 'text' 屬性。

App.vue:

<template>
  <h2>Example v-model Directive</h2>
  <p>App.vue 'text' property: "{{ text }}"</p>
  <comp-one v-model="text"/>
</template>

<script>
export default {
  data() {
    return {
      text: 'Say Cheese'
    }
  }
}
</script>

CompOne.vue:

<template>
  <div>
    <h3>Component</h3>
    <p>Write something in the text input field below to see that changes here are emitted from the component, and the parent 'text' property gets updated by the use of v-model.</p>
    <input
      :value="modelValue"
      @input="$emit('update:modelValue', $event.target.value)"
    />
  </div>
</template>

<script>
  export default {
    props: ['modelValue'],
    emits: ['update:modelValue']
  }
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
  margin: 20px 0;
  max-width: 500px;
}
</style>
執行示例 »

示例 3

在元件上使用 v-model 以更清晰地演示雙向繫結。元件可以更新父級的 'text' 屬性,並且當父級的 'text' 屬性改變時,元件也會更新。

App.vue:

<template>
  <h2>Example v-model Directive</h2>
  <p>App.vue 'text' property: "<pre>{{ text }}</pre>"</p>
  <button v-on:click="this.text = 'Hello!'">text='Hello!'</button>
  <comp-one v-model="text"/>
</template>

<script>
export default {
  data() {
    return {
      text: 'Say Cheese'
    }
  }
}
</script>

<style>
pre {
  display: inline;
  background-color: yellow;
}
</style>

CompOne.vue:

<template>
  <div>
    <h3>Component</h3>
    <p>Two-way binding on component with v-model:</p>
    <ol>
      <li>The component can update the 'text' property (using text field).</li>
      <li>The component gets updated when the 'text' property is changed (using button).</li>
    </ol>
    <input
      :value="modelValue"
      @input="$emit('update:modelValue', $event.target.value)"
    />
  </div>
</template>

<script>
  export default {
    props: ['modelValue'],
    emits: ['update:modelValue']
  }
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
  margin: 20px 0;
  max-width: 600px;
}
</style>
執行示例 »

示例 4

在元件內部使用 v-model 配合計算值,其中包含 get()set() 函式。

CompOne.vue:

<template>
  <div>
    <h3>Component</h3>
    <p>Two-way binding on component with v-model:</p>
    <ol>
      <li>The component can update the 'text' property (using text field).</li>
      <li>The component gets updated when the 'text' property is changed (using button).</li>
    </ol>
    <input v-model="inpVal"/>
  </div>
</template>

<script>
  export default {
    props: ['modelValue'],
    emits: ['update:modelValue'],
    computed: {
      inpVal: {
        get() {
          return this.modelValue;
        },
        set(inpVal) {
          this.$emit('update:modelValue',inpVal)
        }
      }
    }
  }
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
  margin: 20px 0;
  max-width: 600px;
}
</style>
執行示例 »

示例 5

在元件上使用 v-model:message 將預設 prop 名稱 'modelValue' 重新命名為 'message'。

App.vue:

<template>
  <h2>Example v-model Directive</h2>
  <p>App.vue 'text' property: "<pre>{{ text }}</pre>"</p>
  <button v-on:click="this.text = 'Hello!'">text='Hello!'</button>
  <comp-one v-model:message="text"/>
</template>

<script>
export default {
  data() {
    return {
      text: 'Say Cheese'
    }
  }
}
</script>

<style>
pre {
  display: inline;
  background-color: yellow;
}
</style>

CompOne.vue:

<template>
  <div>
    <h3>Component</h3>
    <p>Two-way binding on component with v-model:</p>
    <ol>
      <li>The component can update the 'text' property (using text field).</li>
      <li>The component gets updated when the 'text' property is changed (using button).</li>
    </ol>
    <input
      :value="message"
      @input="$emit('update:message', $event.target.value)"
    />
  </div>
</template>

<script>
  export default {
    props: ['message'],
    emits: ['update:message']
  }
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
  margin: 20px 0;
  max-width: 600px;
}
</style>
執行示例 »

示例 6

在元件上使用兩次 v-model 來建立兩個值的雙向繫結。

App.vue:

<template>
  <h2>Example v-model Directive</h2>
  <p>Name: "<pre>{{ name }}</pre>"</p>
  <p>Height: <pre>{{ height }}</pre> cm</p>
  <comp-one 
    v-model:name="name"
    v-model:height="height"
  />
</template>

<script>
export default {
  data() {
    return {
      name: 'Olaf',
      height: 120
    }
  }
}
</script>

<style>
pre {
  display: inline;
  background-color: yellow;
}
</style>

CompOne.vue:

<template>
  <div>
    <h3>Component</h3>
    <p>Two inputs are bound to the component with v-model through props and emits.</p>
    <p>
      <label>
        Name: 
        <input
          type="text"
          :value="name"
          @input="$emit('update:name', $event.target.value)"
        />
      </label>
    </p>
    <p>
      <label>
        Height:
        <input
          type="range"
          :value="height"
          @input="$emit('update:height', $event.target.value)"
          min="50"
          max="200"
        />
        {{ this.$props.height }} cm
      </label>
    </p>
  </div>
</template>

<script>
  export default {
    props: ['name','height'],
    emits: ['update:name','update:height']
  }
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
  margin: 20px 0;
  max-width: 300px;
}
</style>
執行示例 »

示例 7

使用 .lazy 修飾符,這樣使用者必須先修改輸入元素,然後將焦點移出輸入元素,屬性才會被 v-model 更新。

<template>
  <h1>v-model Example</h1>
  <p>Using the '.lazy' modifier, you must first write something, then click somewhere else, or use the tab key to switch focus away from the input element, before the property get updated.</p>
  <input type="text" v-model.lazy="inputValue"> 
  <p>inputValue property: "{{ inputValue }}"</p>
</template>

<script>
export default {
  data() {
    return {
      inputValue: null
    };
  }
}
</script>
執行示例 »

示例 8

使用 .lazy 修飾符,這樣使用者必須先修改輸入元素,然後將焦點移出輸入元素,屬性才會被 v-model 更新。

<template>
  <h1>v-model Example</h1>
  <p>Using the '.trim' modifier will remove any white spaces at the start and end of the input.</p>
  <p>Add white spaces at the start and end in the input fields below to see the difference with or with out '.trim'.</p>
  <p>No '.trim': <input type="text" v-model="inputVal1"> "<pre>{{ inputVal1 }}</pre>"</p> 
  <p>With '.trim': <input type="text" v-model.trim="inputVal2"> "<pre>{{ inputVal2 }}</pre>"</p>
  
</template>

<script>
export default {
  data() {
    return {
      inputVal1: 'Hello',
      inputVal2: 'Hi'
    };
  }
}
</script>

<style>
pre {
  display: inline;
  background-color: lightgreen;

}
</style>
執行示例 »

示例 9

使用自定義的 .allCapital 修飾符,如果在設定了 .allCapital 修飾符的情況下,將輸入中的所有字元轉換為大寫。

App.vue:

<template>
  <h2>Example v-model Directive</h2>
  <p>App.vue 'text' property: "{{ text }}"</p>
  <comp-one v-model.allCapital="text"/>
</template>

<script>
export default {
  data() {
    return {
      text: ''
    }
  }
}
</script>

CompOne.vue:

<template>
  <div>
    <h3>Component</h3>
    <p>Write something in the text input field below. Click somewhere else or use the tab key to shift focus away from the input element to see the effect of the custom 'allCapital' modifier.</p>
    <input 
      :value="modelValue" 
      @change="this.emitVal" 
    />
  </div>
</template>

<script>
export default {
  props: {
    modelValue: String,
    modelModifiers: {
      // modelModifiers is an empty object initially.
      // Modifiers set on the component will be stored here.
      default: () => ({}) 
    }
  },
  emits: ['update:modelValue'],
  methods: {
    emitVal(e) {
      let value = e.target.value
      if (this.modelModifiers.allCapital) {
        value = value.toUpperCase()
      }
      this.$emit('update:modelValue', value)
    }
  }
}
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
  margin: 20px 0;
  max-width: 500px;
}
</style>
執行示例 »

相關頁面

Vue 教程:Vue Components

Vue 教程:Vue Props

Vue 教程:Vue $emit() Method

Vue 教程:Vue Computed Properties

Vue Reference: Vue $emit() Method

Vue Reference: Vue $props Object

JavaScript Tutorial: JavaScript Object Accessors


×

聯絡銷售

如果您想將 W3Schools 服務用於教育機構、團隊或企業,請傳送電子郵件給我們
sales@w3schools.com

報告錯誤

如果您想報告錯誤,或想提出建議,請傳送電子郵件給我們
help@w3schools.com

W3Schools 經過最佳化,旨在方便學習和培訓。示例可能經過簡化,以提高閱讀和學習體驗。教程、參考資料和示例會不斷審查,以避免錯誤,但我們無法保證所有內容的完全正確性。使用 W3Schools 即表示您已閱讀並接受我們的使用條款Cookie 和隱私政策

版權所有 1999-2024 Refsnes Data。保留所有權利。W3Schools 由 W3.CSS 提供支援