Vue-(4)表單-組件-自定義事件

一:表單

v-model 會根據(jù)控件類型自動選取正確的方法來更新元素

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <p>input 元素:</p>
  <input v-model="message" placeholder="編輯我……">
  <p>消息是: {{ message }}</p>
    
  <p>textarea 元素:</p>
  <p style="white-space: pre">{{ message2 }}</p>
  <textarea v-model="message2" placeholder="多行文本輸入……"></textarea>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob',
    message2: '菜鳥教程\r\nhttp://www.runoob.com'
  }
})
</script>
</body>
</html>

運行結(jié)果:

QQ20210817-142452-HD.gif

復選框
復選框如果是一個為邏輯值奕翔,如果是多個則綁定到同一個數(shù)組:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <p>單個復選框:</p>
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{ checked }}</label>
    
  <p>多個復選框:</p>
  <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
  <label for="runoob">Runoob</label>
  <input type="checkbox" id="google" value="Google" v-model="checkedNames">
  <label for="google">Google</label>
  <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
  <label for="taobao">taobao</label>
  <br>
  <span>選擇的值為: {{ checkedNames }}</span>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    checked : false,
    checkedNames: []
  }
})
</script>
</body>
</html>

運行結(jié)果:

QQ20210817-142741-HD.gif

單選按鈕
以下實例中演示了單選按鈕的雙向數(shù)據(jù)綁定:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <input type="radio" id="runoob" value="Runoob" v-model="picked">
  <label for="runoob">Runoob</label>
  <br>
  <input type="radio" id="google" value="Google" v-model="picked">
  <label for="google">Google</label>
  <br>
  <span>選中值為: {{ picked }}</span>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    picked : 'Runoob'
  }
})
</script>
</body>
</html>

運行結(jié)果:

QQ20210817-142919-HD.gif

select 列表
以下實例中演示了下拉列表的雙向數(shù)據(jù)綁定

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <select v-model="selected" name="fruit">
    <option value="">選擇一個網(wǎng)站</option>
    <option value="www.runoob.com">Runoob</option>
    <option value="www.google.com">Google</option>
  </select>
 
  <div id="output">
      選擇的網(wǎng)站是: {{selected}}
  </div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    selected: '' 
  }
})
</script>
</body>
</html>

運行結(jié)果:

QQ20210817-143040-HD.gif
修飾符

.lazy
在默認情況下, v-model 在 input 事件中同步輸入框的值與數(shù)據(jù)弱左,但你可以添加一個修飾符 lazy 侧纯,從而轉(zhuǎn)變?yōu)樵?change 事件中同步:

<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

.number
如果想自動將用戶的輸入值轉(zhuǎn)為 Number 類型(如果原值的轉(zhuǎn)換結(jié)果為 NaN 則返回原值)骚揍,可以添加一個修飾符 number 給 v-model 來處理輸入值:

<input v-model.number="age" type="number">

這通常很有用媳拴,因為在 type="number" 時 HTML 中輸入的值也總是會返回字符串類型依鸥。

.trim
如果要自動過濾用戶輸入的首尾空格亥至,可以添加 trim 修飾符到 v-model 上過濾輸入:

<input v-model.trim="msg">

二:組件

組件(Component)是 Vue.js最強大的功能之一。
組件可以擴展 HTML 元素贱迟,封裝可重用的代碼姐扮。
組件系統(tǒng)讓我們可以用獨立可復用的小組件來構(gòu)建大型應(yīng)用,幾乎任意類型的應(yīng)用的界面都可以抽象為一個組件樹:

image.png

注冊一個全局組件語法格式如下:

Vue.component(tagName, options)

tagName 為組件名衣吠,options 為配置選項茶敏。注冊后,我們可以使用以下方式來調(diào)用組件:

<tagName></tagName>

全局組件: 所有實例都能用全局組件缚俏。
注冊一個簡單的全局組件runoob惊搏,并使用它:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <runoob></runoob>
</div>

<script>
// 注冊
Vue.component('runoob', {
  template: '<h1>自定義組件!</h1>'
})
// 創(chuàng)建根實例
new Vue({
  el: '#app'
})
</script>
</body>
</html>

結(jié)果:

自定義組件!

局部組件: 實例選項中注冊局部組件贮乳,這樣組件只能在這個實例中使用:。
注冊一個簡單的局部組件runoob恬惯,并使用它:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <runoob></runoob>
</div>

<script>
var Child = {
  template: '<h1>自定義組件!</h1>'
}

// 創(chuàng)建根實例
new Vue({
  el: '#app',
  components: {
    // <runoob> 將只在父模板可用
    'runoob': Child
  }
})
</script>
</body>
</html>

結(jié)果:

自定義組件!

Prop: prop 是子組件用來接受父組件傳遞過來的數(shù)據(jù)的一個自定義屬性向拆。
父組件的數(shù)據(jù)需要通過 props 把數(shù)據(jù)傳給子組件,子組件需要顯式地用 props 選項聲明 "prop":

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <child message="hello!"></child>
</div>

<script>
// 注冊
Vue.component('child', {
  // 聲明 props
  props: ['message'],
  // 同樣也可以在 vm 實例中像 “this.message” 這樣使用
  template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實例
new Vue({
  el: '#app'
})
</script>
</body>
</html>

結(jié)果:

hello!

動態(tài) Prop: 類似于用 v-bind 綁定 HTML 特性到一個表達式酪耳,也可以用 v-bind 動態(tài)綁定 props 的值到父組件的數(shù)據(jù)中亲铡。每當父組件的數(shù)據(jù)變化時,該變化也會傳導給子組件:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>

<script>
// 注冊
Vue.component('child', {
  // 聲明 props
  props: ['message'],
  // 同樣也可以在 vm 實例中像 “this.message” 這樣使用
  template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父組件內(nèi)容'
  }
})
</script>
</body>
</html>

結(jié)果:輸入框改變葡兑,下面的內(nèi)容也變

image.png

動態(tài) Prop: 類似于用 v-bind 綁定 HTML 特性到一個表達式奖蔓,也可以用 v-bind 動態(tài)綁定 props 的值到父組件的數(shù)據(jù)中。每當父組件的數(shù)據(jù)變化時讹堤,該變化也會傳導給子組件:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <ol>
    <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
    </ol>
</div>

<script>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
new Vue({
  el: '#app',
  data: {
    sites: [
      { text: 'Runoob' },
      { text: 'Google' },
      { text: 'Taobao' }
    ]
  }
})
</script>
</body>
</html>

結(jié)果

1. Runoob
2. Google
3. Taobao

Prop 驗證: 組件可以為 props 指定驗證要求吆鹤。
為了定制 prop 的驗證方式,你可以為 props 中的值提供一個帶有驗證需求的對象洲守,而不是一個字符串數(shù)組疑务。例如:

Vue.component('my-component', {
  props: {
    // 基礎(chǔ)的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證)
    propA: Number,
    // 多個可能的類型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 帶有默認值的數(shù)字
    propD: {
      type: Number,
      default: 100
    },
    // 帶有默認值的對象
    propE: {
      type: Object,
      // 對象或數(shù)組默認值必須從一個工廠函數(shù)獲取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗證函數(shù)
    propF: {
      validator: function (value) {
        // 這個值必須匹配下列字符串中的一個
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

當 prop 驗證失敗的時候,(開發(fā)環(huán)境構(gòu)建版本的) Vue 將會產(chǎn)生一個控制臺的警告梗醇。
type 可以是下面原生構(gòu)造器:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

type 也可以是一個自定義構(gòu)造器知允,使用 instanceof 檢測比庄。

三:自定義事件

父組件是使用props傳遞數(shù)據(jù)給子組件忽肛,但如果子組件要把數(shù)據(jù)傳遞回去,就需要使用自定義事件秉版!
我們可以使用 v-on 綁定自定義事件, 每個 Vue 實例都實現(xiàn)了事件接口(Events interface)手负,即:

  • 使用 $on(eventName) 監(jiān)聽事件
  • 使用 $emit(eventName)觸發(fā)事件

另外涤垫,父組件可以在使用子組件的地方直接用v-on來監(jiān)聽子組件觸發(fā)的事件。
以下實例中子組件已經(jīng)和它外部完全解耦了竟终。它所做的只是觸發(fā)一個父組件關(guān)心的內(nèi)部事件蝠猬。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>

<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>
</body>
</html>

結(jié)果:

image.png

如果你想在某個組件的根元素上監(jiān)聽一個原生事件⊥炒罚可以使用 .native 修飾 v-on 榆芦。例如:

<my-component v-on:click.native="doTheThing"></my-component>

data必須是一個函數(shù)
上面例子中,可以看到 ·button-counter 組件中的data不是一個對象喘鸟,而是一個函數(shù):

data: function () {
  return {
    count: 0
  }
}

這樣的好處就是每個實例可以維護一份被返回對象的獨立的拷貝匆绣,如果 data 是一個對象則會影響到其他實例,如下所示:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="components-demo3" class="demo">
    <button-counter2></button-counter2>
    <button-counter2></button-counter2>
    <button-counter2></button-counter2>
</div>

<script>
var buttonCounter2Data = {
  count: 0
}
Vue.component('button-counter2', {
    /*
    data: function () {
        // data 選項是一個函數(shù)迷守,組件不相互影響
        return {
            count: 0
        }
    },
    */
    data: function () {
        // data 選項是一個對象犬绒,會影響到其他實例
        return buttonCounter2Data
    },
    template: '<button v-on:click="count++">點擊了 {{ count }} 次旺入。</button>'
})
new Vue({ el: '#components-demo3' })
</script>
</body>
</html>

結(jié)果:點擊8次的效果

image.png

自定義組件的 v-model
組件上的 v-model 默認會利用名為 valueprop和名為 input 的事件兑凿。

 <input v-model="parentData">

等價于:

<input 
    :value="parentData"
    @input="parentData = $event.target.value"
>

以下實例自定義組件 runoob-input凯力,父組件的 num 的初始值是 100,更改子組件的值能實時更新父組件的 num:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <runoob-input v-model="num"></runoob-input>
    <p>輸入的數(shù)字為:{{num}}</p>
</div>
<script>
Vue.component('runoob-input', {
    template: `
    <p>   <!-- 包含了名為 input 的事件 -->
      <input
       ref="input"
       :value="value" 
       @input="$emit('input', $event.target.value)"
      >
    </p>
    `,
    props: ['value'], // 名為 value 的 prop
})
   
new Vue({
    el: '#app',
    data: {
        num: 100,
    }
})
</script>
</body>
</html>

結(jié)果:

image.png

由于 v-model 默認傳的是 value礼华,不是 checked咐鹤,所以對于復選框或者單選框的組件時,我們需要使用 model 選項圣絮,model 選項可以指定當前的事件類型和傳入的 props祈惶。

由于 v-model 默認傳的是 value,不是 checked扮匠,所以對于復選框或者單選框的組件時捧请,我們需要使用 model 選項,model 選項可以指定當前的事件類型和傳入的 props棒搜。

結(jié)果:

image.png

data 也可以是對象:

Vue.component('button-counter2', {
    /*
    data: function () {
    // data 選項是一個函數(shù)疹蛉,組件不相互影響
        return {
            count: 0
        }
    },
    */
    data: function () {
        // data 選項是一個對象,會影響到其他實例
        return buttonCounter2Data
    },
    template: '<button v-on:click="count++">點擊了 {{ count }} 次力麸。</button>'
})

注釋起來的 data 代碼和未注釋起來的 data 都是函數(shù)可款,只是注釋起來的函數(shù)返回值是每執(zhí)行一次函數(shù)就產(chǎn)生一個獨立的對象,而未注釋的data函數(shù)返回值卻是引用了一個已有對象的名稱(即對象的引用)克蚂,不管函數(shù)執(zhí)行多少次返回值都是這個外部定義的對象的引用而已闺鲸,也就是說不管有多少個組件,所有的組件維護的數(shù)據(jù)都是同一個對象的數(shù)據(jù)而已埃叭,所以一個組件的數(shù)據(jù)發(fā)生變化同樣會影響到其他所有的組件的數(shù)據(jù)摸恍。。赤屋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末误墓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子益缎,更是在濱河造成了極大的恐慌谜慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莺奔,死亡現(xiàn)場離奇詭異欣范,居然都是意外死亡,警方通過查閱死者的電腦和手機令哟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門恼琼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屏富,你說我怎么就攤上這事晴竞。” “怎么了狠半?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵噩死,是天一觀的道長颤难。 經(jīng)常有香客問我,道長已维,這世上最難降的妖魔是什么行嗤? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮垛耳,結(jié)果婚禮上栅屏,老公的妹妹穿的比我還像新娘。我一直安慰自己堂鲜,他們只是感情好栈雳,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缔莲,像睡著了一般甫恩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酌予,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天磺箕,我揣著相機與錄音,去河邊找鬼抛虫。 笑死松靡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的建椰。 我是一名探鬼主播雕欺,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棉姐!你這毒婦竟也來了屠列?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤伞矩,失蹤者是張志新(化名)和其女友劉穎笛洛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乃坤,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡苛让,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了湿诊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狱杰。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖厅须,靈堂內(nèi)的尸體忽然破棺而出仿畸,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布错沽,位于F島的核電站,受9級特大地震影響抢蚀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧易阳,春花似錦潦俺、人聲如沸事示。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至葛超,卻和暖如春答渔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背务豺。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工娶牌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留汹桦,地道東北人营勤。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓猖凛,卻偏偏與公主長得像辨泳,于是被迫代替她去往敵國和親第岖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容