vue數(shù)據(jù)驅(qū)動
vue主要操作的是數(shù)據(jù)
數(shù)據(jù)類型
- 基本 number string boolean null undefined
- Object function
- Symbol(es6)
對象{ } 數(shù)組[]
數(shù)組的變異(括號中能改變原數(shù)組)
- 操作數(shù)組的方法
es4:(pop push unshift前面增加 shift前面減少 splice reverse sort )indexOf lastIndexof concat(拼接數(shù)組)slice
es5
forEach filter map some every reduce includes find
前面都有不贅述
框架和庫
- 框架 vue
- 庫 jquery underscore
框架和庫的區(qū)別,框架擁有完整的解決方案昨登,我們寫好框架調(diào)用我們的大年,庫是我們調(diào)用他
vue.js是漸進(jìn)式的
- 通過組合完成一個完整的框架
- vue全家桶 核心為vue.js+vue-router(單頁應(yīng)用)+vuex(狀態(tài)管理)+axios(獲取數(shù)據(jù))
vue特點(diǎn)
- 核心只關(guān)注圖層
- 輕量列另,靈活
- 適用于移動端
- 漸進(jìn)式框架
漸進(jìn)式
- 聲明式渲染(不關(guān)系怎么實(shí)現(xiàn)的)
- 組件系統(tǒng)
- 客戶端路由(vue-route)
- 大規(guī)模狀態(tài)管理(vuex)
- 構(gòu)建工具(vue-cli)
核心店
- 響應(yīng)的數(shù)據(jù)變化
當(dāng)數(shù)據(jù)發(fā)生變化,視圖自動更新
MVC(backbone) 單向的
- model 數(shù)據(jù)
- view 視圖
- controller 控制器
控制器獲取數(shù)據(jù)->傳遞給業(yè)務(wù)模型->渲染視圖->反饋給用戶MVVM(angular,vue) 雙向的
- model數(shù)據(jù) plan JavaScript Object 計劃好的JS對象
- view視圖 是DOM
- viewModel 視圖模型
view-> view model DOM listensers實(shí)時映射->model
model->view model 中data binding->view
- 組合的視圖組件
UI頁面映射為組件樹
劃分組件可維護(hù)虏劲,可復(fù)用,可測試
安裝vue
通過cdn
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
第一個程序
按照之前的介紹,首先需要一個視圖模型
let vm=new Vue()
然后需要將View控制的DOM告訴它
let vm=new Vue({
el:'#app'})
然后是VM代理的數(shù)據(jù)
let vm=new Vue({
el:'#app',
data:{msg:'大白熊'}
});
最后將數(shù)據(jù)在頁面顯示
<div id="app">
{{msg}}
</div>
全部程序
<body>
<div id="app">
{{msg}}
<!--這里換行會出現(xiàn)問題-->
<!--希望在頁面中展示data-->
<!--moustache語法的猛,表達(dá)式耀盗,可以放賦值,取值卦尊,三元-->
</div>
</body>
<script>
//vue的構(gòu)造函數(shù)叛拷,看到構(gòu)造函數(shù)就總是要new
let vm=new Vue({
el:'#app',
//element,告訴它當(dāng)前歸view管理的DOM,只能掛載在普通的元素上,html和body不行
data:{msg:'大白熊'
//data中的數(shù)據(jù)會被VM所代理岂却,可以通過vm.msg取到對應(yīng)的內(nèi)容
}
});
視圖控制數(shù)據(jù)
現(xiàn)在只能數(shù)據(jù)控制視圖忿薇,還做不到視圖控制數(shù)據(jù)
- input
- checkbox
- textarea
- radio
- select
這里需要用到vue的指令
vue的指令
只是dom的行間屬性,vue給這類屬性賦予了一定的意義躏哩。來實(shí)現(xiàn)特殊的功能署浩,所有的指令都以v-開頭
現(xiàn)在需要將頁面上的數(shù)據(jù)傳遞到VM中,以input框舉例
{{msg}}
<input type="text" v-model="msg">
<!-- 先將數(shù)據(jù)寫入輸入框扫尺,再改變輸入框后筋栋,改變數(shù)據(jù)-->
這時改變input中的值,頁面上的值也會改變
值得注意的是
value,checked,selected屬性一般會被vue忽略
vue沒有大寫的屬性
v-model會將msg的值賦予輸入框正驻,輸入框的值影響數(shù)據(jù)
數(shù)據(jù)改變input中的值也會改變
defineProperty
為對象定義屬性
let obj={}
Object.defineProperty(obj,'name',{
configurable:false,//是否可刪除
writable:false,//是否可重新賦值
enumerable:false,//是否可枚舉
value:1//值
get(){
//取obj的name屬性會觸發(fā)
return value弊攘;
},
set(val){
//給obj賦值會觸發(fā)set方法
}
})
//obj {"name":1}
基本指令
1. v-text==={{}}
代碼從上到下執(zhí)行,{{msg}}會先執(zhí)行姑曙,然后vm再渲染襟交,利用v-text可以解決這個問題
<div id="app" v-text="msg"></div>
msg這里也可以寫表達(dá)式
2. v-once
只綁定一次,數(shù)據(jù)再次變化渣磷,頁面不會刷新
<div v-once>
{{msg}}
</div>
v-once不用賦值
3. v-html
把html字符當(dāng)作html渲染,一定是可以信任的html
直接
{{p}}
輸出在頁面上的會是
<p>大白熊</p>
不符合我們的要求
所以需要
<div v-html="p"></div>
4. v-if
v-if指令是根據(jù)表達(dá)式的值來決定是否插入頁面元素
v-else
v-else-if
和v-if搭配使用
<div id="app">
<div v-if="type==='A'">A</div>
<div v-else-if="type==='B'">B</div>
<div v-else-if="type==='C'">C</div>
</div>
<script>
let VM=new Vue({
el:"#app",
data:{
type:'C'
}
})
</script>
5. v-show
根據(jù)表達(dá)式的布爾值婿着,決定是否顯示頁面元素
6. v-for
可以綁定一組數(shù)據(jù)來渲染一個列表
表達(dá)式有以下幾種形式
- site in sites sites 是源數(shù)據(jù)數(shù)組并且 site 是數(shù)組元素迭代的別名
<div id="app">
<ol>
<li v-for="site in sites">
{{ site.name }}
</li>
</ol>
</div>
<script>
new Vue({
el: '#app',
data: {
sites: [
{ name: 'aaa' },
{ name: 'bbb' },
{ name: 'ccc' }
]
}
})
</script>
- value in object 對象的屬性
<div id="app">
<ul>
<li v-for="value in object">
{{ value }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
object: {
name: 'aaa',
age: 12,
}
}
})
</script>
- (value, key) in object
<div id="app">
<ul>
<li v-for="(value, key) in object">
{{ key }} : {{ value }}
</li>
</ul>
</div>
- (value, key, index) in object
<div id="app">
<ul>
<li v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
</div>
- n in 10 循環(huán)整數(shù)
數(shù)據(jù)響應(yīng)的變化
對象
- 使用變量前先要初始化,否則新加的屬性并不會導(dǎo)致頁面刷新
如果{{}}中是VM data中不存在的項(xiàng)醋界,會報錯
如果是存在的項(xiàng)不存在的屬性竟宋,不會報錯
但是這時給這個屬性賦值并不會有效果
vue會循環(huán)data中的數(shù)據(jù)(數(shù)據(jù)劫持),以此增加getter和setter
<div id="app">
{{a.school}}
<!--如果不存在a會報錯,但是調(diào)用a不存在的屬性并不會-->
<!--vue會循環(huán)data中的數(shù)據(jù)(數(shù)據(jù)劫持),以此增加getter和setter-->
<!--但是如果這時給school賦值也并不會改變頁面-->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm=new Vue(
el:"#app",
data:{
a:{}
}
)
這時給school賦值也不會有更新
- 對于不存在的屬性形纺,想要增加屬性使用
vm.$set(vm.a,'school',1)
第一個變量是對象丘侠,第二個是增加的屬性,第三個是數(shù)據(jù)
- 替換原對象
vm.a={school:"1",age:"8"}
數(shù)組
想要取固定位置的項(xiàng)逐样,可以直接取
<div id="app">
{{arr[1]}}
</div>
在script直接改變數(shù)組相應(yīng)位置的項(xiàng)蜗字,監(jiān)控不到
同理長度也不會
<div id="app">
{{arr}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm=new Vue({
el:"#app",
data:{
arr:[1,2,3,4,5]
}}
)
vm.arr[0]=100
console.log(vm.arr)
//顯示是[1,2,3,4,5],但是console.log()是[100,2,3,4,5]
</script>
利用變異方法可以改變頁面顯示的數(shù)組
let vm=new Vue({
el:"#app",
data:{
arr:[1,2,3,4,5]
}}
)
vm.arr[0]=100
console.log(vm.arr)
//顯示是[1,2,3,4,5]脂新,但是console.log()是[100,2,3,4,5]
//變異方法:pop push shift unshift sort reverse splice 利用這些方法可以修改頁面中顯示的項(xiàng)
//如果是利用不修改的方法挪捕,重新賦值即可
vm.arr.reverse();
//而且這時的數(shù)組是經(jīng)過了改變項(xiàng)目的 輸出為[5,4,3,2,100]
也可以重新賦值
vm.arr=vm.arr.map(item=>item+3)
數(shù)組的循環(huán)
v-for會更高效解決循環(huán)問題,復(fù)用原有結(jié)構(gòu)
v-for這里的值是 隨便一個名稱 in xxx,這里xxx是data中屬性名稱争便,比如例子中的animals
{{}}中是v-for第一個 名稱.屬性值 级零,不能直接用數(shù)組中屬性名稱,例子中 animals.name會無顯示
和forEach相似滞乙,例子中a就相當(dāng)于item
<div id="app">
<ul>
<li v-for="a in animals"> {{a.name}}</li>
<!--循環(huán)誰在誰身上加v-for屬性鉴嗤,這里要循環(huán)的是li不是ul-->
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm=new Vue({
el:"#app",
data:{
animals:[{"name":"大白熊"},{"name":"北極熊"},{"name":"企鵝"}]
}
}
)
(a,index) in animals也可以
in 替換成of 也可以
層疊式的列表
當(dāng)數(shù)組的每一項(xiàng)有另一個數(shù)組時,也可以生成新的子列表
<div id="app">
<ul>
<li v-for="(animal,index) in animals">{{index+1}}.{{animal.name}}
<ul>
<!--這里index的值還是上一步的序调,所以index名需要換一個-->
<li v-for="(age,index2) in animal.age">
{{index+1}}.{{index2+1}}.{{age}}
</li>
</ul>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm=new Vue({
el:"#app",
data:{
animals:[{"name":"大白熊","age":[12,2,5]},{"name":"北極熊","age":[25,4,8]},{"name":"企鵝","age":[2,8,15]}]
}
}
)
一般情況下不會出現(xiàn)三維數(shù)組
字符串,數(shù)字和對象的循環(huán)
<div v-for="c in 'aaa'">{{c}}</div>
<div v-for="c in5">{{c}}</div>
<div v-for="(value,key,index) in obj">{{index+1}}.{{key}}:{{value}}</div>
事件
- 原生點(diǎn)擊事件
<!--所有的事件函數(shù)都要是在window上的-->
<div id="app" onclick="fn()">點(diǎn)擊事件</div>
<!--必須要加()才能執(zhí)行函數(shù)-->
<script>
function fn()
{
alert("點(diǎn)擊")
}
</script>
- vm事件
v-on:事件名稱=""
事件名稱可以使click醉锅,mouseon,mousedown等
method和data全部數(shù)據(jù)都會放在VM中所以名字不能沖突发绢,method中的this指向的都是實(shí)例硬耍,返回的數(shù)據(jù)會是data中的數(shù)據(jù)
事件函數(shù)不能重復(fù)定義,會報錯
<div id="app">
<div v-on:click="fn"></div>
<!--傳參加括號朴摊,不傳參不加,否則會自動傳為事件源-->
<!--需要傳event的時候用$event-->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm=new Vue({
el:"#app",
methods:{
fn(){alert("click")}
},
data:{
//為了區(qū)分默垄,這里全部放數(shù)據(jù)
//fn不要重復(fù)定義
}
})
v-on簡寫為@
<div @click="fn"></div>
傳參加括號此虑,不傳參不加,否則會自動傳為事件源
需要傳event的時候用$event
實(shí)例
現(xiàn)在做一個可增添刪減的列表甚纲,點(diǎn)擊回車將數(shù)據(jù)input上的數(shù)據(jù)傳遞到VM中,然后更新列表
三個部分
- 輸入數(shù)據(jù)的input
- 列表
- 刪除鍵
input部分
<input type="text" v-model="newitem" @keyup="addnew">
增加完畢后
需要在methods中定義按下回車時的函數(shù)朦前,這里methods必須是methods少打s會報錯
addnew(event){
if(event.key=="Enter")
{
this.animals.push(this.newitem)
}
}
同時data中需要有animals和newitem
data:{
newitem:"",
animals:["大白熊","兔子","狼"]
}
列表
簡單的v-for構(gòu)建的列表
<ul>
<li v-for="(animal,index) in animals" style="line-height:60px;">
{{animal}}
</li>
</ul>
此時添加功能就已經(jīng)完成了
刪除功能
在每個li中加入一個按鍵介杆,點(diǎn)擊時調(diào)用函數(shù),給這個函數(shù)傳入index函數(shù)韭寸,再利用filter將符合的值剔除掉
注意filter并不會改變原來的數(shù)組春哨,所以需要利用賦值改變原來的數(shù)組
<ul>
<li v-for="(animal,index) in animals" style="line-height:60px;">
{{animal}}<button style="margin-left:30px" @click="del(index)">刪除</button>
</li>
</ul>
函數(shù)部分
del(i){
let newanimals=this.animals.filter((item,index)=>index!=i)
this.animals=newanimals
}
為了完善功能簡單的加入了遍歷數(shù)組彈出已經(jīng)有的項(xiàng)以及空項(xiàng)警告
addnew(event){
if(event.key=="Enter")
{
if(this.newitem=="")
{
alert("空項(xiàng)")
return
}
else if(this.animals.includes(this.newitem))
{
alert(this.newitem+"已經(jīng)存在")
return
}
else {
this.animals.push(this.newitem)
}
}
}
還有一種檢測按下鍵盤按鍵的方法
<input type="text" v-model="newitem" @keydown.enter>
多個按鍵也可以
<input type="text" v-model="newitem" @keydown.ctrl.enter>
``