簡介
Vue (讀音 /vjuː/,類似於 view) 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合。另一方面,當與現代化的工具鏈以及各種支援類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動。
指令
v-bind 動態的繫結資料
<div v-bind:color="color"></div>
// 簡寫形式
<div :color="color"></div>
複製程式碼
v-text 更新元素的文字內容
<div v-text="content"></div>
複製程式碼
v-html 更新元素的 innerHTML
<div v-html="content"></div>
複製程式碼
v-cloak 隱藏未編譯的 Mustache 標籤直到例項準備完畢 配合樣式使用
//樣式
[v-cloak]{
display: none;
}
<div id="app" v-cloak>
{{content}}
</div>
複製程式碼
v-once 只渲染一次
<div v-once>只渲染一次: {{content}}</div>
複製程式碼
v-for 迴圈
//迴圈陣列
<div id="app">
<ul>
<li v-for="book in books">{{book}}</li>
</ul>
<ul>
<li v-for="(book,index) in books">{{index}} - {{book}}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
books: ['javascript','nodejs','vuejs']
}
})
複製程式碼
//迴圈物件
<div id="app">
<ul>
<li v-for="value in user">{{value}}</li>
</ul>
<ul>
<li v-for="(value,key) in user">{{key}} : {{value}}</li>
</ul>
<ul>
<li v-for="(value,key,index) in user">{{index}} - {{key}} : {{value}}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
user: {
name: 'js',
age: 18,
city: 'china'
}
}
})
複製程式碼
v-if 根據表示式的值的真假條件渲染元素和移出元素
<div v-if="true">我被渲染了</div>
<div v-if="false">我不會被渲染</div>
複製程式碼
v-show 根據表示式的值的真假條件,切換元素的display屬性
<div v-show="true">我顯示了</div>
<div v-show="false">我隱藏了</div>
複製程式碼
v-model 在表單控制元件或者元件上建立雙向繫結
<div>
<input v-model="message" type="text" />
</div>
<h2>{{message}}</h2>
new Vue({
el: '#app',
data: {
message: 'hello vue'
}
})
複製程式碼
v-on 繫結事件處理函式監聽 DOM 事件,簡寫為@
<div v-on:click="clickHandle">點選事件</div>
<div @click="clickHandle">點選事件</div>
// 需要手動傳入$event事件物件
<div v-on:click="clickHandle($event,params)">點選事件</div>
//事件處理函式中的this都指向例項
new Vue({
el: '#app',
data: {},
methods: {
clickHandle(event,params){
console.log(event)
}
}
})
複製程式碼
事件修飾符
- .stop 阻止冒泡
- .prevent 阻止預設事件
- .capture 捕獲事件
- .self 事件源是本身才出發
- .once 只觸發一次
- .left 點選滑鼠左鍵時觸發
- .right 點選滑鼠右鍵時觸發
- .middle 點選滑鼠中鍵時觸發
按鍵修飾符
- .enter
- .tab
- .delete
- .es
- .space
- .up
- .down
- .left
- .right
new Vue({
el: '#app',
data: {},
methods: {
clickA(){
alert('我是A');
},
clickB(){
alert('我是B');
}
}
})
複製程式碼
//阻止冒泡
<div @click="clickA">
我是A
<div @click.stop="clickB">
我是B
</div>
</div>
複製程式碼
//self
<div @click="clickA">
我是A
<div @click.self="clickB">
我是B
</div>
</div>
複製程式碼
//捕獲
<div @click="clickA">
我是A
<div @click.capture="clickB">
我是B
</div>
</div>
複製程式碼
//阻止預設事件
<a @click.prevent href="http://www.juejin.com">阻止預設事件</a>
複製程式碼
//只觸發一次
<div @click.once="clickA">只觸發一次</div>
複製程式碼
選項卡例項
<style>
button.active{
background: yellow;
}
.card{
padding: 10px;
width: 500px;
height: 500px;
border: 1px solid #ccc;
display: none;
}
.card.active{
display: block;
}
</style>
複製程式碼
<div id="app">
<div>
<button v-for="(book,index) in books" @click="showTab(index)" :class="{active: tabIndex==index}" type="button">{{book.name}}</button>
</div>
<div v-for="(book,index) in books" :class="{active: tabIndex==index}" class="card">
<h2>{{book.name}}</h2>
<p>{{book.info}}</p>
</div>
</div>
複製程式碼
new Vue({
el: '#app',
data: {
books: [
{
name: 'javascript',
info: 'JavaScript一種直譯式指令碼語言,是一種動態型別、弱型別、基於原型的語言,內建支援型別。'
},
{
name: 'nodejs',
info: 'Node.js是一個Javascript執行環境(runtime environment),釋出於2009年5月,由Ryan Dahl開發,實質是對Chrome V8引擎進行了封裝。'
},
{
name: 'vuejs',
info: 'Vue是一套用於構建使用者介面的漸進式框架。'
}
],
tabIndex: 0
},
methods: {
showTab(i){
this.tabIndex = i;
}
}
})
複製程式碼
雙向資料繫結
雙向資料繫結
Vue將資料物件和DOM進行繫結,彼此之間互相產生影響,資料的改變會引起DOM的改變,DOM的改變也會引起資料的變化
MVVM模式
<div>
<input v-model="message" type="text" />
</div>
<h2>{{message}}</h2>
new Vue({
el: '#app',
data: {
message: 'hello vue'
}
})
複製程式碼
響應式原理
- 把一個普通的 JavaScript 物件傳給 Vue 例項的 data 選項
- Vue 將遍歷此物件所有的屬性,並使用 Object.defineProperty 把這些屬性全部轉為 getter/setter
- Vue內部會對資料進行劫持操作,進而追蹤依賴,在屬性被訪問和修改時通知變化
Object.defineProperty
- 作用:直接在一個物件上定義一個新屬性,或者修改一個物件的現有屬性
- 語法:Object.defineProperty(obj, prop, descriptor)
- 引數:(物件,屬性,屬性描述符/存取器描述)
[屬性描述符]
是否可配置刪除,預設false
configurable: false
是否可列舉,預設false
enumerable: false
屬性值,預設undefined
value: undefined
是否可被重寫,預設false
writable: false
[存取器描述]
獲得屬性值的方法
getter: function(){}
設定屬性值的方法
setter: function(){}
複製程式碼
//新增修改物件屬性
let obj = {
a: 1,
b: 2
}
Object.defineProperty(obj, 'a', {
value: 3
});
Object.defineProperty(obj, 'c', {
configurable: true,
enumerable: true,
value: 4,
writable: true
});
console.log(obj) //{a: 3, b: 2, c: 4}
複製程式碼
- 使用defineReactive劫持資料
//劫持資料
function observer(data,cb){
Object.keys(data).forEach( (key) => {
defineReactive(data,key,data[key],cb)
})
}
//轉換getter,setter
function defineReactive(obj,key,value,cb){
Object.defineProperty(obj,key,{
get(){
return value;
},
set(newValue){
value = newValue;
cb(newValue);
}
})
}
複製程式碼
- 使用Proxy劫持資料
function observer(data,cb){
return new Proxy(data,{
get(target,attr){
return target[attr];
},
set(target,attr,newValue){
target[attr] = newValue;
cb(newValue);
}
});
}
複製程式碼
<button id="btn" type="button">改變內容</button>
<div id="content"></div>
let content = document.querySelector('#content');
let btn = document.querySelector('#btn');
let data = {
text: 'Vue是一套用於構建使用者介面的漸進式框架。'
}
observer(data,function(newVal){
content.innerHTML = newVal;
})
content.innerHTML = data.text;
btn.onclick = function(){
data.text = '內容改變了';
}
複製程式碼
選項
data
Vue 例項的資料物件
methods
事件處理器
computed
- 計算屬性定義在computed中,它不是方法,屬性的值是函式的返回值。
- 把對處理資料的邏輯抽離在計算屬性中,使得模板更加輕量易讀
- 計算屬性的值會被快取,並根據依賴的資料變化而重新計算
//預設設定的get函式
new Vue({
el: '#app',
data: {
a: 1
},
computed: {
b(){
return 2;
}
}
})
//設定get,set函式
new Vue({
el: '#app',
data: {
a: 1
},
computed: {
b: {
get(){
return 2;
},
set(newVal){
this.b = newVal;
}
}
}
})
複製程式碼
watch
watch觀察 Vue 例項上的資料變動,鍵是需要觀察的表示式,值是對應回撥函式
let vm = new Vue({
el: '#app',
data: {
html: 'html',
js: {
javascript: 'javascript',
nodejs: 'nodejs',
vuejs: 'vuejs'
}
},
watch: {
html(newVal,oldVal){
console.log(newVal,oldVal) // -> 改變html html
}
}
})
vm.html = '改變html';
複製程式碼
//深度監控
let vm = new Vue({
el: '#app',
data: {
html: 'html',
js: {
javascript: 'javascript',
nodejs: 'nodejs',
vuejs: 'vuejs'
}
},
watch: {
'js.vuejs':{
handler(newVal,oldVal){
console.log(newVal,oldVal) // -> 改變vuejs vuejs
},
deep: true
}
}
})
vm.js.vuejs = '改變vuejs';
複製程式碼
//偵聽開始之後被立即呼叫
let vm = new Vue({
el: '#app',
data: {
html: 'html',
js: {
javascript: 'javascript',
nodejs: 'nodejs',
vuejs: 'vuejs'
}
},
watch: {
html:{
handler(newVal,oldVal){
console.log(newVal,oldVal) // -> html undefined
},
immediate: true
}
}
})
複製程式碼
響應的資料變化
- Vue.set( target, key, value )
- vm.$set( target, key, value )
<div id="app">
<button @click="addCity1" type="button">Vue新增城市屬性</button>
<button @click="addCity2" type="button">vm新增城市屬性</button>
<ul>
<li v-for="(value,key) in user">{{key}} : {{value}}</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
user: {
name: 'js',
age: 18
}
},
methods: {
addCity1(){
Vue.set( this.user, 'city', 'china' )
},
addCity2(){
this.$set( this.user, 'city', 'china' )
}
}
})
複製程式碼