Hello Vue!
關鍵詞:模板語法、聲明式javascript
這裏有個小bug,JSFiddle Hello World例子中,並無爲new Vue賦值變量,因而教程中接下來講的,「修改app.message」就無法實現,認真看教程中代碼能夠看到它爲其賦值命名爲app,下一個例子命名爲app-2,命名後就能夠在控制檯採用「名稱.屬性」的形式訪問修改內容了。php
新指令:v-bind
用法:css
新指令:v-if
用法:根據值的真假決定是否渲染DOM內容
原理:Vue能夠綁定DOM結構到數據html
新指令:v-for
用法:vue
原理:v-for是一個包裝過的for in循環,對應的data內須要有一個數組java
新指令:v-on
用法:python
新指令:v-model
用法:webpack
原理:v-model可實現表單輸入和應用狀態的雙向綁定,修改表單內容,message對應值也會修改。git
Vue.component('todo-item',{ template:'<li>這是一個待辦項</li>' })
<ol>
<todo-item></todo-item> </ol>
可是這樣實現,會爲每一個元素綁定相同文本,Vue能夠將數據從父做用域傳到子組件。web
Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' })
<div id="app-7"> <ol> <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item> </ol> </div>
var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { text: '蔬菜' }, { text: '奶酪' }, { text: '隨便其餘什麼人吃的東西' } ] } })
vm.$el===document.getElementById('exzample');
<span>Message:{{ msg}}</span>
也能夠經過v-once執行一次性插值,再也不更新內容,可是這會影響這個節點的全部數據綁定
<span v-once>This will never change:{{message}}</span>
<div id="app-8" v-html='rawHtml'> </div> var app8=new Vue({ el:'#app-8', data:{ rawHtml:'<li>純html</li>' } }) //輸出:● 純html
可是要注意只對可信內容使用html插值,否則容易致使xss攻擊
<div id="app-2"> <span v-bind:title="message">懸停幾秒看信息</span> </div>
{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div>
然而,語句和流控制是不行滴,三元表達式是能夠的
{{var a = 1 }} {{if(ok){return message}}}
<form v-on:submit.prevent="onSubmit"></form>
<div id="app-9">{{message|format}}</div> var app9=new Vue({ el:'#app-9', data:{ message:'hello,Filters!' }, filters:{ format:function(value){ value=value.toLowerCase() return value.charAt(0).toUpperCase()+value.slice(1) } } })
過濾器能夠串聯,能夠接受參數
<a v-bind:href="url"></a> <a :href="url"></a>
v-on縮寫爲@,並省略了後面的冒號
<a v-on:click="doSomething"></a> <a @click="doSomething></a>
var app11=new Vue({ el:'#app-11', data:{ firstName:'Foo', lastName:'Bar' }, computed:{ fullName:{ get:function(){ return this.firstName+' '+this.lastName }, set:function(newValue){ var names = newValue.split(' ') this.firstName=names[0] this.lastName=names[names.length-1] } } } })
對class的加強綁定:
<div id="app-01" v-bind:class="{active:isActive}"></div> var app01=new Vue({ el:'#app-01', data:{ isActive:true } }) //div class="active"
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div>
<div id="app-02" v-bind:class='classObject'></div> var app02=new Vue({ el:'#app-02', data:{ classObject:{ active:true, 'text-danger':false } } })
computed: {
classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal', } } }
總結:只要冒號後的數據形式爲‘名稱:布爾值’就能夠
<div v-bind:class="[activeClass, errorClass]"> data: { activeClass: 'active', errorClass: 'text-danger' } <div v-bind:class="[{ active: isActive }, errorClass]">
<my-component v-bind:class="{ active: isActive }"></my-component>
和內置元素的使用差很少
對style樣式加強綁定:
因爲默認格式裏就包括一對引號,要注意單雙引號的區分,否則會出錯
<div id='app-03' v-bind:style='{color:activeColor,fontSize:fontSize + "px"}'> <p>1111</p> </div> var app03=new Vue({ el:'#app-03', data:{ activeColor:'red', fontSize:30 } })
<div id="app-04"> <p v-if="ok">Yes</p> <p v-else>No</p> </div> var app04=new Vue({ el:'#app-04', data:{ ok:false } })
<div id="app-04"> <template v-if="ok"> <h1>Title</h1> <p>Para</p> </template> <p v-else>No</p> </div>
<div id="app-05"> <template v-if="loginType==='username'"> <label for="">Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label for="">Email</label> <input placeholder="Enter your email address"> </template> <button v-on:click="toggle">Toggle login type</button> </div> var app05=new Vue({ el:'#app-05', data:{ loginType:'username' }, methods:{ toggle:function(){ this.loginType==='username'?this.loginType='email':this.loginType='username' } } })
不復用的以下:
<div id="app-05"> <template v-if="loginType==='username'"> <label>Username</label> <input placeholder="Enter your username" key="username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email"> </template> <button v-on:click="toggle">Toggle login type</button> </div>
<h1 v-show='ok'>222</h1>
v-show vs v-if
v-show適合頻繁切換,v-if適合條件不太改變的狀況
<ul id="app-06"> <li v-for="item in items">{{item.message}}</li> </ul> var app06=new Vue({ el:'#app-06', data:{ items:[ {message:'Foo'}, {message:'Bar'} ] } })
<ul id="app-06"> <li v-for="(item,index) in items">{{parentMessage}}-{{index}}-{{item.message}}</li> </ul>
<ul id="app-07"> <template v-for="(item,index) in items"> <span>組合列表{{index+1}}</span> <li>{{item.message}}</li> </template> </ul>
<ul id="app-08"> <li v-for="(item,key,index) in object"> {{item}}-{{key}}-{{index}} </li> </ul>
<ul id='app-09'> <li v-for="n in 10">{{n}}</li> </ul>
可是一樣須要創建Vue對象,
var app09=new Vue({ el:'#app-09' })
<ul id="app-10" > <li v-for="(item,index) in items" :key='item.id=index+3'>{{item.message}}-{{index}}-{{item.id}}</li> </ul>
這裏我綁了元素的index在id上
vm.items[indexOfItem] = newValue
Vue.set(example1.items,indexOfItem,newValue)
example1.items.splice(indexOfItem,1,newValue)
注意這裏的第二個參數爲"1",表示原地替換原元素
vm.items.length = newLength
可是依舊能夠用萬能的splice:
example1.items.splice(newLength) 第二個參數爲刪除個數,不填第二個參數時表示刪除到末尾
此處翻閱了犀牛書和高程,高程中沒提到splice()省略第二個參數的狀況,犀牛書提到了,省略第二個參數,從起始點到結尾的全部元素都將被刪除。查了ecma-262的文檔,原文是:
5 If the number of actual arguments is 0, then a. Let insertCount be 0. b. Let actualDeleteCount be 0. 6 Else if the number of actual arguments is 1, then a. Let insertCount be 0. b. Let actualDeleteCount be len ‑ actualStart.
<ul id="app-11"> <li v-for="n in evenNumbers">{{n}}</li> </ul> var app11=new Vue({ el:'#app-11', data:{ numbers:[1,2,3,4,5] }, computed:{ evenNumbers:function(){ return this.numbers.filter(function(number){ return number%2 === 0 }) } } })
<ul id="app-11"> <li v-for="n in evenNumbers(numbers)">{{n}}</li> </ul> var app11=new Vue({ el:'#app-11', data:{ numbers:[1,2,3,4,5] }, methods:{ evenNumbers:function(){ return this.numbers.filter(function(number){ return number%2 === 0 }) } } })
<div id="app-12"> <button v-on:click="counter+=1">增長1</button> <p>這個按鈕被點擊了{{counter}}次</p> </div> var app12=new Vue({ el:"#app-12", data:{ counter:0 } })
<div id="app-13"> <button v-on:click="say('hi')">1</button> <button v-on:click="say('what')">2</button> </div> var app13=new Vue({ el:'#app-13', data:{ message:'new event!' }, methods:{ say:function(m){ alert(m) } } })
<div id="app-14"> <button v-on:click="mod('event is modified',$event)">submit</button> </div> var app14=new Vue({ el:'#app-14', methods:{ mod:function(message,e){ if(e)e.preventDefault() alert(message) } } })
代碼中點擊button會觸發一個click事件,把event做爲參數傳入,就能夠對這個事件進行操做
<input type="text" id="app-1" v-on:keyup.13="submit()"> var app1=new Vue({ el:'#app-1', methods:{ submit:function(){ alert('success') } } })
keyup.13是"enter"
還有別名:
<input type="text" v-on:keyup.13="submit"> <input type="text" v-on:keyup.enter="submit"> <input type="text" @keyup.enter="submit">
Vue.config.keyCodes.f2=113
v-model本質上是語法糖,監聽輸入事件以更新數據
<div id="app-2"> <input type="text" v-model="message" placeholder="'edit me"> <p>Message is:{{message}}</p> </div> var app2=new Vue({ el:'#app-2', data:{ message:'' } })
多行文本同理
<div id="app-3"> <input type="checkbox" id="chechbox" v-model="checked"> <label for="checkbox">{{checked}}</label> </div> var app3=new Vue({ el:'#app-3', data:{ checked:false } })
這裏,checked預設值若是設爲空,則開始時label沒有內容,若是設爲true,則選框會默認選上,因此最好只設爲false
<div id="app-4"> <input type="checkbox" value="Jack" v-model="checkedNames" id="jack"> <label for="jack">jack</label> <input type="checkbox" value="John" v-model="checkedNames" id="john"> <label for="john">john</label> <input type="checkbox" value="Mike" v-model="checkedNames" id="mike" > <label for="mike">mike</label> <br> <span>checked names: {{ checkedNames }}</span> </div> var app4=new Vue({ el:'#app-4', data:{ checkedNames:[] } })
<div id="app-6"> <select name="" id="" v-model="selected"> <option>A</option> <option>B</option> <option>C</option> </select> <span>selected:{{selected}}</span> </div> var app06=new Vue({ el:'#app-6', data:{ selected:"" } })
此處遇到一小問題,創建option時,emmet的補全加了屬性value='',若是不改動的話,默認option的值是爲空的,選中無效,須要刪除這個屬性或者顯式填值
<div id="app-6"> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value">{{option.text}}</option> </select> <span>selected:{{selected}}</span> </div> var app06=new Vue({ el:'#app-6', data:{ selected:'A', options:[ {text:'One',value:'A'}, {text:'Two',value:'B'}, {text:'Tree',value:'C'} ] } })
此例子將選項內容與選項值區分紅兩組數據,而selected顯示的是value的內容,同上一個小問題相同,option不顯式設置值時,option標籤內容即爲值,顯式設置後,value值會覆蓋標籤內容被髮送。
<div id="app-7"> <input id="bindvalue" type="checkbox" v-model="toggle" v-bind:true-value="a" v-bind:false-value='b'> <label for="bindvalue">{{toggle}}</label> </div> var app07=new Vue({ el:'#app-7', data:{ toggle:'false', a:'true', b:'false' } })
例子中綁定了true-value到a變量,false-value到b變量
單選框同理:
<input type="radio" v-model='pick' v-bind:value="a">
<input v-model.lazy="msg">
<input v-model.number='age' type='number'>
這個例子玄機不少:
輸入字母e/E狀況特殊,會被理解爲指數標誌,不一樣設定效果不一樣:
1. 只設置type爲number:字母輸入無效;e後爲有效數字時會正常顯示,好比:
輸入:123abc456, 框內顯示爲:123456,值顯示爲123456 、、、 輸入:123e12, 框內顯示爲:123e12 值顯示爲:123e12
可是超過必定數值會顯示爲空:
(很大很大一個數字)顯示爲: 123e1234 值顯示爲:
然而負指數會正確顯示:
123e-1234 值顯示爲 123e-1234
2. 只設置v-model爲number時:
輸入:123abc456, 框內顯示爲123abc456,失去焦點時更新爲123, 值顯示爲123 、、、 輸入:abc123, 框內顯示爲abc123,失去焦點沒變化, 值顯示爲abc123,說明斷定失效啦 、、、 123e12 值顯示爲:123000000000000 ——同時輸入框內會被更新成123000000000000
指數e超過必定數值會顯示爲Infinity
123e1234值顯示爲:Infinity ——同時輸入框內會被更新成Infinity
在一個範圍內的負指數會被格式化後顯示,
超過必定值的負指數會被顯示爲0:
123e-123 值顯示爲:1.23e-121 123e-1234 值顯示爲:0 ——同時輸入框內會被更新
3. 設置type爲number而且v-model爲number時:
輸入123abc456, 框內顯示爲:123456,值顯示爲123456 、、、 輸入abc123, 框內顯示爲:123,值顯示爲123 、、、 123e12 值顯示爲:123000000000000 ——同時輸入框內會被更新成123000000000000 指數大於20位會轉化成指數形式
超過必定數值顯示爲空:
123e1234 值顯示爲:
在一個範圍內的負指數會被格式化後顯示,
超過必定值的負指數會被顯示爲0:
123e-123 值顯示爲:1.23e-121 123e-1234 值顯示爲:0 ——同時輸入框內會被更新
總結:控制數字輸入的主要依賴type="number",v-model.number是將輸入值轉化爲Number類型,可是表現不太穩定。
空空abc空空def空空 ——> abc空空def
<div id="app-01"> <my-component></my-component> </div> Vue.component('my-component',{ template:'<div>A custom component!</div>' }) var app01=new Vue({ el:'#app-01' })
要確保,先註冊組件,再初始化實例,調換先後順序會出錯
<div id="app-01"> <my-component></my-component> </div> var app01=new Vue({ el:'#app-01', components:{ 'my-component':{ template:'<div>A custom component!</div>' } } })
注意此處至關於先實例再在實例中註冊組件,所以能夠判斷,註冊組件行爲不能落後於實例化,可是能夠包含在實例的同時進行。
<table>
<my-row>...</my-row> </table>
須要使用特殊的is屬性:
<table id="app-01"> <tr is="my-component"></tr> </table>
這至關於把組件假裝成一個tr ,查看瀏覽器文檔結構解析爲:
<table id="app-01"> <tbody> <div>A custom component</div>——(組件內容) </tbody> </table>
tbody問題:
此處出現的tbody是html解析自動補全的,tbody功能爲,劃分表格結構,默認狀況下是一個tbody,也可手動創建多個並行的tbody,這影響表格分別渲染及切分(很長的表格換頁的時候斷在哪裏就是切分)
<div id="app-02"> <simple-counter></simple-counter> <simple-counter></simple-counter> <simple-counter></simple-counter> </div> 若是是: var data={counter:0} var app02=new Vue({ el:'#app-02', components:{ 'simple-counter':{ template:'<button v-on:click="counter +=1">{{counter}}</button>', data:function(){ return data } } } 則修改一個模板,其餘模板數字也被修改,由於data的返回值是data自身,而全部模板都會引用data,都有修改權。 改一下: var app02=new Vue({ el:'#app-02', components:{ 'simple-counter':{ template:'<button v-on:click="counter +=1">{{counter}}</button>', data:function(){ return {counter:0} } } } 每一個模板能夠有獨立的值了,由於data做爲一個函數返回的是不一樣的counter,不會被共用
模板內部的data與外部是衝突的
<div id="app-03"> <child message="hello"></child> <div>{{value}}</div> </div> var app03=new Vue({ el:'#app-03', components:{ 'child':{ template:'<span>{{message}}</span>', props:['message'] } }, data:{ value:'yyy' } })
此例子中,props請求的message經過組件元素傳入,即特性傳入,props與外部的data不衝突
props:['myMessage']——js內 <child-11 my-message="hello"></child-11>——html內
<div id="app-03"> <input type="text" v-model='parentMsg'> <child-11 v-bind:my-message="parentMsg"></child-11> </div> var app03=new Vue({ el:'#app-03', components:{ 'child-11':{ template:'<span>{{myMessage}}</span>', props:['myMessage'] } }, data:{ parentMsg:'' } })
<comp some-prop='1'></comp> 因爲這是一個字面prop,傳遞了一個字符串'1',它的值是字符串‘1’而不是number <comp v-bind:some-prop='1'></comp> 這樣會把值當作一個javascript表達式計算,纔是number (存疑) - prop是單向綁定:父組件屬性變化時,將傳到給子組件,但不會反過來。同時,每次父組件更新時,子組件的全部prop都會更新爲最新值,這意味着,不該該在子組件內部改變prop。可是還要用怎麼辦呢? - 定義一個局部變量,用prop初始化 - 定義一個計算屬性,處理prop值 然而,js中,對象和數組是引用類型,指向同一個內存空間,若是prop是對象或者數組,在子組件內部改變也會影響父組件的狀態。 - Prop驗證
<div id="app-04">
<child prop-c="111"></child>
<child prop-c="333" prop-d="222"></child>
</div>
var app04=new Vue({
el:'#app-04',
components:{
'child':{
template:'<span>{{propC}}-{{propD}}-{{propE}}</span>',
props:{
propC:{
type:String,
required:true
},
propD:[String,Number],
propE:{
type:[String,Number],
default:100
}
}
}
}
})
有幾種驗證: - 指定類型驗證:
單個的,propA:Number;
多個的,propB:[String,Number]
- 是否必須存在的驗證:
propC:{
type:String,
required:true
}
- 帶默認值的驗證:
propD:{
type:Number,
default:100
}
默認值能夠是函數:
propE:{
type:Object,
default:function(){
return { message:'hello'}
- 還能夠自定義驗證函數:
propF:{
validator:function(value){
return value>0
}
這個驗證失敗時是控制檯報錯
- type的類型是如下原生構造器: - String - Number - Boolean - Function - Object - Array #####自定義事件
<div id="app-05">
<p>{{total}}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
var app05=new Vue({
el:'#app-05',
components:{
'button-counter':{
template:'<button v-on:click="increment">{{counter}}</button>',
data:function(){
return{
counter:0
}
},
methods:{
increment:function(){
this.counter+=1
this.$emit('increment')
}
}
}
},
data:{
total:0
},
methods:{
incrementTotal:function(){
this.total+=1
}
}
})
這個例子中,建立了父元素和內部的子組件,子組件包含一個點擊事件,v-on:click=‘increment’,點擊後改變counter數值,同時爲了上傳事件,在函數increment內部自定義了一個事件,並在點擊時觸發此事件,$emit,也叫increment,並在子元素上綁定了這個事件,v-on:increment,而後對此在父元素上綁定了一個函數,incrementTotal,從而達到計算總數的效果。 我以爲這個名字區分一下比較好,子組件的方法沒必要和觸發事件同一個名字,因此改一下:
<div id="app-05">
<p>{{total}}</p>
<button-counter v-on:user-defined="incrementTotal"></button-counter>
<button-counter v-on:user-defined="incrementTotal"></button-counter>
</div>
var app05=new Vue({
el:'#app-05',
components:{
'button-counter':{
template:'<button v-on:click="increment">{{counter}}</button>',
data:function(){
return{
counter:0
}
},
methods:{
increment:function(){
this.counter+=1
this.$emit('user-defined')
}
}
}
},
data:{
total:0
},
methods:{
incrementTotal:function(){
this.total+=1
}
}
})
- 給組件綁定原生事件
用.native修飾v-on
<new-component v-on:click.native="doSomeThing"></new-component>
- v-on與$on的不一樣: v-on能夠被父組件用來監聽子組件的事件 (存疑):$on的用法 - v-model的使用: - ref與$.refs——註冊引用信息和使用: - 在元素上註冊:<p ref="a">hello</p> 使用註冊:vm.$refs.a就是p這個DOM節點 - 在組件上註冊:<input ref="b"> 使用註冊:this.$refs.b就是指向了組件實例,this.$refs.b.value指向的是組件input.value - mounted ——生命週期鉤子,當el被新建立的vm.$el替換,並掛載到實例上以後調用該鉤子 - NumberObject.toFixed(num)——把Number四捨五入爲指定小數位數的數字
<script src="https://cdn.rawgit.com/chrisvfritz/5f0a639590d6e648933416f90ba7ae4e/raw/98739fb8ac6779cb2da11aaa9ab6032e52f3be00/currency-validator.js"></script>
//載入一個驗證插件
<div id="app-07">
<currency-input label="Price" v-model="price"></currency-input>
<currency-input label="Shipping" v-model="shipping"></currency-input>
<currency-input label="Handling" v-model="handling"></currency-input>
<currency-input label="Discount" v-model="discount"></currency-input>
//此處有一個合計
<p>Total: ${{total}}</p>
</div>
//組件部分
Vue.component('currency-input',{
template:'<div>
//若是有label,則顯示,不然不顯示
<label v-if="label">{{label}}</label>
$<input ref="input" v-bind:value="value" v-on:input="updateValue($event.target.value)"
v-on:focus="selectAll" v-on:blur="formatValue"></div>',
props:{
//對參數進行驗證
value:{
type:Number,
default:0
},
label:{
type:String,
default:''
}
},
//生命週期鉤子,當組件被掛載到實例時會觸發
mounted:function(){
this.formatValue()
},
methods:{
updateValue:function(value){
var result=currencyValidator.parse(value,this.value)
if(result.warning){
this.$refs.input.value=result.value
}
this.$emit('input',result.value)
},
formatValue:function(){
this.$refs.input.value =currencyValidator.format(this.value)
},
//作setTimeout是因爲safari此處有bug,不考慮兼容的話沒必要如此
selectAll:function(event){
setTimeout(function(){
event.target.select()
},0)
}
}
})
- 非父子組件間的通訊(簡單場景)——建立一個空的Vue實例做爲鏈接:
var bus = new Vue()
//在A組件內
bus.$emit('id-selected', 1)
//在B組件內
bus.$on('id-selected', function (id) {
// ...
})
- slot 內容分發 - 單個slot:子組件只有一個沒有名字的slot時,父組件的整個內容片段會插入到slot所在的DOM位置 - 具名slot:
子模板
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父模板
<app-layout>
<h1 slot="header">這裏多是一個頁面標題</h1>
<p>主要內容的一個段落。</p>
<p>另外一個主要段落。</p>
<p slot="footer">這裏有一些聯繫信息</p>
</app-layout>
渲染結果
<div class="container">
<header>
<h1>這裏多是一個頁面標題</h1>
</header>
<main>
<p>主要內容的一個段落。</p>
<p>另外一個主要段落。</p>
</main>
<footer>
<p>這裏有一些聯繫信息</p>
</footer>
</div>
- 做用域插槽:子組件中把數據傳遞到插槽slot,父元素用一個template scope="props" 獲取數據,而後就可使用了
Vue.component('child',{
template:'<div><slot text="hello from child"></slot></div>'
})
var app03=new Vue({
el:'#app-03',
components:{
'parent-component':{
template:'<div>
<child>
<template scope="props">
<span>hello from parent</span>
<span>{{props.text}}</span>
</template>
</child></div>'
}
}
})
//顯示爲:
hello from parent hello from child
- 更復雜的列表組件的例子:
//須要把mylist傳遞進parent-list
<parent-list id="app-04" v-bind:mylist="mylist"></parent-list>
Vue.component('child-list',{
props:['mylist'],
template:'<ul><slot name="item" v-for="item in mylist" v-bind:text="item.text"></slot></ul>'
})
var app04=new Vue({
el:'#app-04',
data:{
mylist:[
{text:'蔬菜'},
{text:'水果'},
{text:'肉'}
]
},
components:{
'parent-list':{
props:['mylist'],
//此處也須要把mylist傳遞進child-list
template:'<child-list v-bind:mylist="mylist">
<template slot="item" scope="props">
<li>{{props.text}}</li>
</template>
</child-list>'
}
}
})
顯示爲:
- 渲染一個元組件爲動態組件,根據is的值來決定渲染哪一個組件
<component id="app-06" v-bind:is="currentView"></component>
var app06=new Vue({
el:'#app-06',
data:{
currentView:'posts'
},
components:{
'home':{
template:'<span>home</span>'
},
'posts':{
template:'<span>posts</span>'
},
'archive':{
template:'<span>archive</span>'
}
}
})
//輸入爲posts
- keep-alive保留狀態或避免從新渲染
<keep-alive><component id="app-06" v-bind:is="currentView"></component></keep-alive>
- 可複用組件,三個接口: - props - events - slots
<my-component
:foo="baz"
:bar="qux"
@event-a="doThis"
@event-b="doThat"
<img slot="icon" scr="...">
<p slot="main-text">Hello!</p>
</my-component>
- 子組件索引:使用ref指定一個索引id
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({el:'#parent'})
var child = parent.$refs.profile
當ref與v-for一塊兒使用時,ref是一個數組或對象,包含相應的子組件,是非響應式的,應避免在模板或計算屬性中使用 - 異步組件,接受一個工廠函數,能夠動態解析組件的定義:
<div id="app-07"> <recursion-component :count="0"></recursion-component> </div> Vue.component('recursion-component',{ props:['count'], name:'count', template:'<div><span>{{count}}</span><recursion-component :count="count+1" v-if="count<10"></recursion-component></div>' }) var app07=new Vue({ el:'#app-07' }) //輸出是:0 1 2 3 4 5 6 7 8 9 10
beforeCreate:function(){ this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue') }
此處(存疑,之後用了webpack再說)
文件目錄樹的例子:
<div id="app-08"> <tree-folder :folder="folder"></tree-folder> </div> Vue.component('tree-folder',{ template:'<p><span>{{folder.name}}</span><tree-folder-contents :children="folder.children"/></p>', props:['folder'] }) Vue.component('tree-folder-contents',{ template:'<ul><li v-for="child in children">\ <tree-folder v-if="child.children" :folder="child"/>\ <span v-else>{{child.name}}</span>\ </li></ul>', props:['children'] }) var app08=new Vue({ el:'#app-08', data:{ folder:{ name:'總目錄', children:[ {name:"二層目錄1"}, {name:"二層目錄2", children:[ {name:"三層目錄1"}, {name:"三層目錄1"} ] }, {name:'二層目錄3'} ] } } }) //輸出: 總目錄 - 二層目錄1 - 二層目錄2 - 三層目錄1 - 三層目錄2 - 二層目錄3
<parent-com><span>啦啦啦</span></parent-com> \\js部分 Vue.component('parent-com',{ template:'<div><child-com><span>this is part of parents</span></child-com></div>' }) \\默認狀況下,「啦啦啦」做爲分發內容,不會顯示,而是顯示this is part of parents. \\若是改成: <parent-com inline-template><span>啦啦啦</span></parent-com> \\則顯示爲「啦啦啦」,原設定的template被覆蓋了
<div id="app-10"> <hello-world></hello-world> </div> \\先單獨一個js,類型爲type="text/x-template",而且須要有id <script type="text/x-template" id="hello-world-template">
Vue.component('terms-of-service', {
template: '\
<div v-once>\ <h1>Terms of Service</h1>\ ... a lot of static content ...\ </div>\ ' })