vue基礎(chǔ)知識(shí)部分
扯淡前言
- 這個(gè)筆記是關(guān)于vue的所有重點(diǎn)基礎(chǔ)知識(shí),大部分配的有實(shí)例,這些實(shí)例都是我自己一個(gè)個(gè)敲上去的,我基本都是先在jsfiddle上敲完,代碼直接粘貼過(guò)來(lái)的,嘔心瀝血有木有...
- 弄這個(gè)的目的一是為了大家能夠更好的掌握vue,因?yàn)榭丛蹅內(nèi)豪锏娜藬?shù)慢慢多了,其實(shí)最開(kāi)始就想著弄一個(gè)這樣的筆記,后來(lái)時(shí)間原因就擱置了.目前我個(gè)人覺(jué)得,如果不是構(gòu)建大型應(yīng)用,我覺(jué)得vue仍然是三大框架中最好用的,但是構(gòu)建大型應(yīng)用,肯定首選react,所以vue仍然是very,very重要的,必須無(wú)理由的熟練掌握;第二是這段時(shí)間有很多同學(xué)因?yàn)镃NODE的原因問(wèn)我一些問(wèn)題,從很多人的問(wèn)題來(lái)看,還是基礎(chǔ)知識(shí)并不是那么牢固,所以也就想為大家補(bǔ)一課;
- 不懂的群里問(wèn),但是大家問(wèn)問(wèn)題可以,提倡的是大家先思考,再仔細(xì)檢查代碼,還是不會(huì)就谷歌,百度,如果都做完了再來(lái)問(wèn)老濕,有時(shí)候大家問(wèn)我問(wèn)題,我不是不回答,是真沒(méi)看到,因?yàn)槲乙灿泻芏喙ぷ饕?不可能一天盯著,在這里也向很多同學(xué)道個(gè)歉,因?yàn)橛袝r(shí)候我可能是一天盯著電腦,但不可能自己一天盯著手機(jī),真的很抱歉...
- 最后祝愿大家都能前程似錦,一路繁花,好,開(kāi)始正文了....
構(gòu)造器
-
實(shí)例化vue時(shí),需傳入一個(gè)選項(xiàng)對(duì)象,它可以包括 數(shù)據(jù)、模板、掛載元素、方法和生命周期鉤子
屬性與方法
每個(gè)vue實(shí)例都會(huì)代理其data對(duì)象里所有的屬性
-
vue實(shí)例暴露了一些有用的實(shí)例屬性與方法,這些屬性與方法都有前綴$,以便與代理的data屬性區(qū)分
實(shí)例生命周期
created鉤子------在實(shí)例被創(chuàng)建后被調(diào)用
mounted----當(dāng)編譯好的HTML被掛載到對(duì)應(yīng)的位置,這個(gè)操作完成后觸發(fā)
updated----當(dāng)data中的數(shù)據(jù)改變,并且虛擬DOM重新渲染完成后觸發(fā)
destroyed
-
概要: 鉤子的this 指向調(diào)用它的實(shí)例
生命周期圖示
-
https://cn.vuejs.org/images/lifecycle.png
插值
-
文本
- 雙大括號(hào)
- v-text
-
純HTML
- v-html
-
屬性
- v-bind(大雙括號(hào)不能在屬性中使用,因此需使用v-bind)
-
使用JavaScript表達(dá)式
指令
-
哪些指令?
v-bind
v-on
v-if
-
v-for(特殊)
v-if <div id="app"> <template v-if="ok==='username'"> 用戶名: <input type="text" placeholder="請(qǐng)輸入用戶名" key="name-input"> </template> <template v-else> 密碼: <input type="text" placeholder="請(qǐng)輸入密碼" key="psd-input"> </template> <button @click="toggle">點(diǎn)擊切換類型</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 提交事件不再重載頁(yè)面
.capture 添加事件偵聽(tīng)器時(shí)使用時(shí)間捕獲模式
.self 只當(dāng)事件在該元素本身(而不是子元素)觸發(fā)時(shí)觸發(fā)回調(diào)
-
太多了,不再總結(jié).這些都不重要,大家有空自己搜一下吧~~~~哈哈
過(guò)濾器
- v-on
-
過(guò)濾器的目的是用于文本轉(zhuǎn)換,轉(zhuǎn)化成你想要的格式,還是給大家來(lái)個(gè)例子
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>
計(jì)算屬性
計(jì)算屬性(減少模板{{}}的復(fù)雜度)
-
基礎(chǔ)例子1
-
計(jì)算屬性的兩種寫法
computed<div id="app"> {{fullName}} </div>
new Vue({
el: "#app",
data: {
firstName:'Ji',
lastName:'RenGu'
},
computed:{
fullName(){
return this.firstName+'----'+this.lastName;
}
}
})
* 計(jì)算緩存vs方法(Methods)
* 計(jì)算屬性computed具有緩存,而methods無(wú)緩存
* Computed屬性vs 偵聽(tīng)器(Watch屬性)
* watch方法--觀察Vue實(shí)例上的數(shù)據(jù)變動(dòng),只要指定的數(shù)據(jù)改變就會(huì)執(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改變,這個(gè)方法就會(huì)執(zhí)行
msg(val,oldVal){
this.isChange = 'Yes'
}
},
methods:{//不得不說(shuō)ES6寫起來(lái)真爽
change(){
this.msg = '更上一層樓'
}
}
})
- computed方法
* 計(jì)算setter 和getter
* get和set,顧名思義,一個(gè)是獲得,一個(gè)是設(shè)置,常規(guī)上來(lái)講,計(jì)算屬性中都是有g(shù)et和set方法的,默認(rèn)是只有g(shù)etter方法,如果需要的話,自然,你也可以寫一個(gè)setter方法.來(lái)個(gè)例子,諸位往下看:
```
```
get和set
```
<div id="app">
此時(shí)的onpiece: {{onepiece}} <br>
此時(shí)的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){
//當(dāng)你給onepiece設(shè)置值的時(shí)候set就就會(huì)調(diào)用
this.msg = newVal+'is the greatest basketball player';
}
}
}
})
class與style綁定
綁定HTML class
- 對(duì)象語(yǔ)法
- 基本
- 在對(duì)象中傳入多個(gè)class屬性(其會(huì)與原有class共存)
- 直接傳入對(duì)象
- 與計(jì)算屬性一起使用(綁定返回對(duì)象的計(jì)算屬性)
- 數(shù)組語(yǔ)法
- 簡(jiǎn)單例子
- 三元表達(dá)式
- 當(dāng)有多個(gè)條件class時(shí),可以在數(shù)組語(yǔ)法中使用對(duì)象語(yǔ)法
- 用在組件上
簡(jiǎn)單例子
綁定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>
-------------------綁定對(duì)象-------------------------
<div :class="styleObj">
綁定對(duì)象
</div>
-------------------綁定數(shù)組-------------------------
<div :class="arrClass">
綁定數(shù)組
</div>
-------------------綁定三元運(yùn)算符-------------------------
<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)樣式
- 對(duì)象語(yǔ)法
- 內(nèi)聯(lián)式對(duì)象語(yǔ)法
- 樣式對(duì)象式對(duì)象語(yǔ)法(更推薦)
- 數(shù)組語(yǔ)法
- 自動(dòng)添加前綴
- v-bind:style 當(dāng)需要特定的前綴時(shí)如transform,vue.js會(huì)自動(dòng)添加
- 多重值
- 從vue2.3+后,可以為一個(gè)屬性添加多個(gè)值的數(shù)組,常用于含有多個(gè)前綴的情況
例子跟上邊差不了多少,懶得寫了.相信大家應(yīng)該也都會(huì),哈哈哈哈~~~
- 從vue2.3+后,可以為一個(gè)屬性添加多個(gè)值的數(shù)組,常用于含有多個(gè)前綴的情況
條件渲染
v-if(v-else)是真正的渲染
template元素與v-if
v-else(需要緊跟在v-if后邊)
v-else-if(vue2.1.0新增)
-
用key管理可復(fù)用的元素---(如果這個(gè)例子看不懂的話.可以在群里問(wèn)我!!!)
-
例子:用戶名和郵箱登錄界面 如果有key就不會(huì)復(fù)用,大家可以把key去試一下,然后輸入看一下效果!!!
<div id="app"> <template v-if="ok==='username'"> 用戶名: <input type="text" placeholder="請(qǐng)輸入用戶名" key="name-input"> </template> <template v-else> 密碼: <input type="text" placeholder="請(qǐng)輸入密碼" key="psd-input"> </template> <button @click="toggle">點(diǎn)擊切換類型</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(其只是簡(jiǎn)單的切換display屬性)
-
v-show不支持template語(yǔ)法
-
v-show不支持v-else
v-if VS v-show
-
v-if
- 當(dāng)條件不成立時(shí)不會(huì)渲染
- 切換開(kāi)銷較大,適合不太可能變化的場(chǎng)景
-
v-show
無(wú)論成不成立都會(huì)渲染
-
首次渲染開(kāi)銷較大,但切換開(kāi)銷小,因此適合經(jīng)常變化的場(chǎng)景
列表渲染
v-for
-
基本用法
- 簡(jiǎn)單例子
- 帶有index參數(shù)
- 使用of 替代 in
-
template v-for
- 簡(jiǎn)單例子
-
對(duì)象迭代 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;">遍歷對(duì)象數(shù)組:</strong> <ul> <li v-for="(item,index) in pers">{{index}}--我是{{item.name}},今年{{item.age}}歲</li> </ul> <hr> <strong style="border:2px solid #ccc;">遍歷對(duì)象:</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更新已渲染過(guò)的列表時(shí),它默認(rèn)采用的是“就地復(fù)用”的原則,也就是如果數(shù)據(jù)項(xiàng)順序發(fā)生了改變,vue將不是移動(dòng)DOM元素來(lái)匹配數(shù)據(jù)項(xiàng)的順序,而是簡(jiǎn)單復(fù)用此處的元素。如果想跟蹤每個(gè)節(jié)點(diǎn)的身份,從而重用或重新排列現(xiàn)有元素,可使用key。(key還可用在v-if中,詳見(jiàn)v-if中的郵箱名和用戶名切換的例子)
-
好吧,可能大家看到這里是一頭霧水,不知所以,憂心忡忡,到底key有什么卵用,剛才上邊的例子不是沒(méi)有加key嗎?好吧,不扯那沒(méi)用的,通過(guò)一個(gè)例子告訴大家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}) } } })
因?yàn)榧由蟢ey默認(rèn)采取的就是就地復(fù)用策略,這個(gè)例子,如果不懂,可以在群里問(wèn)我
### 數(shù)組更新檢測(cè)
* 變異方法(會(huì)改變?cè)袛?shù)組)
* push()
* pop()
* shift()
* unshift()
* splice()
* sort()
* reverse()
* 重塑數(shù)組
* filter()
* concat()
* slice()
* 注意事項(xiàng)
利用索引直接設(shè)置一個(gè)項(xiàng)時(shí),vue不能檢測(cè)變動(dòng),如: vm.items[indexOfItem] = newValue
那如果設(shè)置某一項(xiàng)的該怎么設(shè)置呢?
```
* Vue.set(example1.items, indexOfItem, newValue)
* example1.items.splice(indexOfItem, 1, newValue)
```
```
<div id="app">
<button @click="setZF">設(shè)置第二項(xiàng)為張飛</button>
<button @click="setGY">設(shè)置第三項(xiàng)為關(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ù)組長(zhǎng)度時(shí),vue不能檢測(cè)變動(dòng),如:vm.items.length = newLength
* 只能用example1.items.splice(newLength)
對(duì)與顯示過(guò)濾/排序結(jié)果的兩種方法
過(guò)濾數(shù)組--計(jì)算屬性computed例子
過(guò)濾數(shù)組--方法methods例子
計(jì)算屬性應(yīng)用于過(guò)濾
<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;
})
}
}
})
兩個(gè)簡(jiǎn)單的事件處理器
先來(lái)一個(gè)簡(jiǎn)單小李子,v-on用來(lái)綁定事件
1
<div id="app">
<button @click="num+=1">增加1</button>
{{num}}
</div>
* * *
2
<div id="app">
<button @click="sayHello">點(diǎn)擊sayHello</button>
</div>
new Vue({
el: "#app",
methods: {
sayHello: function(){
alert('sayHello')
}
}
})
`### 內(nèi)聯(lián)處理器方法 * 訪問(wèn)原生DOM事件的例子,如果click事件不傳參數(shù),就默認(rèn)把原生DOM傳遞進(jìn)去`
<div id="app"> //沒(méi)有傳參數(shù),就是原生的!!!
<button @click="showBtnname">顯示按鈕的名字</button> <br><br>
{{msg}}
</div>
new Vue({
el: "#app",
data: {
msg:''
},
methods: {
showBtnname: function(e){
this.msg = e.target.innerText;
}
}
})
- 未訪問(wèn)原生DOM事件的例子,如果傳了參數(shù).那么方法中接受的第一個(gè)參數(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
- 提交事件不再重載頁(yè)面
- .capture
- 使用事件捕獲模式
- .self
- 只有當(dāng)事件在該元素本身被觸發(fā)時(shí)(不包含子元素)才觸發(fā)回調(diào)
- .once
- 事件只觸發(fā)一次(vue 2.1.4新增)
- 修飾符串聯(lián)
- 例子
按鍵修飾符
-
.enter
- keyCode
- .enter
.tab
-
.delete
- (捕獲 “刪除” 和 “退格” 鍵)
.esc
.space
.up
.down
.left
.right
組合使用,單獨(dú)是使用的話,和click都是一樣的,這里組合使用有點(diǎn)特殊,使用 . 進(jìn)行連接簡(jiǎn)單給個(gè)例子
<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:'萬(wàn)年的msg' } }) -
多行文本---注意了啊:在文本區(qū)域插值(
<textarea></textarea>) 并不會(huì)生效,應(yīng)用v-model來(lái)代替<div id="app"> <p style="white-space: pre"> {{msg}} </p> <br> <textarea type="text" v-model="msg"></textarea> </div> -
復(fù)選框
-
單個(gè)復(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 } }) -
多個(gè)復(fù)選框(將選中的所有value綁定到一個(gè)數(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元素上)
-
單選列表(綁定到被選中項(xiàng)的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:'' } })
-
* 多選列表(綁定一個(gè)數(shù)組,數(shù)組的內(nèi)容是所有的選中項(xiàng)的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: []
}
})
```
* 動(dòng)態(tài)選項(xiàng)
```
<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:'萬(wàn)年的msg' } })
-
-
.number
- 將輸入的類型轉(zhuǎn)換成數(shù)字類型(NaN則還是原有類型)
-
.trim
- 去除兩端空白
算了,這點(diǎn)太簡(jiǎn)單了,不給例子了,自己寫去吧,別來(lái)煩我,有不會(huì)的群里問(wèn)......
v-model與組件
組件
使用組件
-
注冊(cè)
-
注意事項(xiàng)
在初始化根實(shí)例前一定要確保注冊(cè)了組件
-
名稱最好 小寫(可以使用短桿)
<div id="app"> <my-comp></my-comp> </div>
-
Vue.component('my-comp',{
template:'<h3>我是新出爐的組件</h3>'
})
new Vue({
el: "#app",
data: {
}
})
```
-
局部注冊(cè)
<div id="app"> <my-comp></my-comp> </div> new Vue({ el: "#app", components:{ 'my-comp':{template:'<h3>我是新出爐的組件</h3>'} }, data: { } }) -
DOM模板解析說(shuō)明
-
自定義組件在這些元素內(nèi)受限
ul
ol
table
select
-
概要: 解決方案是 使用 特殊的is屬性
<div id="app"> <table><tr>
<my-comp></my-comp>//注意:這樣寫是絕對(duì)錯(cuò)誤的,因?yàn)閠r中只允許有td,這樣寫他是不認(rèn)識(shí)滴
</tr></table> </div> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 上邊是錯(cuò)誤的
-
---------------------------------下邊是正確的-----------------------------------
<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"> 怎么用呢?給大家來(lái)個(gè)例子吧!
```
-------------------------------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> //這個(gè)就是字符串模板
<my-comp></my-comp>
</template>
</tr>
</table>
</div>
```
* .vue組件 (第三種不解釋了,用了那么多遍了,要是還不會(huì),我就開(kāi)始瘋狂嘲笑你)
* data必須是函數(shù),在組件中使用data中定義的數(shù)據(jù),必須使用函數(shù)返回,其實(shí)這事要說(shuō)為啥,還得從根上說(shuō),我自己的理解,最根本的三個(gè)字就是作用域,目的就是為了防止組件中使用的data和vue實(shí)例中的data進(jìn)行相互污染,有機(jī)會(huì)的話可以給大家講一下,但是這不是三句兩句就能講清楚的,門票一人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="我是來(lái)自于父組件的內(nèi)容"></child> </div> new Vue({ el: "#app", components:{ 'child':{ props:['msg'], template:'<h2>{{msg}}</h2>' } } })動(dòng)態(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注意事項(xiàng)
- 一般情況下是數(shù)組形式,如果要想規(guī)定props的數(shù)據(jù)類型(后面用中括號(hào) [ ])。默認(rèn)值等(見(jiàn)props驗(yàn)證),則是對(duì)象了(后面用花括號(hào) { })
關(guān)于命名:要不然全小寫,要不然kebabCase(駝峰式),kebab-case(短橫線隔開(kāi)式)Vue 能夠正確識(shí)別出小駝峰和下劃線命名法混用的變量,如這里的
forChildMsg和for-child-msg是同一值。-
,如果出不來(lái),先檢查一下命名,看個(gè)例子:
老濕老濕,幫我看下我寫的這個(gè)哪里錯(cuò)了?---呵呵呵,我哪知道,我也不會(huì) <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' } }) -
動(dòng)態(tài)Prop(使用v-bind):在模板中,要?jiǎng)討B(tài)地綁定父組件的數(shù)據(jù)到子組件模板的 props,和綁定 Html 標(biāo)簽特性一樣,使用v-bind綁定
- 局部注冊(cè)組件
- 全局注冊(cè)組件
字面量語(yǔ)法vs動(dòng)態(tài)語(yǔ)法
-
單向數(shù)據(jù)流
-
解釋
-
父組件數(shù)據(jù)更新后,子組件的所有prop都會(huì)更新為最新值,但是反過(guò)來(lái)就不會(huì)。(注意 :如果prop為數(shù)組或?qū)ο髸r(shí),子組件改變prop,父組件的狀態(tài)也會(huì)受到影響,因?yàn)閿?shù)組或?qū)ο笫且妙愋?,他們指向同一個(gè)內(nèi)存空間。)如果子組件的prop值被修改,則vue會(huì)給出警告。試一下下邊這個(gè)例子
<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)對(duì)方法
-
prop作為初始值傳入后,可能子組件想把它當(dāng)做局部數(shù)據(jù)來(lái)用的情況
-
方法:定義一個(gè)局部變量,并用prop的值初始化它
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } } //直接使用counter作為子組件的局部變量就可以了
-
-
prop作為初始值傳入,可能子組件處理成其他數(shù)據(jù)輸出的情況,比如處理成去空格并大寫
-
方法:定義一個(gè)計(jì)算屬性,處理prop的值并返回
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
-
-
-
-
prop驗(yàn)證
-
例子--代碼篇
Vue.component('example', { props: { // 基礎(chǔ)類型檢測(cè) (`null` 意思是任何類型都可以) propA: Number, // 多種類型 propB: [String, Number], // 必傳且是字符串 propC: { type: String, required: true }, // 數(shù)字,有默認(rèn)值 propD: { type: Number, default: 100 }, // 數(shù)組/對(duì)象的默認(rèn)值應(yīng)當(dāng)由一個(gè)工廠函數(shù)返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, // 自定義驗(yàn)證函數(shù) propF: { validator: function (value) { return value > 10 } } } })
-
自定義事件(子組件將數(shù)據(jù)傳回父組件)
-
使用v-on綁定自定義事件
給組件綁定自定義事件例子(用v-on來(lái)監(jiān)聽(tīng)子組件觸發(fā)的事件)
-
給組件綁定原生事件例子--使用native修飾符
<div id="app"> <btncomp @click.native="alertE"></btncomp> </div> new Vue({ el: "#app", components:{ btncomp:{ template:'<button>點(diǎn)擊我彈出</button>' } }, methods:{ alertE(){ alert(777) } } })
-
.sync修飾符(vue 2.3)
目的:使父子組件實(shí)現(xiàn)prop類似“雙向數(shù)據(jù)綁定”(默認(rèn)子組件無(wú)法更改prop的值,上邊已經(jīng)說(shuō)到了,但是使用sync后子組件可以改變prop 的值,并傳回父組件)
-
使用范例
<div id="app"> <child :name.sync="name"></child> //其實(shí)不加也能更改,但是會(huì)報(bào)錯(cuò) <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' } }, }) // 實(shí)例化一個(gè)Vue對(duì)象 const app = new Vue({ el: '#app', data(){ return { name: 'world' } }, methods:{ changePropsInFather(){ this.name='I am from father' }, }, })
-
使用自定義事件的表單輸入組件
-
v-model的語(yǔ)法糖(可能之前我在CNODE課程中講過(guò),但是提的不是特別的仔細(xì),這里還是給大家再說(shuō)一下)
<div id="app"> <input v-model="price"> </div> new Vue({ el: '#app', data: { price: '' } });我們對(duì)v-model已經(jīng)再熟悉不過(guò)了,一般都是像上邊這樣的用法,但是v-model只是一個(gè)語(yǔ)法糖,它的真身是下邊這樣:
<div id="app"> <input type="text" :value="price" @input="price = $event.target.value">{{price}} </div> new Vue({ el: '#app', data: { price: '' } });
-
* 例子
* html及實(shí)例部分和注冊(cè)組件部分
```
<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就是子組件傳遞過(guò)來(lái)的
this.price = val;
}
}
})
```
非父子組件通信
-
非父子組件通信(1 父?jìng)髯邮怯胮rops 2 子傳父在vue中是不允許的,因?yàn)関ue只允許單向數(shù)據(jù)傳遞,這時(shí)候我們可以通過(guò)觸發(fā)事件來(lái)通知父組件改變數(shù)據(jù),從而達(dá)到改變子組件數(shù)據(jù)的目的. 3 那么非父子組件之間通信怎么搞??????)
-
簡(jiǎn)單的場(chǎng)景---采用空實(shí)例作為中央事件總線,原理就是找一個(gè)人來(lái)當(dāng)作一個(gè)中轉(zhuǎn)站!
<div id="app1" @click="toApp2"> 我是組件一,點(diǎn)擊我給二傳值 </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)建完成的時(shí)候就使用中轉(zhuǎn)站進(jìn)行監(jiān)聽(tīng) }) } })
-
* 復(fù)雜的場(chǎng)景---專門的狀態(tài)管理模式vuex
使用Slot分發(fā)內(nèi)容
-
內(nèi)容分發(fā)概念
-
為了讓組件可以組合(如本子主題的例子),因此需要混合父組件的內(nèi)容與子組件的自己模板,這一過(guò)程就稱作內(nèi)容分發(fā)。
<app> <app-header></app-header> <app-footer></app-footer> </app> 之前我們的組件,如果給app指定了模板,那么里邊的app-header和foot組件的內(nèi)容就會(huì)被覆蓋,因此,為了讓他們能夠組合.需要混用,這就是內(nèi)容分發(fā)
-
-
編譯作用域
- 分發(fā)內(nèi)容是在父作用域內(nèi)編譯的
-
單個(gè)slot(無(wú)具名slot)
-
為什么用slot
-
當(dāng)父組件中有內(nèi)容(即自定義的標(biāo)簽名之間有元素--見(jiàn)本子主題的例子) 子組件模板中無(wú)slot時(shí),則父組件中的內(nèi)容會(huì)被丟棄。
<div id="app"> <my-comp> <p>我是組件中的內(nèi)容</p> //這個(gè)p會(huì)被覆蓋 </my-comp> </div> new Vue({ el: "#app", components:{ 'my-comp':{ template:'<h1>我是一個(gè)組件</h1>' } } })
-
-
* 那么單個(gè)slot怎么用呢?
```
<div id="app">
<children>
<span>12345</span>
<!--上面這行不會(huì)顯示-->
</children>
</div>
var vm = new Vue({
el: '#app',
components: {
children: { //這個(gè)無(wú)返回值,不會(huì)繼續(xù)派發(fā)
template: "<button><slot></slot>(我是button)</button>"
}
}
});
```
* 當(dāng)父組件中有內(nèi)容時(shí)
* 子組件中的slot會(huì)被父組件中內(nèi)容所替換。(slot標(biāo)簽也會(huì)被替換掉)
* 當(dāng)父組件中無(wú)內(nèi)容時(shí)
* 子組件中slot內(nèi)容會(huì)被顯示出來(lái)
-
具名slot
-
用法:保子引父(保持子組件模板,引入父組件參數(shù))--嚴(yán)格按照子組件的模板順序來(lái)即:遇到具名slot對(duì)應(yīng)的元素就渲染相應(yīng)的元素,遇到不具名的slot,則會(huì)渲染除了具名slot對(duì)應(yīng)的元素以外的所有元素。
<div id="app"> <children> <span slot="first">12345</span> <span slot="second">56789</span> <!--上面這行不會(huì)顯示--> </children> </div> var vm = new Vue({ el: '#app', components: { children: { //這個(gè)無(wú)返回值,不會(huì)繼續(xù)派發(fā) template: "<button><slot name='first'></slot>我是button<slot name='second'></slot>所以使用button標(biāo)簽</button>" } } }); 總結(jié):說(shuō)白了,就是多一個(gè)name屬性.沒(méi)啥稀奇玩意
-
-
作用域插槽(特殊的插槽)
作用:使用可復(fù)用模板替代已渲染元素
-
用法:同具名slot類似,都是嚴(yán)格按照子組件的模板順序渲染,只不過(guò)遇到slot元素時(shí)會(huì)將父組件中的template元素里的元素全部渲染
-
列表組件例子
<div id="app"> <child :items="items"> <template slot="item" scope="props"> <!--必須存在的具有 scope屬性的 template元素(作用域插槽的模板), props臨時(shí)的變量名稱,接受子組件中傳遞的props對(duì)象--> <!--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:'雞'}
]
}
})
```
動(dòng)態(tài)組件
-
使用is屬性(注意,is前使用了v-bind?。?!通過(guò)is來(lái)決定那個(gè)組件被渲染顯示 )
<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)或避免重新渲染(包裹動(dòng)態(tài)組件時(shí)會(huì)緩存不活動(dòng)的組件實(shí)例而不是銷毀它們)配合 <keep-alive>使用時(shí),可以保留組件狀態(tài)避免重新渲染(和v-show 比較的差別是v-show 是一開(kāi)始就渲染的所有組件,而keep-alive 并不是一開(kāi)始就渲染好所有組件,而已保留渲染過(guò)的組件
注意事項(xiàng):使用環(huán)境應(yīng)該是較大頁(yè)面頻繁切換的情景下
-
用法
<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' } } } })
總結(jié)
- 這些就基本涵蓋了vue的基礎(chǔ)知識(shí),大家都知道,經(jīng)濟(jì)基礎(chǔ)決定上層建筑,學(xué)知識(shí)也是一樣,只有基礎(chǔ)知識(shí)掌握牢固,你才有機(jī)會(huì),有資格去學(xué)習(xí)vue中更加高級(jí)的用法,比如異步組件,嵌套組件等等,好了,感謝大家看到這里,有問(wèn)題可以群里交流