vue.js 從基礎到實戰(匯總)

vue.js 從基礎到實戰


Vue.js 介紹

什么是vue

vue一詞是法語,同英語中的view。
vue.js是一套構建用戶界面的MVVM框架。vue的核心庫只關注視圖層,經常與其他庫或者已有的項目整合

vue的目的

1). 解決數據綁定問題
2). vue框架生產的主要目的是為了開發大型單頁應用(SPA:single page appliacation),對移動端支持較好,PC端也支持,而angular對PC端支持好,移動端支持不是很好
3). vue支持組件化(方便復用),也就是將頁面封裝成若干個組件,采用積木式編程,使頁面的復用度達到最高。實現一次開發多次復用的目的

SPA簡介 :在制作APP時,需要運用Android程序員,iOS程序員和.net程序員(Windows phone),很浪費財力物力,于是人們想用HTML5開發APP,但是遇到一個問題:從一個頁面調到另一個頁面會消耗很長的時間。解決方法是將APP所用到的所有頁面構建出來放到一個網頁上,根據JavaScript按照一定的規則來控制到底顯示哪一個頁面,所有切換通過router完成,這就是單頁面應用。所以SPA主要是解決H5做APP卡頓的問題。

vue的特性

1). MVVM模型
2). 組件化
3). 指令系統
4). vue.js從2.0開始支持虛擬DOM,vue.js1.0操作的是真實的DOM,而不是虛擬的DOM(虛擬DOM可以提升頁面的刷新速度)

MVVM模式 :
? M:model 業務模式 用處:處理數據,提供數據
? V:view 用戶界面,用戶視圖
? 業務模式model中的數據發生改變時,用戶視圖view也隨之改變;用戶視圖view改變時,業務模式model中的數據也可以發生改變

vue 入門

1.) vue.js和vue.min.js

vue.js是完整的vue文件,包括換行,空格,注釋等,一般用于開發使用
vue.min.js是壓縮之后的vue文件,在功能上與vue.js無差別,但它是壓縮過的,文件比較小,沒有注釋,也將錯誤調試信息關閉了,它的下載速度更快,一般用于線上項目

2.) vue.js是一個js庫,直接在外部引入即可

<script src="js/vue.js"></script>

3.) vue.js提供了Vue類,它是一個對象

var app = new Vue({});

4.) 對象參數里常用的兩個屬性:el和data

var app = new Vue({
    el : '#app',    // 管理id為app的元素
    data : {}    // data的核心作用是存放顯示在頁面中的數據,data必須是一個對象

})

var app = new Vue({
    el : '.app'        // 管理class為app的元素
})

5.) 創建一個實例

<div id="app">
    {{ message }}        
</div>

var app = new Vue({
    el : '#app',
    data : {
        message : 'hello world'    
    }
})

實例解析:
??在用戶界面view中,通過{{ }}的形式將data中的數據顯示在頁面中
而在用戶界面中,{{ }}綁定的是data的key值(這里是message),而頁面中顯示的是該key的value值(這里是hello world)

app這個變量會代理vue中data的數據,所以我們訪問data中的數據時,直接用app.message就可以了

Vue.js 計算屬性

為什么使用計算屬性?

模板內的表達式是非常便利的,但是它們實際上只用于簡單的運算。在模板中放入太多的邏輯會讓模板過重且難以維護。例如:

<div id="example">
{{ message.split('').reverse().join('') }}
</div>

在這種情況下,模板不再簡單和清晰。在意識到這是反向顯示 message 之前,你不得不再次確認第二遍。當你想要在模板中多次反向顯示 message 的時候,問題會變得更糟糕。
這就是對于任何復雜邏輯,你都應當使用計算屬性的原因。

基礎例子
注: Vue 中 computed 是實時計算的意思。

<div id="app">
 <p>原始的消息 : "{{ message }}"</p>
 <p>反轉的消息: "{{ reversedMessage }}"</p>
</div>
<script type="text/javascript">
var vm = new Vue({
 el: '#app',
 data: {
  message: 'Hello'
 },
 computed: {
  //反轉文本
   reversedMessage: function () {
   return this.message.split('').reverse().join('');
  } 
 }
});
</script>

計算屬性 和 Methods(方法)

我們可以通過調用表達式中的 method 來達到同樣的效果:

<div id="app">
 <p>原始的消息 : "{{ message }}"</p>
 <p>反轉的消息: "{{ reversedMessage() }}"</p>
</div>
<script type="text/javascript">
var vm = new Vue({
 el: '#app',
 data: {
  message: 'Hello'
 },
 methods: {
  //反轉文本
  reversedMessage: function () {
   return this.message.split('').reverse().join('');
  } 
 }
});
</script>

我們可以將同一函數定義為一個 method 而不是一個計算屬性。對于最終的結果,兩種方式確實是相同的。
然而,不同的是計算屬性是基于它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時才會重新求值。這就意味著只要 message 還沒有發生改變,多次訪問 reversedMessage 計算屬性會立即返回之前的計算結果,而不必再次執行函數。
一個比較例子

computed:{
    now: function (){
        return Date.now();
    }
}

相比而言,只要發生重新渲染,method 調用總會執行該函數。
我們為什么需要緩存?假設我們有一個性能開銷比較大的的計算屬性 A,它需要遍歷一個極大的數組和做大量的計算。然后我們可能有其他的計算屬性依賴于 A 。
如果沒有緩存,我們將不可避免的多次執行 A 的 getter!如果你不希望有緩存,請用 method 替代。

計算屬性 vs Watched 屬性

Vue 提供了一種更通用的方式來觀察和響應 Vue 實例上的數據變動:watch 屬性。
當你有一些數據需要隨著其它數據變動而變動時,你可以使用 watch。然而,通常更好的想法是使用 computed 屬性而不是命令式的 watch 回調。細想一下這個例子:

<div id="demo">{{ fullName }}</div>
<script type="text/javascript">
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
});
vm.$data.firstName = 'hi..';
</script>

上面代碼是命令式的和重復的。將它與計算屬性的版本進行比較:

var vm = new Vue({

  el: '#demo',

  data: {

    firstName: 'Foo',

    lastName: 'Bar'

  },

  computed: {

    fullName: function () {

      return this.firstName + ' ' + this.lastName

    }

  }

})
vm.$data.firstName = 'hi..';

好得多了,不是嗎?

Vue.js Class 與 Style 綁定

數據綁定一個常見需求是操作元素的 class 列表和它的內聯樣式。因為它們都是屬性 ,我們可以用v-bind 處理它們:只需要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。因此,在 v-bind 用于 class 和 style 時, Vue.js 專門增強了它。表達式的結果類型除了字符串之外,還可以是對象或數組。

class綁定

普通綁定

<style type="text/css">
    .red{color:#FF0000;}
</style>

<div id="app" :class="test">
 test...
</div>
<script type="text/javascript" src="js/vue.min.js" charset="UTF-8"></script>
<script type="text/javascript">
var vue = new Vue({
 el : '#app',
 data : {
  test : 'red'
 }
});
</script>

對象語法綁定

我們可以傳給 v-bind:class 一個對象,以動態地切換 class:

<div v-bind:class="{ active: isActive }"></div>

上面的語法表示 class active 的更新將取決于數據屬性 isActive 是否為真值 。
你可以在對象中傳入更多屬性用來動態切換多個 class。此外, v-bind:class 指令也可以與普通的 class 屬性共存。如下模板:

<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
如下 data :
data: {
  isActive: true,
  hasError: false
}

渲染為:

<div class="static active"></div>

當 isActive 或者 hasError 變化時,class 列表將相應地更新。例如,如果 hasError 的值為 true , class列表將變為 "static active text-danger" 。
你也可以直接綁定數據里的一個對象:

<div v-bind:class="classObject"></div>

data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

渲染的結果和上面一樣。我們也可以在這里綁定返回對象的計算屬性。這是一個常用且強大的模式:

<div v-bind:class="classObject"></div>

data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active : this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal',
    }
  }
}

數組語法

我們可以把一個數組傳給 v-bind:class,以應用一個 class 列表:

<div v-bind:class="[activeClass, errorClass]">

data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

渲染為:

<div class="active text-danger"></div>

如果你也想根據條件切換列表中的 class,可以用三元表達式:

<div v-bind:class="[isActive ? activeClass : '', errorClass]">

此例始終添加 errorClass ,但是只有在 isActive 是 true 時添加 activeClass。
不過,當有多個條件 class 時這樣寫有些繁瑣。可以在數組語法中使用對象語法:

<div v-bind:class="[{ active: isActive }, errorClass]">

綁定內聯樣式style

對象語法

v-bind:style 的對象語法十分直觀——看著非常像 CSS,其實它是一個 JavaScript 對象。 CSS 屬性名可以用駝峰式 (camelCase) 或 (配合引號的) 短橫分隔命名 (kebab-case):

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

data: {
  activeColor: 'red',
  fontSize: 30
}

直接綁定到一個樣式對象通常更好,讓模板更清晰:

<div v-bind:style="styleObject"></div>

data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

同樣的,對象語法常常結合返回對象的計算屬性使用。

自動添加前綴

當 v-bind:style 使用需要特定前綴的 CSS 屬性時,如 transform,Vue.js 會自動偵測并添加相應的前綴。

多重值

從 2.3.0 起你可以為 style 綁定中的屬性提供一個包含多個值的數組,常用于提供多個帶前綴的值,例如:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">

這會渲染數組中最后一個被瀏覽器支持的值。在這個例子中,如果瀏覽器支持不帶瀏覽器前綴的 flexbox,那么渲染結果會是 display: flex。

Vue.js 條件渲染

v-if

<div id="app">
  <h1 v-if="ok">Yes</h1>
</div>
<script type="text/javascript">
var app = new Vue({
 el : '#app',
 data : {ok : true}
});
</script>

在 <template> 中配合 v-if 條件渲染一整組

因為 v-if 是一個指令,需要將它添加到一個元素上。但是如果我們想切換多個元素呢?此時我們可以把一個 <template> 元素當做包裝元素,并在上面使用 v-if。最終的渲染結果不會包含<template> 元素。

<div id="app">
 <template v-if="ok">
    <h1>Title</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
 </template>
</div>
<script type="text/javascript">
var app = new Vue({
 el : '#app',
 data : {ok : true}
});
</script>

v-else

你可以使用 v-else 指令來表示 v-if 的“else 塊”:

<div id="app">
    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
</div>
<script type="text/javascript">
var app = new Vue({
 el : '#app',
 data : {ok : true}
});
</script>

v-else 元素必須緊跟在 v-if 或者 v-else-if 元素的后面——否則它將不會被識別。

v-else-if

v-else-if,顧名思義,充當 v-if 的“else-if 塊”。可以鏈式地使用多次:

<div id="app">
 <h1 v-if="color == 'red'" style="color:#FF0000;">red</h1>
 <h1 v-if="color == 'green'" style="color:#00FF00;">green</h1>
 <h1 v-else style="color:#0000FF;">blue</h1>
</div>

<script type="text/javascript">
var app = new Vue({
 el : '#app',
 data : {color : 'green'}
});
</script>

類似于 v-else,v-else-if 必須緊跟在 v-if 或者 v-else-if 元素之后。

用 key 管理可復用的元素

Vue 會盡可能高效地渲染元素,通常會復用已有元素而不是從頭開始渲染。這么做,除了使 Vue 變得非常快之外,還有一些有用的好處。例如,如果你允許用戶在不同的登錄方式之間切換:

<div id="app">
    <template v-if="loginType === 'username'">
         <label>Username</label>
         <input placeholder="Enter your username" />
    </template>
    <template v-else>
         <label>Email</label>
         <input placeholder="Enter your email address" />
    </template>
    <input type="button" value="切換" v-on:click="changeType" />
</div>

<script type="text/javascript">
var app = new Vue({
 el : '#app',
 data : {'loginType' : 'username'},
 methods : {
  changeType : function(){
   if(this.loginType == 'username'){
    this.loginType = 'email';
   }else{
    this.loginType = 'username';
   }
  }
 }
});
</script>

那么在上面的代碼中切換 loginType 將不會清除用戶已經輸入的內容。因為兩個模版使用了相同的元素,<input> 不會被替換掉——僅僅是替換了它的 placeholder。
這樣也不總是符合實際需求,所以 Vue 為你提供了一種方式來聲明“這兩個元素是完全獨立的——不要復用它們”。只需添加一個具有唯一值的 key 屬性即可:

<div id="app">
    <template v-if="loginType === 'username'">
         <label>Username</label>
         <input placeholder="Enter your username" key="username-input" />
    </template>
    <template v-else>
         <label>Email</label>
         <input placeholder="Enter your email address" key="email-input" />
    </template>
    <input type="button" value="切換" v-on:click="changeType" />
</div>

<script type="text/javascript">
var app = new Vue({
 el : '#app',
 data : {'loginType' : 'username'},
 methods : {
  changeType : function(){
   if(this.loginType == 'username'){
    this.loginType = 'email';
   }else{
    this.loginType = 'username';
   }
  }
 }
});
</script>

現在,每次切換時,輸入框都將被重新渲染。
注意,<label> 元素仍然會被高效地復用,因為它們沒有添加 key 屬性。

v-show

另一個用于根據條件展示元素的選項是 v-show 指令。用法大致一樣:

<h1 v-show="ok">Hello!</h1>

不同的是帶有 v-show 的元素始終會被渲染并保留在 DOM 中。v-show 是簡單地切換元素的 CSS 屬性 display 。
注意, v-show 不支持 <template> 語法,也不支持 v-else。

v-if vs v-show

v-if 是“真正的”條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
v-if 也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
相比之下, v-show 就簡單得多——不管初始條件是什么,元素總是會被渲染,并且只是簡單地基于 CSS 進行切換。
一般來說, v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運行時條件不太可能改變,則使用 v-if 較好。

v-if 與 v-for 一起使用

當 v-if 與 v-for 一起使用時,v-for 具有比 v-if 更高的優先級。

Vue.js 列表渲染

v-for迭代分為數組迭代和對象迭代
作用 : 控制HTML元素中的循環,實現語句列表的生成
用法 : v-for = “item in 集合”,其中item指集合的子項,集合指被遍歷的元素,通常為數組
用處 : 用處:寫在誰上邊,誰遍歷

數組迭代

我們用 v-for 指令根據一組數組的選項列表進行渲染。 v-for 指令需要以 item in items 形式的特殊語法, items 是源數據數組并且 item 是數組元素迭代的別名。
基本用法

<ul id="example-1">
    <li v-for="item in items">{{ item.message }}</li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
</script>

運行結果

* Foo
* bar

在 v-for 塊中,我們擁有對父作用域屬性的完全訪問權限。 v-for 還支持一個可選的第二個參數為當前項的索引。

<ul id="example-1">
    <li v-for="(item, index) in items">{{ index }} - {{ item.message }}</li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
</script>

運行結果

0 - Foo
1 - Bar

你也可以用 of 替代 in 作為分隔符,因為它是最接近 JavaScript 迭代器的語法:

<div v-for="item of items"></div>

template渲染

如同 v-if 模板,你也可以用帶有 v-for 的 <template> 標簽來渲染多個元素塊。例如:

<ul id="example-1">
    <template v-for="item in items">
         <li>{{ item.message }}</li>
         <li>-----------------------------</li>
     </template>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
</script>

運行結果


* Foo
* ----------
* Bar
* ----------

對象遍歷

可以用 v-for 通過一個對象的屬性來迭代。

<ul id="example-1">
    <li v-for="( value, key ) in obj">{{ key }} : {{ value }}</li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    obj:{
     name : 'hcoder',
     age  : '18'
    }
  }
});
</script>

運行結果

* hcoder -- name
* 18 -- age

還可以接受第三個參數作為索引

<ul id="app3">
    <li v-for="(value, key, index) in object">
        {{ index }} : {{ key }} : {{ value }}
    </li>
</ul>

運行結果

* hcoder -- name--1
* 18 -- age--2

整數迭代

v-for 也可以取整數。在這種情況下,它將重復多次模板。

  <div v-for="n in 5">{{ n }} </div>

運行結果

* 1
* 2
* 3
* 5

也可以將10替換成一個變量,從data中提取數據

<div id="app4">
    <span v-for="n in m">
        {{ n }}
    </span>
</div>
    var app4 = new Vue({
         el : '#app4',
         data : {
           m : 5
          }
    })

Vue.js 數組操作

變異方法
Vue 包含一組觀察數組的變異方法,所以它們也將會觸發視圖更新。這些方法如下:

push() 添加元素

<ul id="example-1">
    <li v-for="item in items" :key="item.id">{{ item.message }} </li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
example1.$data.items.push({message :  'test'});
</script>

運行結果

  • Foo
  • Bar
  • test

pop() 刪除最后一個

<ul id="example-1">
    <li v-for="item in items" :key="item.id">{{ item.message }} </li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
example1.$data.items.pop();
</script>

運行結果

  • Foo
  • Bar

shift() 刪除第一個

<ul id="example-1">
    <li v-for="item in items" :key="item.id">{{ item.message }} </li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
example1.$data.items.shift(); 
</script>

運行結果

  • Bar

unshift() 添加一個到數組最前面

<ul id="example-1">
    <li v-for="item in items" :key="item.id">{{ item.message }} </li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'Foo' },
      {message: 'Bar' }
    ]
  }
});
example1.$data.items.unshift({message :'hi..'}); 
</script>

運行結果

  • hi
  • Foo
  • Bar

splice() 插入\刪除\替換數組的元素

參數 描述
index 必需。規定從何處添加/刪除元素。該參數是開始插入和(或)刪除的數組元素的下標,必須是數字。
howmany 必需。規定應該刪除多少元素。必須是數字,但可以是 "0"。如果未規定此參數,則刪除從 index 開始到原數組結尾的所有元素。
item1, ..., itemX 可選。要添加到數組的新元素

example1.$data.items.splice(0,1,{message:'splice'});

sort() 排序(升序)

<ul id="example-1">
    <li v-for="item in items" :key="item.id">{{ item }} </li>
</ul>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      2,6,4
    ]
  }
});
example1.$data.items.sort();

運行結果

  • 2
  • 4
  • 6

reverse() 排序(降序)

example1.$data.items.reverse();

事件處理器v-on

v-on 指令監聽 DOM 事件

<div id="example-1">
 {{ num }}
     <input type="button" value="增加" v-on:click="test" />
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    num : 0
  },
  methods : {
   test : function(){
    this.num++;
   }
  }
});
</script>

內聯處理器方法

<div id="example-1">
 {{ sayContent }}
     <input type="button" value="增加" v-on:click="test('hi... ')" />
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    sayContent : ''
  },
  methods : {
   test : function(txt){
    this.sayContent = txt;
   }
  }
});
</script>

事件修飾符

在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。
盡管我們可以在 methods 中輕松實現這點,但更好的方式是:methods 只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
為了解決這個問題, Vue.js 為 v-on 提供了 事件修飾符。通過由點(.)表示的指令后綴來調用修飾符。

.stop

點擊span阻止冒泡

<div id="example-1">
 {{ sayContent }}
     <div v-on:click="doThis">點擊試試<span v-on:click.stop="sayhi">hi...</span></div>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    sayContent : ''
  },
  methods : {
   doThis : function(){
    alert(1);
    this.sayContent = 'hi';
   },
   sayhi : function(){
    alert('hi');
   }
  }
});
</script>

.self
只當事件在該元素本身(比如不是子元素)觸發時觸發回調

<div id="example-1">
 {{ sayContent }}
     <div v-on:click.self="doThis">點擊試試<span>hi...</span></div>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    sayContent : ''
  },
  methods : {
   doThis : function(){
    alert(1);
    this.sayContent = 'hi';
   }
  }
});
</script>

.once
只執行一次

<div id="example-1">
 {{ sayContent }}
    <div v-on:click.once="doThis">點擊試試</div>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    sayContent : ''
  },
  methods : {
   doThis : function(){
    alert(1);
    this.sayContent = 'hi';
   }
  }
});
</script>

鍵值修飾符

在監聽鍵盤事件時,我們經常需要監測常見的鍵值。 Vue 允許為 v-on 在監聽鍵盤事件時添加關鍵修飾符:

<!-- 只有在 keyCode 是 13 時調用 vm.submit() -->

<input v-on:keyup.13="submit">

記住所有的 keyCode 比較困難,所以 Vue 為最常用的按鍵提供了別名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">

<!-- 縮寫語法 -->
<input @keyup.enter="submit">

全部的按鍵別名:

.enter
.tab

.delete (捕獲 “刪除” 和 “退格” 鍵)
.esc
.space
.up
.down
.left
.right

表單控件

表單控件綁定基礎用法

可以用 v-model 指令在表單控件元素上創建雙向數據綁定。它會根據控件類型自動選取正確的方法來更新元素。盡管有些神奇,但 v-model 本質上不過是語法糖,它負責監聽用戶的輸入事件以更新數據,并特別處理一些極端的例子。
v-model 會忽略所有表單元素的 value、checked、selected 特性的初始值。因為它會選擇 Vue 實例數據來作為具體的值。你應該通過 JavaScript 在組件的 data 選項中聲明初始值。
對于要求 IME (如中文、 日語、 韓語等) (IME意為’輸入法’)的語言,你會發現v-model不會在 ime 輸入中得到更新。如果你也想實現更新,請使用 input事件

文本

<div id="example-1">
    <input v-model="message" placeholder="edit me">
    <p>Message is: {{ message }}</p>
</div>

<script type="text/javascript">
    var example1 = new Vue({
      el: '#example-1',
         data: {
         message : ''
         }
    });
</script>

復選樞

<div id="example-1">
     <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
     <label for="jack">Jack</label>
     <input type="checkbox" id="john" value="John" v-model="checkedNames">
     <label for="john">John</label>
     <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
     <label for="mike">Mike</label>
     <br>
     <span>Checked names: {{ checkedNames }}</span>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    checkedNames : []
  }
});
</script>

單選框

<div id="example-1">
     <input type="radio" id="one" value="One" v-model="picked">
     <label for="one">One</label>
     <br>
     <input type="radio" id="two" value="Two" v-model="picked">
     <label for="two">Two</label>
     <br>
     <span>Picked: {{ picked }}</span>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    picked : ''
  }
});
</script>

選擇列表

<div id="example-1">
     <select v-model="selected">
          <option disabled value="">請選擇</option>
          <option>A</option>
          <option>B</option>
          <option>C</option>
     </select>
     <span>Selected: {{ selected }}</span>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
    selected : ''
  }
});
</script>

表單修飾符

.lazy
在默認情況下, v-model 在 input 事件中同步輸入框的值與數據 (除了 上述 IME 部分),但你可以添加一個修飾符 lazy ,從而轉變為在 change 事件中同步:

<div id="example-1">
    <input type="text" name="test" v-model.lazy="val" />
     <span>val: {{ val }}</span>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
   val : ''
  }
});
</script>

.number
將用戶的輸入值轉為 Number 類型(如果原值的轉換結果為 NaN 則返回原值)。

<div id="example-1">
     <input type="text" name="test" v-model.lazy.number="val" />
     <span>val: {{ val }}</span>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
   val : ''
  }
});
</script>

.trim
自動過濾用戶輸入的首尾空格

<div id="example-1">
    <input type="text" name="test" v-model.trim="val" />
     <span>val: {{ val }}</span>
</div>

<script type="text/javascript">
var example1 = new Vue({
  el: '#example-1',
  data: {
   val : ''
  }
});
</script>

組件

什么是組件?

組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。在有些情況下,組件也可以是原生 HTML 元素的形式,以 is 特性擴展。

使用組件

<div id="example">
    <!-- 使用組件 -->
    <c-say></c-say>
</div>

<script type="text/javascript">
//1、創建組件
Vue.component('c-say', {
 template : '<h1>say....</h1>'
});

//2、實例化 Vue
var vm = new Vue({
 el: '#example'
});
</script>

運行結果

say...

局部注冊
不必在全局注冊每個組件。通過使用組件實例選項注冊,可以使組件僅在另一個實例/組件的作用域中可用:

<div id="example">
     <c-say></c-say>
</div>

<script type="text/javascript">
//創建組件
var vm = new Vue({
 el: '#example',
 components : {
  'c-say' : {
   template : '<h1>say....</h1>'
  }
 }
});
</script>

data 必須是函數
通過 Vue 構造器傳入的各種選項大多數都可以在組件里用。data 是一個例外,它必須是函數。實際上,如果你這么做:

<div id="example">
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
</div>

<script type="text/javascript">
//創建組件
Vue.component('simple-counter', {
   template: '<button v-on:click="counter += 1">{{ counter }}</button>',
 data: {
     message: 'hello'
 }
})
new Vue({
  el: '#example'
})
</script>

那么 Vue 會停止,并在控制臺發出警告,告訴你在組件中 data 必須是一個函數。理解這種規則的存在意義很有幫助,讓我們假設用如下方式來繞開 Vue 的警告:

<div id="example">
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
  <simple-counter></simple-counter>
</div>

<script type="text/javascript">
//創建組件
Vue.component('simple-counter', {
   template: '<button v-on:click="counter += 1">{{ counter }}</button>',
 data: function(){
  return {counter : 0};
 }
})
new Vue({
  el: '#example'
})
</script>

DOM 模版解析說明

當使用 DOM 作為模版時 (例如,將 el 選項掛載到一個已存在的元素上), 你會受到 HTML 的一些限制,因為 Vue 只有在瀏覽器解析和標準化 HTML 后才能獲取模版內容。尤其像這些元素 <ul>,<ol>,<table>,<select> 限制了能被它包裹的元素,而一些像 <option> 這樣的元素只能出現在某些其它元素內部。
在自定義組件中使用這些受限制的元素時會導致一些問題,例如:

<table>
  <my-row>...</my-row>
</table>

自定義組件 <my-row> 被認為是無效的內容,因此在渲染的時候會導致錯誤。變通的方案是使用特殊的 is 屬性:

<div id="example">
  <table>
   <tr is="my-row"></tr>
 </table>
</div>

<script type="text/javascript">
//創建組件
Vue.component('my-row', {
 template: '<tr><td>hi..</td></tr>'
});
var vm = new Vue({
 el : '#example'
});
</script>

Prop 傳遞數據

組件實例的作用域是孤立的。這意味著不能 (也不應該) 在子組件的模板內直接引用父組件的數據。要讓子組件使用父組件的數據,我們需要通過子組件的 props 選項。
子組件要顯式地用 props 選項聲明它期待獲得的數據

<div id="example">
  <child my-message="hi...."></child>
</div>

<script type="text/javascript">
//創建組件
Vue.component('child', {
  // camelCase in JavaScript
  props: ['myMessage'],
  template: '<span>{{ myMessage }}</span>'
})
var vm = new Vue({el : '#example'});
</script>

注:

HTML 特性是不區分大小寫的。所以,當使用的不是字符串模版,camelCased (駝峰式) 命名的 prop 需要轉換為相對應的 kebab-case (短橫線隔開式)

動態 Prop

在模板中,要動態地綁定父組件的數據到子模板的 props,與綁定到任何普通的HTML特性相類似,就是用 v-bind。每當父組件的數據變化時,該變化也會傳導給子組件:

<div id="app">
    <mytmp :message="msg"></mytmp>
</div>

<script type="text/javascript" src="vue.js" charset="UTF-8"></script>
<script type="text/javascript">
Vue.component('mytmp', {
 props: ['message'],
 template: '<p>{{ message }}</p>'
});
var vue = new Vue({
 el : "#app",
 data : {
  msg : 'i am message...'
 }
});
</script>

字面量語法 vs 動態語法

初學者常犯的一個錯誤是使用字面量語法傳遞數值:

<!-- 傳遞了一個字符串 "1" -->
<comp some-prop="1"></comp>

因為它是一個字面 prop,它的值是字符串 "1" 而不是 number。如果想傳遞一個實際的 number,需要使用 v-bind,從而讓它的值被當作 JavaScript 表達式計算:

<!-- 傳遞實際的 number -->
<comp v-bind:some-prop="1"></comp>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容