構(gòu)造器
-
實例化vue時,需傳入一個選項對象,它可以包括 數(shù)據(jù)、模板、掛載元素、方法和生命周期鉤子
屬性與方法
每個vue實例都會代理其data對象里所有的屬性
-
vue實例暴露了一些有用的實例屬性與方法,這些屬性與方法都有前綴$,以便與代理的data屬性區(qū)分
實例生命周期
created鉤子------在實例被創(chuàng)建后被調(diào)用
mounted----當編譯好的HTML被掛載到對應(yīng)的位置,這個操作完成后觸發(fā)
updated----當data中的數(shù)據(jù)改變,并且虛擬DOM重新渲染完成后觸發(fā)
destroyed
-
概要: 鉤子的this 指向調(diào)用它的實例
生命周期圖示
-
https://cn.vuejs.org/images/lifecycle.png
插值
-
文本
- 雙大括號
- v-text
-
純HTML
- v-html
-
屬性
- v-bind(大雙括號不能在屬性中使用,因此需使用v-bind)
-
使用JavaScript表達式
指令
-
哪些指令?
v-bind
v-on
v-if
-
v-for(特殊)
v-if
<div id="app"> <template v-if="ok==='username'"> 用戶名: <input type="text" placeholder="請輸入用戶名" key="name-input"> </template> <template v-else> 密碼: <input type="text" placeholder="請輸入密碼" key="psd-input"> </template> <button @click="toggle">點擊切換類型</button> </div> new Vue({ el: "#app", data: { ok:'username' }, methods: { toggle: function(todo){ if(this.ok==='username'){ this.ok = 'psd' }else{ this.ok = 'username'; } } } })v-for
<div id="app"> <ul> <li v-for="item in items">{{item}}</li> </ul> </div> new Vue({ el: "#app", data: { items:['a','b','c'] }, methods: { toggle: function(todo){ todo.done = !todo.done } } })
-
修飾符
- v-on
.stop 阻止單擊事件冒泡 <a v-on:click.stop="doThis"></a>
.prevent 提交事件不再重載頁面
.capture 添加事件偵聽器時使用時間捕獲模式
.self 只當事件在該元素本身(而不是子元素)觸發(fā)時觸發(fā)回調(diào)
-
太多了,不再總結(jié).這些都不重要,大家有空自己搜一下吧~~~~哈哈
過濾器
- v-on
過濾器的目的是用于文本轉(zhuǎn)換,轉(zhuǎn)化成你想要的格式,還是給大家來個例子
filters
<div id="app">
<p>{{message | changeChar}}</p>
<button @click="changeFirstChar">改變</button>
</div>
new Vue({
el: "#app",
data: {
message:'nihao'
},
methods: {
changeFirstChar: function(todo){
this.message = 'good evening'
}
},
filters:{
changeChar(value){
if(!value){
return '';
}else{
return value.charAt(0).toUpperCase()+value.substring(1)
}
}
}
})
縮寫
-
v-bind縮寫
- 原有: <a v-bind:href="url"></a> 縮寫: <a :href="url"></a>
-
v-on縮寫
-
原有:<button v-on:click="doSomeThing"></button> 縮寫:<button @click="doSomeThing"></button>
計算屬性
計算屬性(減少模板{{}}的復(fù)雜度)
-
基礎(chǔ)例子1
計算屬性的兩種寫法
computed
<div id="app">
{{fullName}}
</div>
new Vue({
el: "#app",
data: {
firstName:'Ji',
lastName:'RenGu'
},
computed:{
fullName(){
return this.firstName+'----'+this.lastName;
}
}
})
- 計算緩存vs方法(Methods)
- 計算屬性computed具有緩存,而methods無緩存
- Computed屬性vs 偵聽器(Watch屬性)
- watch方法--觀察Vue實例上的數(shù)據(jù)變動,只要指定的數(shù)據(jù)改變就會執(zhí)行預(yù)定的函數(shù)
watch
<div id="app">
{{msg}} <br>
改變了嗎? {{isChange}}
<button @click="change">改變</button>
</div>
new Vue({
el: "#app",
data: {
msg:'欲窮千里目',
isChange:'No'
},
watch:{
//只要msg改變,這個方法就會執(zhí)行
msg(val,oldVal){
this.isChange = 'Yes'
}
},
methods:{//不得不說ES6寫起來真爽
change(){
this.msg = '更上一層樓'
}
}
})
* computed方法
-
計算setter 和getter
- get和set,顧名思義,一個是獲得,一個是設(shè)置,常規(guī)上來講,計算屬性中都是有g(shù)et和set方法的,默認是只有g(shù)etter方法,如果需要的話,自然,你也可以寫一個setter方法.來個例子,諸位往下看:
get和set
<div id="app">
此時的onpiece: {{onepiece}} <br>
此時的msg: {{msg}} <br><br>
<button @click="setName">設(shè)置name</button>
</div>
new Vue({
el: "#app",
data: {
name:'Kobe',
msg:''
},
methods:{
setName(){
this.onepiece = 'JorDan'
}
},
computed:{
onepiece:{
get(){
return this.name +'Bryant';
},
set(newVal){
//當你給onepiece設(shè)置值的時候set就就會調(diào)用
this.msg = newVal+'is the greatest basketball player';
}
}
}
})
class與style綁定
綁定HTML class
- 對象語法
- 基本
- 在對象中傳入多個class屬性(其會與原有class共存)
- 直接傳入對象
- 與計算屬性一起使用(綁定返回對象的計算屬性)
- 數(shù)組語法
- 簡單例子
- 三元表達式
- 當有多個條件class時,可以在數(shù)組語法中使用對象語法
- 用在組件上
簡單例子
綁定HTML class例子
綁定class的幾種方式
.classC{
color:red;
}
.classD{
font-weight:bold;
}
.classE{
font-size:20px;
}
.classF{
color:blue;
}
.classM{
display:block;
}
.classN{
display:none;
}
<div id="app">
<h2>class屬性綁定</h2>
-------------------綁定變量-------------------------
<div :class="{classA:a,classB:b}">
綁定變量
</div>
-------------------綁定對象-------------------------
<div :class="styleObj">
綁定對象
</div>
-------------------綁定數(shù)組-------------------------
<div :class="arrClass">
綁定數(shù)組
</div>
-------------------綁定三元運算符-------------------------
<div :class="m==true?'classM':'classN'">
綁定變量
</div>
<button @click="toggle">toggle</button>
</div>
new Vue({
el: "#app",
data: {
a:true,
b:false,
styleObj:{
classC:true,
classD:true
},
m:true,
arrClass:['classE','classF']
},
methods:{
toggle(){
this.m=!this.m;
}
}
})
### 綁定內(nèi)聯(lián)樣式
* 對象語法
* 內(nèi)聯(lián)式對象語法
* 樣式對象式對象語法(更推薦)
* 數(shù)組語法
* 自動添加前綴
* v-bind:style 當需要特定的前綴時如transform,vue.js會自動添加
* 多重值
* 從vue2.3+后,可以為一個屬性添加多個值的數(shù)組,常用于含有多個前綴的情況
例子跟上邊差不了多少,懶得寫了.相信大家應(yīng)該也都會,哈哈哈哈~~~
## 條件渲染
### v-if(v-else)是真正的渲染
* template元素與v-if
* v-else(需要緊跟在v-if后邊)
* v-else-if(vue2.1.0新增)
* 用key管理可復(fù)用的元素---(如果這個例子看不懂的話.可以在群里問我!!!)
* 例子:用戶名和郵箱登錄界面 如果有key就不會復(fù)用,大家可以把key去試一下,然后輸入看一下效果!!!
<div id="app">
<template v-if="ok==='username'">
用戶名: <input type="text" placeholder="請輸入用戶名" key="name-input">
</template>
<template v-else>
密碼: <input type="text" placeholder="請輸入密碼" key="psd-input">
</template>
<button @click="toggle">點擊切換類型</button>
</div>
new Vue({
el: "#app",
data: {
ok:'username'
},
methods: {
toggle: function(todo){
if(this.ok==='username'){
this.ok = 'psd'
}else{
this.ok = 'username';
}
}
}
})
### v-show(其只是簡單的切換display屬性)
* v-show不支持template語法
* v-show不支持v-else
### v-if VS v-show
* v-if
* 當條件不成立時不會渲染
* 切換開銷較大,適合不太可能變化的場景
* v-show
* 無論成不成立都會渲染
* 首次渲染開銷較大,但切換開銷小,因此適合經(jīng)常變化的場景
## 列表渲染
### v-for
* 基本用法
* 簡單例子
* 帶有index參數(shù)
* 使用of 替代 in
* template v-for
* 簡單例子
* 對象迭代 v-for
* 基礎(chǔ)用法
* 帶其他參數(shù)用法
* 整數(shù)迭代 v-for
* 例子
* 組件和v-for
包含所有類型的例子
<div id="app">
<hr>
<strong style="border:2px solid #ccc;">遍歷數(shù)組:</strong>
<ul>
<li v-for="item in items" >{{item}}</li>
</ul>
<hr>
<strong style="border:2px solid #ccc;">遍歷對象數(shù)組:</strong>
<ul>
<li v-for="(item,index) in pers">{{index}}--我是{{item.name}},今年{{item.age}}歲</li>
</ul>
<hr>
<strong style="border:2px solid #ccc;">遍歷對象:</strong>
<ul>
<li v-for="(value,key) in obj">
key:{{key}} |
value:{{value}}
</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
isOK:'true',
items:['香蕉','蘋果','烤肉'],
pers:[{
name:'Kobe',
age:'40'
},
{
name:'James',
age:'38'
}],
obj:{
1:'one',
2:'two'
}
}
})
key
-
作用
- 用v-for更新已渲染過的列表時,它默認采用的是“就地復(fù)用”的原則,也就是如果數(shù)據(jù)項順序發(fā)生了改變,vue將不是移動DOM元素來匹配數(shù)據(jù)項的順序,而是簡單復(fù)用此處的元素。如果想跟蹤每個節(jié)點的身份,從而重用或重新排列現(xiàn)有元素,可使用key。(key還可用在v-if中,詳見v-if中的郵箱名和用戶名切換的例子)
好吧,可能大家看到這里是一頭霧水,不知所以,憂心忡忡,到底key有什么卵用,剛才上邊的例子不是沒有加key嗎?好吧,不扯那沒用的,通過一個例子告訴大家key到底有啥用!!!
<div id="app">
KEY: <input type="text" v-model="id">
VALUE: <input type="text" v-model="name">
<button @click="add">添加</button>
<ul>
<li v-for="item in list" :key="item.id">
//此處你可以把key去了,先勾選一條,在追加一條試一下,然后加上key,勾選一條追加一條再試一下,一目了然
<input type="checkbox" >
{{item.id}}---{{item.name}}
</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
id:"",
name:"",
list:[
{id:1, name:'李斯'},
{id:2, name:'嬴政'},
{id:3, name:'趙高'},
{id:4, name:'韓非'},
{id:5, name:'荀子'},
]
},
methods: {
add: function(){
this.list.unshift({id:this.id,name:this.name})
}
}
})
因為加上key默認采取的就是就地復(fù)用策略
數(shù)組更新檢測
-
變異方法(會改變原有數(shù)組)
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
-
重塑數(shù)組
- filter()
- concat()
- slice()
-
注意事項
利用索引直接設(shè)置一個項時,vue不能檢測變動,如:vm.items[indexOfItem] = newValue
那如果設(shè)置某一項的該怎么設(shè)置呢?- Vue.set(example1.items, indexOfItem, newValue)
- example1.items.splice(indexOfItem, 1, newValue)
<div id="app">
<button @click="setZF">設(shè)置第二項為張飛</button>
<button @click="setGY">設(shè)置第三項為關(guān)羽</button>
<ul>
<li v-for="item in list">
<input type="checkbox" >
{{item.id}}---{{item.name}}
</li>
</ul>
</div>
var vmm = new Vue({
el: "#app",
data: {
id:"",
name:"",
list:[
{id:1, name:'李斯'},
{id:2, name:'嬴政'},
{id:3, name:'趙高'},
{id:4, name:'韓非'},
{id:5, name:'荀子'},
]
},
methods: {
setZF: function(){
Vue.set(this.list,1,{id:2,name:'張飛'})
},
setGY:function(){
this.list.splice(2,1,{id:3,name:'關(guān)羽'})
}
}
})
* 修改數(shù)組長度時,vue不能檢測變動,如:vm.items.length = newLength
* 只能用example1.items.splice(newLength)
對與顯示過濾/排序結(jié)果的兩種方法
過濾數(shù)組--計算屬性computed例子
過濾數(shù)組--方法methods例子
計算屬性應(yīng)用于過濾
<div id="app">
{{specialNum}}
</div>
new Vue({
el: "#app",
data: {
nums:[1,2,3,4,5,6,7,8,9]
},
computed:{
specialNum(){
return this.nums.filter((item,index)=>{
return item%3==0;
})
}
}
})
<div id="app">
<ul>
在v-for循環(huán)中直接嵌入方法
<li v-for="item in fil(numbers)">{{item}}</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
numbers:[1,2,3,4,5,6,7,8,9]
},
methods:{
fil(nums){
return nums.filter((item,index)=>{
return item%3==0;
})
}
}
})
兩個簡單的事件處理器
先來一個簡單小例子,v-on用來綁定事件
<div id="app">
<button @click="num+=1">增加1</button>
{{num}}
</div>
* * *
<div id="app">
<button @click="sayHello">點擊sayHello</button>
</div>
new Vue({
el: "#app",
methods: {
sayHello: function(){
alert('sayHello')
}
}
})
`### 內(nèi)聯(lián)處理器方法 * 訪問原生DOM事件的例子,如果click事件不傳參數(shù),就默認把原生DOM傳遞進去`
<div id="app"> //沒有傳參數(shù),就是原生的!!!
<button @click="showBtnname">顯示按鈕的名字</button> <br><br>
{{msg}}
</div>
new Vue({
el: "#app",
data: {
msg:''
},
methods: {
showBtnname: function(e){
this.msg = e.target.innerText;
}
}
})
- 未訪問原生DOM事件的例子,如果傳了參數(shù).那么方法中接受的第一個參數(shù)就是該參數(shù),在vue中所有的事件綁定都是這樣的
----------------------------html---------------------------------
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<label>
<input type="checkbox" v-on:change="toggle(todo)" v-bind:checked="todo.done">
<del v-if="todo.done">
{{ todo.text }}
</del>
<span v-else>
{{ todo.text }}
</span>
</label>
</li>
</ol>
</div>
----------------------------js---------------------------------
new Vue({
el: "#app",
data: {
todos: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
----------------------------css---------------------------------
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
事件修飾符
- .stop
- 阻止單擊事件冒泡
- .prevent
- 提交事件不再重載頁面
- .capture
- 使用事件捕獲模式
- .self
- 只有當事件在該元素本身被觸發(fā)時(不包含子元素)才觸發(fā)回調(diào)
- .once
- 事件只觸發(fā)一次(vue 2.1.4新增)
- 修飾符串聯(lián)
- 例子
按鍵修飾符
-
.enter
- keyCode
- .enter
.tab
-
.delete
- (捕獲 “刪除” 和 “退格” 鍵)
.esc
.space
.up
.down
.left
.right
組合使用,單獨是使用的話,和click都是一樣的,這里組合使用有點特殊,使用 . 進行連接簡單給個例子
<div id="app">
<button @click.ctrl="num++">num+1</button>
{{num}}
</div>
new Vue({
el: "#app",
data: {
num:0
}
})
### vue2.1.0新增 按鍵修飾符
* .ctrl
* .alt
* .shift
* .meta
## 表單控件綁定
### 基礎(chǔ)用法
* 文本
```
<div id="app">
<h2>{{msg}}</h2>
<br>
<input type="text" v-model="msg">
</div>
new Vue({
el: "#app",
data: {
msg:'萬年的msg'
}
})
```
* 多行文本---注意了啊:在文本區(qū)域插值( `<textarea></textarea>` ) 并不會生效,應(yīng)用 `v-model` 來代替
```
<div id="app">
<p style="white-space: pre">
{{msg}}
</p>
<br>
<textarea type="text" v-model="msg"></textarea>
</div>
```
* 復(fù)選框
* 單個復(fù)選框(直接綁定true,false)
```
<div id="app">
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
</div>
new Vue({
el: "#app",
data: {
checked:true
}
})
```
* 多個復(fù)選框(將選中的所有value綁定到一個數(shù)組)
```
<div id="app">
<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>
{{checkedNames}}
</div>
new Vue({
el: "#app",
data: {
checkedNames:[]
}
})
```
* 單選按鈕(綁定選中的單選框的value)
```
<div id="app">
<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>
new Vue({
el: "#app",
data: {
picked:''
}
})
```
* 選擇列表(不管是單選還是多選,v-model都要綁定到select元素上)
* 單選列表(綁定到被選中項的value)
```
<div id="app">
<select v-model="selected">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
new Vue({
el: "#app",
data: {
selected:''
}
})
```
-
多選列表(綁定一個數(shù)組,數(shù)組的內(nèi)容是所有的選中項的value)
<div id="app"> <select v-model="selected" multiple> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span> </div> new Vue({ el: "#app", data: { selected: [] } }) -
動態(tài)選項
<div id="app"> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span> </div> new Vue({ el: "#app", data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } })
### 修飾符
* .lazy
* 由原有的input事件變更為change事件
```
<div id="app">
<input type="text" v-model.lazy="msg">
{{msg}}
</div>
new Vue({
el: "#app",
data: {
msg:'萬年的msg'
}
})
```
* .number
* 將輸入的類型轉(zhuǎn)換成數(shù)字類型(NaN則還是原有類型)
* .trim
* 去除兩端空白
算了,這點太簡單
### v-model與組件
## 組件
### 使用組件
* 注冊
* 注意事項
* 在初始化根實例前一定要確保注冊了組件
* 名稱最好 小寫(可以使用短桿)
```
<div id="app">
<my-comp></my-comp>
</div>
Vue.component('my-comp',{
template:'<h3>我是新出爐的組件</h3>'
})
new Vue({
el: "#app",
data: {
}
})
```
* 局部注冊
```
<div id="app">
<my-comp></my-comp>
</div>
new Vue({
el: "#app",
components:{
'my-comp':{template:'<h3>我是新出爐的組件</h3>'}
},
data: {
}
})
```
* DOM模板解析說明
* 自定義組件在這些元素內(nèi)受限
* ul
* ol
* table
* select
* 概要: 解決方案是 使用 特殊的is屬性
```
<div id="app">
<table>
```
<tr>
<my-comp></my-comp>//注意:這樣寫是絕對錯誤的,因為tr中只允許有td,這樣寫他是不認識滴
</tr>
```
</table>
</div>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 上邊是錯誤的
---------------------------------下邊是正確的-----------------------------------
<div id="app">
<table>
<tr>
<td is="my-comp"></td>
</tr>
</table>
</div>
new Vue({
el: "#app",
components:{
'my-comp':{
template:'<td>我是組件td</td>'
}
},
data: {
}
})
```
-
不受限的情況--使用字符串模板
-
<script type="text/x-template"> 怎么用呢?給大家來個例子吧!
-------------------------------HTML----------------------------------------- <div id="app"> <table> <tr> <template> <my-comp></my-comp> </template> </tr> </table> </div> <script type="text/x-template" id="myComponent"> <td>This is a component!</td> </script> -----------------------------------JS---------------------------------- new Vue({ el: "#app", components:{ 'my-comp':{ template:'#myComponent' } }, data: { } }) -
JavaScript內(nèi)聯(lián)模板字符串(第二種也給大家解釋一下是什么意思,什么是字符串模板)
<div id="app"> <table> <tr> <template> //這個就是字符串模板 <my-comp></my-comp> </template> </tr> </table> </div> .vue組件 (第三種不解釋了,用了那么多遍了,要是還不會,我就開始瘋狂嘲笑你)
-
-
data必須是函數(shù),在組件中使用data中定義的數(shù)據(jù),必須使用函數(shù)返回,其實這事要說為啥,還得從根上說,我自己的理解,最根本的三個字就是作用域,目的就是為了防止組件中使用的data和vue實例中的data進行相互污染,有機會的話可以給大家講一下,但是這不是三句兩句就能講清楚的,門票一人5毛怎么樣?
<div id="app"> <mycomp></mycomp> </div> new Vue({ el: "#app", components:{ 'mycomp':{ template:'<button>{{btncount}}</button>', data(){ return {btncount:8} } } }, data:{ btncount:10 } })
Prop(子組件從父組件獲得數(shù)據(jù))
-
使用prop傳遞數(shù)據(jù)
<div id="app"> <child msg="我是來自于父組件的內(nèi)容"></child> </div> new Vue({ el: "#app", components:{ 'child':{ props:['msg'], template:'<h2>{{msg}}</h2>' } } })動態(tài)綁定父組件中的數(shù)據(jù)
<div id="app">
<input type="text" v-model="fathertext">
{{fathertext}}
<child :childText="fathertext"></child>
</div>
new Vue({
el: "#app",
components:{
'child':{
props:['childtext'],
template:'<h1>{{childtext}}</h1>'
}
},
data: {
fathertext:''
}
})
props注意事項
一般情況下是數(shù)組形式,如果要想規(guī)定props的數(shù)據(jù)類型(后面用中括號 [ ])。默認值等(見props驗證),則是對象了(后面用花括號 { })
關(guān)于命名:要不然全小寫,要不然kebabCase(駝峰式),kebab-case(短橫線隔開式)Vue 能夠正確識別出小駝峰和下劃線命名法混用的變量,如這里的
forChildMsg和for-child-msg是同一值。-
,如果出不來,先檢查一下命名,看個例子:
<div id="app"> <input type="text" v-model="msg"> <child :childMsg="msg"></child> </div> new Vue({ el: "#app", components:{ child:{ template:'<h1>{{childMsg}}</h1>', props:['childMsg'] } }, data: { msg:'apple' } }) -
動態(tài)Prop(使用v-bind):在模板中,要動態(tài)地綁定父組件的數(shù)據(jù)到子組件模板的 props,和綁定 Html 標簽特性一樣,使用v-bind綁定
- 局部注冊組件
- 全局注冊組件
字面量語法vs動態(tài)語法
-
單向數(shù)據(jù)流
-
解釋
-
父組件數(shù)據(jù)更新后,子組件的所有prop都會更新為最新值,但是反過來就不會。(注意 :如果prop為數(shù)組或?qū)ο髸r,子組件改變prop,父組件的狀態(tài)也會受到影響,因為數(shù)組或?qū)ο笫且妙愋?,他們指向同一個內(nèi)存空間。)如果子組件的prop值被修改,則vue會給出警告。試一下下邊這個例子
<div id="app"> <parent></parent> </div> let childNode = { template: ` <div class="child"> <div> <span>子組件數(shù)據(jù)</span> <input v-model="forChildMsg"/> </div> <p>{{forChildMsg}}</p> </div>`, props: { "for-child-msg": String } }; let parentNode = { template: ` <div class="parent"> <div> <span>父組件數(shù)據(jù)</span> <input v-model="msg"/> </div> <p>{{msg}}</p> <child :for-child-msg="msg"></child> </div> `, components: { child: childNode }, data() { return { msg: "default string." }; } }; new Vue({ el: "#app", components:{ parent:parentNode } })
-
-
特殊情況應(yīng)對方法
-
prop作為初始值傳入后,可能子組件想把它當做局部數(shù)據(jù)來用的情況
-
方法:定義一個局部變量,并用prop的值初始化它
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } } //直接使用counter作為子組件的局部變量就可以了
-
-
prop作為初始值傳入,可能子組件處理成其他數(shù)據(jù)輸出的情況,比如處理成去空格并大寫
-
方法:定義一個計算屬性,處理prop的值并返回
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
-
-
-
-
prop驗證
-
例子--代碼篇
Vue.component('example', { props: { // 基礎(chǔ)類型檢測 (`null` 意思是任何類型都可以) propA: Number, // 多種類型 propB: [String, Number], // 必傳且是字符串 propC: { type: String, required: true }, // 數(shù)字,有默認值 propD: { type: Number, default: 100 }, // 數(shù)組/對象的默認值應(yīng)當由一個工廠函數(shù)返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, // 自定義驗證函數(shù) propF: { validator: function (value) { return value > 10 } } } })
-
自定義事件(子組件將數(shù)據(jù)傳回父組件)
-
使用v-on綁定自定義事件
給組件綁定自定義事件例子(用v-on來監(jiān)聽子組件觸發(fā)的事件)
-
給組件綁定原生事件例子--使用native修飾符
<div id="app"> <btncomp @click.native="alertE"></btncomp> </div> new Vue({ el: "#app", components:{ btncomp:{ template:'<button>點擊我彈出</button>' } }, methods:{ alertE(){ alert(777) } } })
-
.sync修飾符(vue 2.3)
目的:使父子組件實現(xiàn)prop類似“雙向數(shù)據(jù)綁定”(默認子組件無法更改prop的值,上邊已經(jīng)說到了,但是使用sync后子組件可以改變prop 的值,并傳回父組件)
-
使用范例
<div id="app"> <child :name.sync="name"></child> //其實不加也能更改,但是會報錯 <button type="button" @click="changePropsInFather">在父組件中將props值改變?yōu)?props'</button> </div> Vue.component('Child', { template: `<h1 @click="changePropsInChild">hello, {{name}}</h1>`, props: { name: String, }, methods:{ changePropsInChild(){ this.name = 'I am from child' } }, }) // 實例化一個Vue對象 const app = new Vue({ el: '#app', data(){ return { name: 'world' } }, methods:{ changePropsInFather(){ this.name='I am from father' }, }, })
-
使用自定義事件的表單輸入組件
-
v-model的語法糖(可能之前我在CNODE課程中講過,但是提的不是特別的仔細,這里還是給大家再說一下)
<div id="app"> <input v-model="price"> </div> new Vue({ el: '#app', data: { price: '' } });我們對v-model已經(jīng)再熟悉不過了,一般都是像上邊這樣的用法,但是v-model只是一個語法糖,它的真身是下邊這樣:
<div id="app"> <input type="text" :value="price" @input="price = $event.target.value">{{price}} </div> new Vue({ el: '#app', data: { price: '' } });
-
* 例子
* html及實例部分和注冊組件部分
```
<div id="app">
<price-input :value="price" @input="isinputing"></price-input>
{{price}}
</div>
new Vue({
el: "#app",
components:{
'price-input':{
template:"<input type='text' @input='update($event.target.value)' />",
props:['value'],
methods:{
update(val){
this.$emit('input',val)
}
}
}
},
data: {
price:''
},
methods: {
isinputing: function(val){//此處的value就是子組件傳遞過來的
this.price = val;
}
}
})
```
非父子組件通信
-
非父子組件通信(1 父傳子是用props 2 子傳父在vue中是不允許的,因為vue只允許單向數(shù)據(jù)傳遞,這時候我們可以通過觸發(fā)事件來通知父組件改變數(shù)據(jù),從而達到改變子組件數(shù)據(jù)的目的. 3 那么非父子組件之間通信怎么搞??????)
-
簡單的場景---采用空實例作為中央事件總線,原理就是找一個人來當作一個中轉(zhuǎn)站!
<div id="app1" @click="toApp2"> 我是組件一,點擊我給二傳值 </div> <br> <div id="app2"> {{app2msg}} </div> var bus = new Vue(); // 創(chuàng)建事件中心,創(chuàng)建中轉(zhuǎn)站 new Vue({ el: "#app1", data: {}, methods: { toApp2: function(){ bus.$emit('change','上山打老虎') //使用中轉(zhuǎn)站觸發(fā) } } }) new Vue({ el: "#app2", data: { app2msg:'' }, created(){ bus.$on('change',(val)=>{ this.app2msg = val; //在組件二創(chuàng)建完成的時候就使用中轉(zhuǎn)站進行監(jiān)聽 }) } })
-
* 復(fù)雜的場景---專門的狀態(tài)管理模式vuex
使用Slot分發(fā)內(nèi)容
-
內(nèi)容分發(fā)概念
-
為了讓組件可以組合(如本子主題的例子),因此需要混合父組件的內(nèi)容與子組件的自己模板,這一過程就稱作內(nèi)容分發(fā)。
<app> <app-header></app-header> <app-footer></app-footer> </app> 之前我們的組件,如果給app指定了模板,那么里邊的app-header和foot組件的內(nèi)容就會被覆蓋,因此,為了讓他們能夠組合.需要混用,這就是內(nèi)容分發(fā)
-
-
編譯作用域
- 分發(fā)內(nèi)容是在父作用域內(nèi)編譯的
-
單個slot(無具名slot)
-
為什么用slot
-
當父組件中有內(nèi)容(即自定義的標簽名之間有元素--見本子主題的例子) 子組件模板中無slot時,則父組件中的內(nèi)容會被丟棄。
<div id="app"> <my-comp> <p>我是組件中的內(nèi)容</p> //這個p會被覆蓋 </my-comp> </div> new Vue({ el: "#app", components:{ 'my-comp':{ template:'<h1>我是一個組件</h1>' } } })
-
-
* 那么單個slot怎么用呢?
```
<div id="app">
<children>
<span>12345</span>
<!--上面這行不會顯示-->
</children>
</div>
var vm = new Vue({
el: '#app',
components: {
children: { //這個無返回值,不會繼續(xù)派發(fā)
template: "<button><slot></slot>(我是button)</button>"
}
}
});
```
* 當父組件中有內(nèi)容時
* 子組件中的slot會被父組件中內(nèi)容所替換。(slot標簽也會被替換掉)
* 當父組件中無內(nèi)容時
* 子組件中slot內(nèi)容會被顯示出來
-
具名slot
-
用法:保子引父(保持子組件模板,引入父組件參數(shù))--嚴格按照子組件的模板順序來即:遇到具名slot對應(yīng)的元素就渲染相應(yīng)的元素,遇到不具名的slot,則會渲染除了具名slot對應(yīng)的元素以外的所有元素。
<div id="app"> <children> <span slot="first">12345</span> <span slot="second">56789</span> <!--上面這行不會顯示--> </children> </div> var vm = new Vue({ el: '#app', components: { children: { //這個無返回值,不會繼續(xù)派發(fā) template: "<button><slot name='first'></slot>我是button<slot name='second'></slot>所以使用button標簽</button>" } } }); 總結(jié):說白了,就是多一個name屬性.沒啥稀奇玩意
-
-
作用域插槽(特殊的插槽)
作用:使用可復(fù)用模板替代已渲染元素
-
用法:同具名slot類似,都是嚴格按照子組件的模板順序渲染,只不過遇到slot元素時會將父組件中的template元素里的元素全部渲染
-
列表組件例子
<div id="app"> <child :items="items"> <template slot="item" scope="props"> <!--必須存在的具有 scope屬性的 template元素(作用域插槽的模板), props臨時的變量名稱,接受子組件中傳遞的props對象--> <!--slot = “item”是具名 slot的用法。--> <li> {{props.tex}} <!--引用子組件中綁定的tex屬性值。--> </li> </template> </child> </div>
-
Vue.component('child',{
props:["items"],
template:'<ul><slot name="item" v-for="item in items" v-bind:tex="item.text"></slot></ul>'
});
new Vue({
el:'#app',
data:{
items:[
{text:'老虎'},
{text:'棒子'},
{text:'雞'}
]
}
})
```
動態(tài)組件
-
使用is屬性(注意,is前使用了v-bind!??!通過is來決定那個組件被渲染顯示 )
<div id="app"> <component v-bind:is="show"></component> <button v-on:click="changeShow">change show</button> </div> var app=new Vue({ el:'#app', data:{ show:'tem1' }, components:{ tem1:{ template:'<div>11111111111</div>' }, tem2:{ template:'<div>22222</div>' }, tem3:{ template:'<div>333333</div>' } }, methods:{ changeShow:function(){ if(this.show=='tem1'){ this.show='tem2' }else if(this.show=='tem2'){ this.show='tem3' }else{ this.show='tem1' } } } }) -
keep-active
作用:可保留組件狀態(tài)或避免重新渲染(包裹動態(tài)組件時會緩存不活動的組件實例而不是銷毀它們)配合 <keep-alive>使用時,可以保留組件狀態(tài)避免重新渲染(和v-show 比較的差別是v-show 是一開始就渲染的所有組件,而keep-alive 并不是一開始就渲染好所有組件,而已保留渲染過的組件
注意事項:使用環(huán)境應(yīng)該是較大頁面頻繁切換的情景下
-
用法
<div id="app"> <component v-bind:is="show"></component> <button v-on:click="changeShow">change show</button> </div> var app=new Vue({ el:'#app', data:{ show:'tem1' }, components:{ tem1:{ template:'<div>11111111111</div>' }, tem2:{ template:'<div>22222</div>' }, tem3:{ template:'<div>333333</div>' } }, methods:{ changeShow:function(){ if(this.show=='tem1'){ this.show='tem2' }else if(this.show=='tem2'){ this.show='tem3' }else{ this.show='tem1' } } } })