前言
記錄平時學到的知識,標題寫的大氣一點,也算是給自己一點鼓勵,希望在技術這條路可以遠走越遠,路越走越寬~
PS:如果對你有一點幫助,請順手給個小星星哦,鼓勵我繼續寫下去~
引入的文件文件說明
vue.js——開發版本:包含完整的警告和調試模式 vue.min.js——生產版本:刪除了警告,進行了壓縮
1. propsData Option 全局擴展的數據傳遞
propsData在實際開發中使用的並不多,用在全局擴展時進行傳遞數據,主要搭配Vue.extend使用。
在實際的項目中,使用全局擴展的方式製作自定義標籤比較少用,完全可以使用組件來替代。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>propsData Option</title> </head> <body> <h1>propsData Option</h1> <hr> <div id="app"></div> <script type="text/javascript"> var header_a = Vue.extend({ template:`<p>{{message}}</p>`, data:function(){ return { message:'Hello,I am Header' } } }); new header_a().$mount('#app'); </script> </body> </html>
擴展標籤已經做好了,這時要在掛載時傳遞數據,就用到了propsData。
使用用propsData三步解決傳值:
- 在全局擴展里加入props進行接收;
- 傳遞時用propsData進行傳遞;
- 用插值的形式寫入模板;
完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>propsData Option</title> </head> <body> <h1>propsData Option</h1> <hr> <div id="app"></div> <script type="text/javascript"> var header_a = Vue.extend({ template:`<p>{{message}}-{{a}}</p>`, data:function(){ return { message:'Hello,I am Header' } }, props:['a'] }); new header_a({propsData:{a:1}}).$mount('header'); </script> </body> </html>
2.computed Option 計算選項
computed計算屬性的主要作用是在數據渲染之前,根據實際需求對數據進行處理,比如:大小寫轉換,順序重排,添加符號……。爲了不污染data中定義的數據源,在computed裏需要新聲明一個對象保存處理之後的數據。
computed計算屬性的所有getter和setter的this上下文自動地綁定爲 Vue 實例。注意如果你爲一個計算屬性使用了箭頭函數,則 this 不會指向這個組件的實例,不過你仍然可以將其實例作爲函數的第一個參數來訪問。
computed: { aDouble: vm => vm.a * 2 }
計算屬性的結果會被緩存,除非依賴的響應式屬性變化纔會重新計算。注意,如果某個依賴 (比如非響應式屬性) 在該實例範疇之外,則計算屬性是不會被更新的。
用計算屬性反轉新聞數據數組,讓最近發生的新聞放在前面顯示,demo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>computed 計算選項</title> </head> <body> <h1>computed 計算選項</h1> <hr> <div id="app"> {{newPrice}} <br> <br> <ul> <li v-for="item in reverseNews">{{item.title}} - {{item.date}}</li> </ul> </div> <script type="text/javascript"> var newsList = [ {title:'香港或就“裝甲車被扣”事件追責 起訴涉事運輸公司',date:'2017/3/10'}, {title:'日本第二大準航母服役 外媒:針對中國潛艇',date:'2017/3/12'}, {title:'中國北方將有明顯雨雪降溫天氣 南方陰雨持續',date:'2017/3/13'}, {title:'起底“最短命副市長”:不到40天落馬,全家被查',date:'2017/3/23'}, ]; var app=new Vue({ el:'#app', data:{ price:100, newsList: newsList }, computed:{ newPrice:function(){ return this.price='¥' + this.price + '元'; }, reverseNews:function(){ return this.newsList.reverse(); } } }) </script> </body> </html>
computed 計算屬性是非常有用並且在實際的項目開發中經常使用,它在輸出數據前可以根據實際項目需求對數據進行處理,改變數據。
3. methods Option 方法選項
在Vue中,可以使用v-on給元素綁定事件,在methods選項中處理一些邏輯方面的事情。在Vue中的邏輯處理,一般都在Vue的methods選項中來處理,那是因爲很多事件處理邏輯代碼都很複雜,如果直接把JavaScript代碼寫在v-on指令中有時並不可行,所以在methods中定義方法,讓v-on指令來接收(調用)。
一個數字,每點擊一下按鈕加2:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>methods Option</title> <script type="text/javascript" src="../assets/js/vue.js"></script> </head> <body> <h1>methods Option</h1> <hr> <div id="app"> {{ a }} <p><button @click="add">add</button></p> </div> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ a:1 }, methods:{ add () { this.a++ } } }) </script> </body> </html>
methods中參數的傳遞:
使用方法和正常的javascript傳遞參數的方法一樣,分爲兩步:
- 在methods的方法中進行聲明,比如給add方法傳入一個num參數,就要寫出add (num){...};
- 調用方法時直接傳遞,比如要傳遞2這個參數,在button上就直接可以寫。
<button @click=”add(2)”></button>
;
給add添加num參數,並在按鈕上調用傳遞:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>methods Option</title> <script type="text/javascript" src="../assets/js/vue.js"></script> </head> <body> <h1>methods Option</h1> <hr> <div id="app"> {{ a }} <p><button @click="add(2)">add</button></p> </div> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ a:1 }, methods:{ add (num) { this.a += num } } }) </script> </body> </html>
這時,再點擊按鈕時結果每次加2。
methods中的$event參數:
傳遞的$event參數都是關於你點擊鼠標的一些事件和屬性。傳遞方法:
<button @click=”add(2,$event)”>add</button> 。
這時候可以打印一下,看看event到底是個怎樣的對象。你會發現,它包含了大部分鼠標事件的屬性:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>methods Option</title> <script type="text/javascript" src="../assets/js/vue.js"></script> </head> <body> <h1>methods Option</h1> <hr> <div id="app"> {{ a }} <p><button @click="add(2,'每次加2', $event)">add</button></p> </div> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ a:1 }, methods:{ add (num, msg, event) { console.log('num==>', num) console.log('msg==>', msg) console.log('event==>', event) this.a += num } } }) </script> </body>
native 給組件綁定構造器裏的原生事件:
在實際開發中經常需要把某個按鈕封裝成組件,然後反覆使用,如何讓組件調用構造器裏的方法,而不是組件裏的方法。就需要用到.native修飾器了。
把我們的add按鈕封裝成組件,聲明btn對象:
var btn={ template:`<button>組件Add</button>` }
在構造器裏註冊組件:
components:{ "btn":btn }
用.native修飾器來調用構造器裏的add方法:
<p><btn @click.native="add(3)"></btn></p>
完整代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>methods Option</title> <script type="text/javascript" src="../assets/js/vue.js"></script> </head> <body> <h1>methods Option</h1> <hr> <div id="app"> {{a}} <p><button @click="add(2, '每次加2', $event)">add</button></p> <p><btn @click.native="add(3, '每次加3', $event)"></btn></p> </div> <script type="text/javascript"> var btn={ template:'<button>外部組件</button>' } var app=new Vue({ el:'#app', data:{ a:1 }, methods:{ add (num, msg, event) { console.log('num==>', num) console.log('msg==>', msg) console.log('event==>', event) this.a += num } }, components:{ "btn":btn } }) </script> </body> </html>
作用域外部調用構造器裏的方法:
這種不經常使用,如果你出現了這種情況,說明你的代碼組織不夠好。
<button onclick="app.add(4)" >外部調用構造器裏的方法</button>
完整代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>methods Option</title> <script type="text/javascript" src="../assets/js/vue.js"></script> </head> <body> <h1>methods Option</h1> <hr> <div id="app"> {{a}} <p><button @click="add(2, '每次加2', $event)">add</button></p> <p><btn @click.native="add(3, '每次加3', $event)"></btn></p> </div> <button onclick="app.add(4, '每次加4')">外部訪問構造器裏的方法</button> <script type="text/javascript"> var btn={ template:'<button>外部組件</button>' } var app=new Vue({ el:'#app', data:{ a:1 }, methods:{ add (num, msg, event) { console.log('num==>', num) console.log('msg==>', msg) console.log('event==>', event) this.a += num } }, components:{ "btn":btn } }) </script> </body> </html>
4. Watch 選項 監控數據
使用watch選項來監控數據的變化。watch選項對應一個對象,鍵是觀察表達式,值是對應回調。值也可以是方法名,或者是對象,包含選項。在實例化時爲每個鍵調用 $watch() 。
天氣預報的穿衣指數,它主要是根據溫度來進行提示,溫度大於26度時,建議穿T恤短袖,溫度小於26度大於0度時,建議穿夾克長裙,溫度小於0度時建議穿棉衣羽絨服:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>watch Option</title> </head> <body> <h1>watch Option</h1> <hr> <div id="app"> <p>今日溫度:{{temperature}}°C</p> <p>穿衣建議:{{suggestion}}</p> <p> <button @click="add">添加溫度</button> <button @click="reduce">減少溫度</button> </p> </div> <script type="text/javascript"> var suggestion=['T恤短袖','夾克長裙','棉衣羽絨服']; var app=new Vue({ el:'#app', data:{ temperature:14, suggestion:'夾克長裙' }, methods:{ add:function(){ this.temperature+=5; }, reduce:function(){ this.temperature-=5; } }, watch:{ temperature (newVal,oldVal) { if(newVal>=26){ this.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.suggestion=suggestion[1]; }else{ this.suggestion=suggestion[2]; } } } }) </script> </body> </html>
handler方法和immediate屬性:
這裏 watch 的一個特點是,最初綁定的時候是不會執行的,要等到 temperature 改變時才執行監聽計算。那我們想要一開始就讓它最初綁定的時候就執行改怎麼辦呢?我們需要修改一下我們的 watch 寫法,修改過後的 watch 代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>watch Option</title> </head> <body> <h1>watch Option</h1> <hr> <div id="app"> <p>今日溫度:{{temperature}}°C</p> <p>穿衣建議:{{suggestion}}</p> <p> <button @click="add">添加溫度</button> <button @click="reduce">減少溫度</button> </p> </div> <script type="text/javascript"> var suggestion=['T恤短袖','夾克長裙','棉衣羽絨服']; var app=new Vue({ el:'#app', data:{ temperature:14, suggestion:'T恤短袖' }, methods:{ add:function(){ this.temperature+=5; }, reduce:function(){ this.temperature-=5; } }, watch:{ temperature: { handler (newVal,oldVal) { if(newVal>=26){ this.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.suggestion=suggestion[1]; }else{ this.suggestion=suggestion[2]; } }, // 代表在wacth裏聲明瞭temperature這個方法之後立即先去執行handler方法 immediate: true } } }) </script> </body> </html>
注意到handler了嗎,我們給 temperature 綁定了一個handler方法,之前我們寫的 watch 方法其實默認寫的就是這個handler,Vue.js會去處理這個邏輯,最終編譯出來其實就是這個handler。
而immediate:true代表如果在 wacth 裏聲明瞭 temperature 之後,就會立即先去執行裏面的handler方法,如果爲 false就跟我們以前的效果一樣,不會在綁定的時候就執行。
在上面的事例中把suggestion
的初始數據設置爲'T恤短袖',而初始溫度是14°C,這時如果沒有讓watch在最初綁定的時候就執行,那麼推薦的穿衣就有問題,因爲14°C原本是推薦穿'夾克長裙'的,通過讓watch在最初綁定的時候就執行完美解決了這個問題。
deep屬性: watch 裏面還有一個屬性 deep,默認值是 false,代表是否深度監聽,比如我們 data 裏有一個obj屬性:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>watch Option</title> </head> <body> <h1>watch Option</h1> <hr> <div id="app"> <p>今日溫度:{{obj.temperature}}°C</p> <p>穿衣建議:{{obj.suggestion}}</p> <p> <button @click="add">添加溫度</button> <button @click="reduce">減少溫度</button> </p> </div> <script type="text/javascript"> var suggestion=['T恤短袖','夾克長裙','棉衣羽絨服']; var app=new Vue({ el:'#app', data: { obj: { temperature: 14, suggestion:'T恤短袖' } }, methods:{ add:function(){ this.obj.temperature+=5; }, reduce:function(){ this.obj.temperature-=5; } }, watch: { obj: { handler(newVal, oldVal) { console.log('obj.a changed', newVal.temperature) if(newVal.temperature>=26){ this.obj.suggestion=suggestion[0]; }else if(newVal.temperature<26 && newVal.temperature >=0) { this.obj.suggestion=suggestion[1]; }else{ this.obj.suggestion=suggestion[2]; } console.log('obj.a 2', newVal.suggestion) }, immediate: true } } }) </script> </body> </html>
當我們在點擊添加溫度和減少溫度按鈕改變obj.temperature的值時,發現是無效的。受現代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測到對象屬性的添加或刪除。由於 Vue 會在初始化實例時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。
默認情況下 handler 只監聽obj這個屬性它的引用的變化,我們只有給obj賦值的時候它纔會監聽到,比如我們在 mounted事件鉤子函數中對obj進行重新賦值:
mounted: { this.obj = { temperature: 40, suggestion:'T恤短袖' } }
這樣我們的 handler 纔會執行。
如果需要監聽obj裏的屬性temperature的值,這時候deep屬性就派上用場了:
watch: { obj: { handler(newVal, oldVal) { console.log('obj.a changed', newVal.temperature) if(newVal.temperature>=26){ this.obj.suggestion=suggestion[0]; }else if(newVal.temperature<26 && newVal.temperature >=0) { this.obj.suggestion=suggestion[1]; }else{ this.obj.suggestion=suggestion[2]; } console.log('obj.a 2', newVal.suggestion) }, immediate: true, deep: true } }
deep的意思就是深入觀察,監聽器會一層層的往下遍歷,給對象的所有屬性都加上這個監聽器,但是這樣性能開銷就會非常大了,任何修改obj裏面任何一個屬性都會觸發這個監聽器裏的 handler。
優化,可以使用字符串形式監聽:
watch: { 'obj.temperature': { handler(newVal, oldVal) { console.log('obj.a changed', newVal) if(newVal>=26){ this.obj.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.obj.suggestion=suggestion[1]; }else{ this.obj.suggestion=suggestion[2]; } console.log('obj.a 2', this.obj.suggestion) }, immediate: true, deep: true } }
這樣Vue.js纔會一層一層解析下去,直到遇到屬性temperature,然後纔給temperature設置監聽函數。
完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>watch Option</title> </head> <body> <h1>watch Option</h1> <hr> <div id="app"> <p>今日溫度:{{obj.temperature}}°C</p> <p>穿衣建議:{{obj.suggestion}}</p> <p> <button @click="add">添加溫度</button> <button @click="reduce">減少溫度</button> </p> </div> <script type="text/javascript"> var suggestion=['T恤短袖','夾克長裙','棉衣羽絨服']; var app=new Vue({ el:'#app', data: { obj: { temperature: 14, suggestion:'T恤短袖' } }, methods:{ add:function(){ this.obj.temperature+=5; }, reduce:function(){ this.obj.temperature-=5; } }, // watch: { // obj: { // handler(newVal, oldVal) { // console.log('obj.a changed', newVal.temperature) // if(newVal.temperature>=26){ // this.obj.suggestion=suggestion[0]; // }else if(newVal.temperature<26 && newVal.temperature >=0) // { // this.obj.suggestion=suggestion[1]; // }else{ // this.obj.suggestion=suggestion[2]; // } // console.log('obj.a 2', newVal.suggestion) // }, // immediate: true, // deep: true // } // } //優化使用字符串形式監聽 watch: { 'obj.temperature': { handler(newVal, oldVal) { console.log('obj.a changed', newVal) if(newVal>=26){ this.obj.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.obj.suggestion=suggestion[1]; }else{ this.obj.suggestion=suggestion[2]; } console.log('obj.a 2', this.obj.suggestion) }, immediate: true, deep: true } } }) </script> </body> </html>
用實例屬性寫watch監控:
有些時候我們會用實例屬性的形式來寫watch監控。也就是把我們watch卸載構造器的外部,這樣的好處就是降低我們程序的耦合度,使程序變的靈活:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>watch Option</title> </head> <body> <h1>watch Option</h1> <hr> <div id="app"> <p>今日溫度:{{temperature}}°C</p> <p>穿衣建議:{{suggestion}}</p> <p> <button @click="add">添加溫度</button> <button @click="reduce">減少溫度</button> </p> </div> <script type="text/javascript"> var suggestion=['T恤短袖','夾克長裙','棉衣羽絨服']; var app=new Vue({ el:'#app', data:{ temperature:14, suggestion:'夾克長裙' }, methods:{ add:function(){ this.temperature+=5; }, reduce:function(){ this.temperature-=5; } } }) app.$watch('temperature',function(newVal,oldVal){ if(newVal>=26){ this.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.suggestion=suggestion[1]; }else{ this.suggestion=suggestion[2]; } }) </script> </body> </html>
註銷watch:
爲什麼要註銷 watch?因爲我們的組件是經常要被銷燬的,比如我們跳一個路由,從一個頁面跳到另外一個頁面,那麼原來的頁面的 watch 其實就沒用了,這時候我們應該註銷掉原來頁面的 watch 的,不然的話可能會導致內置溢出。當把 watch 寫在組件的選項中的,它會隨着組件的銷燬而銷燬。
但是,如果我們使用上面的這樣的方式寫 watch:
app.$watch('temperature',function(newVal,oldVal){ if(newVal>=26){ this.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.suggestion=suggestion[1]; }else{ this.suggestion=suggestion[2]; } })
那麼就要手動註銷了,這種註銷其實也很簡單:
var unwatch = app.$watch('temperature',function(newVal,oldVal){ if(newVal>=26){ this.suggestion=suggestion[0]; }else if(newVal<26 && newVal >=0) { this.suggestion=suggestion[1]; }else{ this.suggestion=suggestion[2]; } }) unWatch(); // 手動註銷watch
app.$watch調用後會返回一個值,就是unWatch方法,你要註銷 watch 只要調用unWatch方法就可以了。
5. mixins 混入選項
混入 (mixins) 是一種分發 Vue 組件中可複用功能的非常靈活的方式。混入對象可以包含任意組件選項。當組件使用混入對象時,所有混入對象的選項將被混入該組件本身的選項。
mixins一般有兩種用途:
- 在你已經寫好了構造器後,需要增加方法或者臨時的活動時使用的方法,這時用混入會減少源代碼的污染。
- 很多地方都會用到的公用方法,用混入的方法可以減少代碼量,實現代碼重用。
現在有個數字點擊遞增的程序,假設已經完成了,這時希望每次數據變化時都能夠在控制檯打印出提示:“數據發生變化”:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>Mixins Option</title> </head> <body> <h1>Mixins Option Demo</h1> <hr> <div id="app"> <p>num: {{ num }}</p> <P><button @click="add">增加數量</button></P> </div> <script type="text/javascript"> //額外臨時加入,用於顯示日誌 var addLog={ updated:function(){ console.log("數據放生變化,變化成"+this.num+"."); } } var app=new Vue({ el:'#app', data:{ num:1 }, methods:{ add:function(){ this.num++; } }, //混入 mixins:[addLog] }) </script> </body> </html>
選項合併:
當組件和混入對象含有同名選項時,這些選項將以恰當的方式混合,合併規則:
- 值爲對象的選項,例如數據對象data、方法對象methods、組件對象components和自定義指令對象directives,將被混合爲同一個對象。兩個對象鍵名衝突時,取組件對象的鍵值對。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>Mixins Option</title> </head> <body> <h1>Mixins Option Demo</h1> <hr> <div id="app"> <p>num: {{ num }}</p> <P><button @click="add">增加數量</button></P> </div> <script type="text/javascript"> //額外臨時加入,用於顯示日誌 var addLog={ data: function () { return { message: 'hello', foo: 'abc' } }, updated () { console.log("數據放生變化,變化成"+this.num+"."); }, created () { console.log('混入對象的鉤子被調用==>', this.$data) } } var app=new Vue({ el:'#app', data:{ num:1, message: 'goodbye', bar: 'def' }, methods:{ add:function(){ this.num++; } }, created () { console.log('實例鉤子被調用==>', this.$data) }, //混入 mixins:[addLog] }) </script> </body> </html>
打開控制檯可以看到,混入的created鉤子函數和實例的created鉤子函數打印出的this.$data都爲{bar: "def", foo: "abc", message: "goodbye", num: 1}
。
- 由1的例子可以看出,同名鉤子函數將混合爲一個數組,因此都將被調用。另外,混入對象的鉤子將在組件自身鉤子之前調用。
mixins的調用順序:
從執行的先後順序來說,都是混入的先執行,然後構造器裏的再執行,需要注意的是,這並不是方法的覆蓋,而是被執行了兩邊。
同名鉤子函數將混合爲一個數組,因此都將被調用。混入對象的鉤子將在組件自身鉤子之前調用。
全局API混入方式:
可以全局註冊混入對象。但應注意使用!因爲一旦使用全局混入對象,將會影響到所有之後創建的 Vue 實例。
定義全局的混入,然後在需要這段代碼的地方直接引入js,就可以擁有這個功能了:
Vue.mixin({ updated:function(){ console.log('我是全局被混入的'); } })
注意:全局混入的執行順序要前於混入和構造器裏的方法。
完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>Mixins Option</title> </head> <body> <h1>Mixins Option Demo</h1> <hr> <div id="app"> <p>num: {{ num }}</p> <P><button @click="add">增加數量</button></P> </div> <script type="text/javascript"> //全局混入 Vue.mixin({ created () { console.log('我是全局混入'); } }) //額外臨時加入,用於顯示日誌 var addLog={ data: function () { return { message: 'hello', foo: 'abc' } }, updated () { console.log("數據放生變化,變化成"+this.num+"."); }, created () { console.log('混入對象的鉤子被調用==>', this.$data) } } var app=new Vue({ el:'#app', data:{ num:1, message: 'goodbye', bar: 'def' }, methods:{ add:function(){ this.num++; } }, created () { console.log('實例鉤子被調用==>', this.$data) }, //混入 mixins:[addLog] }) </script> </body> </html>
6. extends Option 擴展選項
通過外部增加對象的形式,對構造器進行擴展。允許聲明擴展另一個組件(可以是一個簡單的選項對象或構造函數),而無需使用 Vue.extend。這主要是爲了便於擴展單文件組件。和 mixins 類似。
選項合併:
當組件和擴展對象含有同名選項時,這些選項將以恰當的方式混合,合併規則:
- 值爲對象的選項,例如數據對象data、方法對象methods、組件對象components和自定義指令對象directives,將被混合爲同一個對象。兩個對象鍵名衝突時,取組件對象的鍵值對。
- 同名鉤子函數將混合爲一個數組,因此都將被調用。另外,擴展對象的鉤子將在組件自身鉤子之前調用。
完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Extends Optin</title> <script type="text/javascript" src="../assets/js/vue.js"></script> </head> <body> <h1>Extends Optin Demo</h1> <hr> <div id="app"> {{message}} <p><button @click="add">add</button></p> </div> <script type="text/javascript"> var bbb={ created () { console.log("我是擴展出來的鉤子函數"); }, methods:{ add () { console.log('我是被擴展出來的方法!'); } } }; var app=new Vue({ el:'#app', data:{ message:'hello Vue!' }, methods:{ add () { console.log('我是原生方法'); } }, created () { console.log("我是原生的鉤子函數"); }, extends:bbb }) </script> </body> </html>
打開控制檯可以看到,擴展出來的鉤子函數先執行,然後是實例的鉤子函數;點擊按鈕之後只有實例的方法被執行。
7. delimiters 選項
delimiters的作用是改變插值的符號。Vue默認的插值是雙大括號{{}}。但有時我們會有需求更改這個插值的形式。
比如後臺渲染模板如swig,也使用“{{ }}“作爲渲染,與前端vue的數據綁定“Mustache”語法 (雙大括號)產生衝突,此時只要在新建Vue對象時,添加delimiters: ['${', '}'],就搞定了。
現在插值形式就變成了${}。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript" src="../assets/js/vue.js"></script> <title>delimiters Option</title> </head> <body> <h1>delimiters Option</h1> <hr> <div id="app"> <ul> <li v-for=" aa in arr">${aa}</li> </ul> </div> <script type="text/javascript"> var outData={ arr:['aaa','bbb','ccc'], }; var app=new Vue({ delimiters: ['${', '}'], el: '#app', data: outData }) </script> </body> </html>