vue介紹
什麼是vue
vue.js是一套構建用戶界面的漸進式框架,用來快速構建GUI頁面。
vue.js 通過儘可能簡單的 API 實現響應的數據綁定和組合的視圖組件。通過MVVM思想實現數據的雙向綁定,讓開發者不用再操作dom對象,有更多的時間去思考業務邏輯。
Vue.js 專注於 MVVM 模型的 ViewModel 層。它通過雙向數據綁定把 View 層和 Model 層連接了起來。實際的 DOM 封裝和輸出格式都被抽象爲了 Directives 和 Filters。
爲什麼使用vue.js
- 輕量級框架
vue.js通過簡潔的API提供高效的數據綁定和靈活的組件系統。 - 雙向數據綁定
vue.js會自動對頁面中某些數據的變化做出同步的響應。
也就是說,vue.js會自動響應數據的變化情況,並且根據用戶在代碼中預先寫好的綁定關係,對所有綁定在一起的數據和視圖內容都進行修改。
通過MVVM思想實現數據的雙向綁定,讓開發者不用再操作dom對象,有更多的時間去思考業務邏輯。 - 組件化
vue.js通過組件,把一個單頁應用中的各種模塊拆分到一個一個單獨的組件(component)中,我們只要先在父級應用中寫好各種組件標籤(佔坑),並且在組件標籤中寫好要傳入組件的參數(就像給函數傳入參數一樣,這個參數叫做組件的屬性),然後再分別寫好各種組件的實現(填坑),然後整個應用就算做完了。 - 視圖,數據,結構分離
使數據的更改更爲簡單,不需要進行邏輯代碼的修改,只需要操作數據就能完成相關操作 - 虛擬DOM
在傳統開發中,用JQuery或者原生的JavaScript DOM操作函數對DOM進行頻繁操作的時候,瀏覽器要不停的渲染新的DOM樹,導致頁面看起來非常卡頓。
vue.js使用虛擬DOM,可以預先通過JavaScript進行各種計算,把最終的DOM操作計算出來並優化,由於這個DOM操作屬於預處理操作,並沒有真實的操作DOM,所以叫做虛擬DOM。最後在計算完畢才真正將DOM操作提交,將DOM操作變化反映到DOM樹上。
如何使用vue.js
主要有兩種使用方式:
方式一:
直接在html中使用<script>引入。這種方式主要用來創建簡單的但頁面應用。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全棧工程師:vue小白學習</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue_app">
<h1>內容 : {{message}}</h1>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_app',
data: {
message: "hello,小白來了"
}
})
</script>
</body>
</html>
方式二:
使用vue-cli腳手架構建vue.js項目。這種方式也是工程項目中最主流的使用方式。
具體使用步驟如下:
(1)安裝vue-cli項目構建工具包
- 安裝npm
在用 vue.js 構建大型應用時推薦使用 npm 安裝,npm 能很好地和諸如 webpack 或 browserify 模塊打包器配合使用。vue.js 也提供配套工具來開發單文件組件。
在MAC系統上執行brew install npm - 安裝cnpm
在國內,使用淘寶的鏡像會比較快安裝一些包。
npm install -g cnpm --registry=https://registry.npm.taobao.org - 安裝vue
cnpm install vue - 安裝vue-cli
Vue 提供了一個官方的 CLI,爲單頁面應用快速搭建 (SPA) 繁雜的腳手架。它爲現代前端工作流提供了 batteries-included 的構建設置。只需要幾分鐘的時間就可以運行起來並帶有熱重載、保存時 lint 校驗,以及生產環境可用的構建版本
在國內,使用淘寶的鏡像會比較快安裝一些包。
cnpm install --global vue-cli
因爲vue命令去初始化項目的時候實際上還是使用的是npm去安裝各種模塊,並沒有使用cnpm,所以還是先設置npm使用淘寶中的鏡像比較快。
npm config set registry https://registry.npm.taobao.org - 創建基於 webpack 模板的新項目
使用webpack套件構建項目:vue init webpack front
(venv3.7) bruce-mac-pro: bruce.xu$ vue init webpack front
? Project name portal
? Project description automation test framework front_end
? Author Bruce Xu
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
-
安裝項目依賴
cnpm install -
啓動項目
cd front
npm run dev
在瀏覽器中導航到 http://localhost:8080
項目目錄詳解及各文件規範
(2)編寫vue代碼
step1: 在components目錄下創建組件Hello.vue
組件系統是vue的另一個重要概念,它是一種抽象,允許我們使用小型、獨立和通常可複用的組件構建大型應用。
<template>
<div>
vue小白來了:{{msg}}
</div>
</template>
<script>
export default {
name: 'TestProject',
data () {
return {
msg: '小白 hello world!!'
}
}
}
</script>
<style scoped>
div {
font-weight: normal;
color: brown
}
</style>
step2: 在router目錄下的index.js中添加路由
import Vue from 'vue'
import Router from 'vue-router'
import TestProject from '@/components/Hello'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Hello',
component: TestProject
}
]
})
step3: 打包發佈
在終端console輸入命令:npm run dev
瀏覽器打開: http://localhost:8080
vue基礎
本章節主要學習vue基礎,先從最簡單的但頁面vue項目開始。暫時不考慮vue-cli腳手架,從單頁面html嵌入vue.js的方式學習基礎用法。
vue實例
構造vue實例
ViewModel
一個同步 Model 和 View 的對象。
Vue.js 專注於 MVVM 模型的 ViewModel 層。它通過雙向數據綁定把 View 層和 Model 層連接了起來。在 Vue.js 中,每個 Vue 實例都是一個 ViewModel。它們是通過構造函數 Vue 或其子類被創建出來的。
通過用 Vue 函數創建一個新的 Vue 實例:
<script type="text/javascript">
var vm = new Vue({ //創建vue實例
el: '#vue_app', //綁定DOM元素
data: { //元素的數據
message: "hello,小白來了"
}
})
</script>
視圖 (View)
被 Vue 實例管理的 DOM 節點。
Vue.js 使用基於 DOM 的模板。每個 Vue 實例都關聯着一個相應的 DOM 元素。當一個 Vue 實例被創建時,它會遞歸遍歷根元素的所有子結點,同時完成必要的數據綁定。當這個視圖被編譯之後,它就會自動響應數據的變化。
我們幾乎不需要直接操作DOM,即可自動完成數據的更新。當數據發生變化時,視圖將會自動觸發更新。
<script type="text/javascript">
var vm = new Vue({ //創建vue實例
el: '#vue_app', //綁定DOM元素
data: { //元素的數據
message: "hello,小白來了"
}
})
</script>
vm.$el //視圖,即元素vue_app
模型 (Model)
Vue.js 中的模型就是普通的 JavaScript 對象——也可以稱爲數據對象。
例如,上例中的vm.$data這個對象,就是Model。
一旦某對象被作爲 Vue 實例中的數據,它就成爲一個 “反應式” 的對象了。你可以操作它們的屬性,同時正在觀察它的 Vue 實例也會收到提示。
vue的 實例vm代理了它們觀察到的數據對象的所有屬性。所以一旦一個對象 { a: 1 } 被觀察,那麼 vm.$data.a 和 vm.a 將會返回相同的值,而設置 vm.a = 2 則也會修改 vm.$data。
<script type="text/javascript">
var val = {a: 1}
var vm = new Vue({
el: '#vue_app',
data: val
})
// 獲得這個實例上的 property
// 返回源數據中對應的字段
// vm.a == val.a // => true
// vm.$data.a == val.a // => true
console.log(vm.a === val.a)
console.log(vm.$data.a === val.a)
</script>
指令 (Directives)
帶特殊前綴的 HTML 特性,可以讓 Vue.js 對一個 DOM 元素做各種處理。
<div v-text="message"></div>
這裏的 div 元素有一個 v-text 指令,其值爲 message。Vue.js 會讓該 div 的文本內容與 Vue 實例中的 message 屬性值保持一致。
Directives 可以封裝任何 DOM 操作。比如 v-attr 會操作一個元素的特性;v-repeat 會基於數組來複制一個元素;v-on會綁定事件等。
Mustache 風格綁定
vue可以使用 mustache 風格的綁定,不管在文本中還是在屬性中。它們在底層會被轉換成 v-text 和 v-attr 的指令。比如:
<div id="person-{{id}}">Hello {{name}}!</div>
過濾器 (Filters)
過濾器是用於在更新視圖之前處理原始值的函數。它們通過一個 “管道” 在指令或綁定中進行處理:
<div>{{message | capitalize}}</div>
這樣在 div 的文本內容被更新之前,message 的值會先傳給 capitalizie 函數處理。
實例的數據和方法
data屬性
Vue 實例的數據對象。
類型: Object | Function
限制: 組件的定義只接受 function。
說明: Vue 將會遞歸將 data 的 property 轉換爲 getter/setter,從而讓 data 的 property 能夠響應數據變化。對象必須是純粹的對象 (含有零個或多個的 key/value 對):瀏覽器 API 創建的原生對象,原型上的 property 會被忽略。大概來說,data 應該只能是數據。
當一個 Vue 實例被創建時,它將 data 對象中的所有的 property 加入到 Vue 的響應式系統中。當這些 property 的值發生改變時,視圖將會產生“響應”,即匹配更新爲新的值。
實例創建之後,可以通過 vm./data.a。
<script type="text/javascript">
var val = {a: 1} //數據對象
var vm = new Vue({
el: '#vue_app',
data: val //數據對象被加入到一個 Vue 實例中
})
// 獲得這個實例上的 property
// 返回源數據中對應的字段
// vm.a == val.a // => true
// vm.$data.a == val.a // => true
console.log(vm.a == val.a)
console.log(vm.$data.a === val.a)
// 設置 property 也會影響到原始數據
vm.a = 2
val.a // => 2
console.log(val.a)
// ……反之亦然
val.a = 3
vm.a // => 3
console.log(vm.a)
</script>
當這些數據改變時,視圖會進行重渲染。值得注意的是只有當實例被創建時就已經存在於 data 中的 property 纔是響應式的。也就是說如果你添加一個新的 property,新property的改動不會觸發視圖更新。比如:
vm.b = "hello" //vue實例綁定一個新屬性b
vm.b = "welcome" //改動屬性b的值不會觸發視圖更新
除了數據 property,Vue 實例還暴露了一些有用的實例 property 與方法。它們都有前綴 $,以便與用戶定義的 property 區分開來。例如:
el屬性
el屬性指向vue實例綁定的DOM元素。
類型: string | Element
限制: 只在用 new 創建實例時生效。
用法: 提供一個在頁面上已存在的 DOM 元素作爲 Vue 實例的掛載目標。可以是 CSS 選擇器,也可以是一個 HTMLElement 實例。
在實例掛載之後,元素可以用 vm.$el 訪問。
<script type="text/javascript">
var val = {a: 1} //數據對象
var vm = new Vue({
el: '#vue_app',
data: val //數據對象被加入到一個 Vue 實例中
})
vm.$el === document.getElementById('vue_app') // => true
console.log(vm.$el === document.getElementById('vue_app'))
</script>
computed屬性
模板內的表達式非常便利,但是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護。
對於任何複雜邏輯,你都應當使用計算屬性。
基本用法
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<p>原始數據:"{{msg}}"</p>
<p>新數據:"{{reveseMsg}}"</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo"
},
computed: {
// 計算屬性的 getter
reveseMsg: function () {
// `this` 指向 vm 實例
return this.msg.split('').reverse().join('')
}
}
}
)
</script>
</body>
</html>
計算屬性的 setter
計算屬性默認只有 getter,不過在需要時你也可以提供一個 setter.
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<p>全名:"{{fullName}}"</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
firstName : "Bruce",
lastName: "Xu"
},
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
console.log("set被調用了")
}
}
}
}
)
//給fullName賦值,運行 vm.fullName = 'Bruce Darcy' 時,setter 會被調用
vm.fullName = "Bruce Darcy"
</script>
</body>
</html>
methods屬性
函數必須在 Vue.js 中的 methods 屬性下添加,類似於計算屬性(computed)。
使用 Vue 的 methods 時,當調用 methods 定義的方法時,一定記得加上小括號 (),不然輸出的就是函數中的字符。
基本用法
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<p>原始數據:"{{msg}}"</p>
<!-- 注意methods方法必須要加上() -->
<p>新數據:"{{reveseMsg()}}"</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo"
},
methods: {
reveseMsg: function () {
// `this` 指向 vm 實例
return this.msg.split('').reverse().join('')
}
}
}
)
</script>
</body>
</html>
傳參
定義methods函數時,可以帶上額外的不在data屬性中的外部參數
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<p>原始數據:"{{msg}}"</p>
<!-- 注意methods方法必須要加上() -->
<p>新數據:"{{reveseMsg('data_1','data_2')}}"</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo"
},
methods: {
// 計算屬性的 getter
reveseMsg: function (param_a, param_b) {
// `this` 指向 vm 實例
return this.msg.split('').reverse().join('') + param_a + ' ' + param_b
}
}
}
)
</script>
</body>
</html>
props屬性
父組件通過 props 向下傳遞數據給子組件。
props 可以是數組或對象,用於接收來自父組件的數據。props 可以是簡單的數組,或者使用對象作爲替代,對象允許配置高級選項,如類型檢測、自定義驗證和設置默認值。
類型: Array | Object
用法:
你可以基於對象的語法使用以下選項:
- type:可以是下列原生構造函數中的一種:String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定義構造函數、或上述內容組成的數組。會檢查一個 prop 是否是給定的類型,否則拋出警告。
- default:any
爲該 prop 指定一個默認值。如果該 prop 沒有被傳入,則換做用這個值。對象或數組的默認值必須從一個工廠函數返回。 - required:Boolean
定義該 prop 是否是必填項。在非生產環境中,如果這個值爲 truthy 且該 prop 沒有被傳入的,則一個控制檯警告將會被拋出。 - validator:Function
自定義驗證函數會將該 prop 的值作爲唯一的參數代入。在非生產環境下,如果該函數返回一個 falsy 的值 (也就是驗證失敗),一個控制檯警告將會被拋出。你可以在這裏查閱更多 prop 驗證的相關信息。
// 簡單語法
Vue.component('props-demo-simple', {
props: ['size', 'myMessage']
})
// 對象語法,提供驗證
Vue.component('props-demo-advanced', {
props: {
// 檢測類型
height: Number,
// 檢測類型 + 其他驗證
age: {
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
})
watch方法
watch 是一個實例方法。鍵是需要觀察的表達式,值是對應回調函數。值也可以是方法名,或者包含選項的對象。Vue 實例將會在實例化時調用 $watch(),遍歷 watch 對象的每一個 property。
vm.$watch( expOrFn, callback, [options] )
參數:
- {string | Function} expOrFn
- {Function | Object} callback
- {Object} [options]
- {boolean} deep
- {boolean} immediate
示例:
<script type="text/javascript">
var val = {a: 1, b:2, c:3} //數據對象
var vm = new Vue({
el: '#vue_app',
name: "bruce.xu",
data: val //數據對象被加入到一個 Vue 實例中
})
// $watch 是一個實例方法
vm.$watch('a', function (newValue, oldValue) {
// 這個回調將在 `vm.a` 改變後調用
console.log('舊數據:'+ oldValue + "替換爲:" + newValue)
})
vm.a = "123"
</script>
實例生命週期的鉤子
每個 Vue 實例在被創建時都要經過一系列的初始化過程——例如,需要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。同時在這個過程中也會運行一些叫做生命週期鉤子的函數,這給了用戶在不同階段添加自己的代碼的機會。
比如 created 鉤子可以用來在一個實例被創建之後執行代碼:
<script type="text/javascript">
var val = {a: 1, b:2, c:3} //數據對象
var vm = new Vue({
el: '#vue_app',
name: "bruce.xu",
data: val, //數據對象被加入到一個 Vue 實例中
created: function () {
// `this` 指向 vm 實例
console.log('a is: ' + this.a)
}
})
</script>
生命週期鉤子的 this 上下文指向調用它的 Vue 實例。還有有一些其它的鉤子,在實例生命週期的不同階段被調用,如 mounted、updated 和 destroyed。
模版語法
插值
文本
數據綁定最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值:
<span>Message: {{ msg }}</span>
綁定的數據對象上 msg property 發生了改變,插值處的內容都會更新。
通過使用 v-once 指令,你也能執行一次性地插值,當數據改變時,插值處的內容不會更新。
<span v-once>這個將不會改變: {{ msg }}</span>
原始 HTML
雙大括號會將數據解釋爲普通文本,而非 HTML 代碼。爲了輸出真正的 HTML,需要使用 v-html。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全棧工程師:vue小白學習</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue_app">
<h1>內容</h1>
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_app',
name: "bruce.xu",
data: {
rawHtml: "<p>段落文本</p>"
}
})
</script>
</body>
</html>
這個 span 的內容將會被替換成爲 property 值 rawHtml,直接作爲 HTML——會忽略解析 property 值中的數據綁定。
Attribute
Mustache 語法不能作用在 HTML attribute 上,遇到這種情況應該使用 v-bind 指令。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全棧工程師:vue小白學習</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue_app">
<h1>內容</h1>
<div v-bind:id="app_id">Attribute綁定</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_app',
name: "bruce.xu",
data: {
msg : "hello vue小白",
app_id: "id1"
}
})
console.log(document.getElementById(vm.app_id))
</script>
</body>
</html>
javascript表達式
對於所有的數據綁定,Vue.js 都提供了完全的 JavaScript 表達式支持。
每個綁定都只能包含單個表達式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全棧工程師:vue小白學習</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue_app">
<h1>內容</h1>
<p v-bind:id="app_id">Attribute綁定: {{msg.split('').reverse().join('') }}</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_app',
name: "bruce.xu",
data: {
msg : "hello vue小白來了",
app_id: "id1"
}
})
console.log(document.getElementById(vm.app_id))
</script>
</body>
</html>
每個綁定都只能包含單個表達式。非單表達式語句會失效。
<!-- 這是語句,不是表達式 -->
{{ var a = 1 }}
<!-- 流控制也不會生效,請使用三元表達式 -->
{{ if (ok) { return message } }}
指令
指令 (Directives) 是帶有 v- 前綴的特殊 attribute。指令 attribute 的值預期是單個 JavaScript 表達式(v-for除外)。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地作用於 DOM。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<!-- 這裏,v-if 指令將根據表達式 seen 的值的真假來插入/移除 <p> 元素 -->
<p v-if="seen">
如果seen爲true,才能看到: {{ msg }}
</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo",
seen: true
}
}
)
</script>
</body>
</html>
參數
一些指令能夠接收一個“參數”,在指令名稱之後以冒號表示。例如,v-bind 指令可以用於響應式地更新 HTML attribute:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<!-- 這裏,v-if 指令將根據表達式 seen 的值的真假來插入/移除 <p> 元素 -->
<p v-if="seen">
<a v-bind:href="url">如果seen爲true,才能看到: {{ msg }}</a>
</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo",
seen: true,
url: "http://www.baidu.com"
}
}
)
</script>
</body>
</html>
另一個例子是 v-on 指令,它用於監聽 DOM 事件:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<!-- 這裏,v-if 指令將根據表達式 seen 的值的真假來插入/移除 <p> 元素 -->
<p v-if="seen">
<a v-bind:href="url">如果seen爲true,才能看到: {{ msg }}</a>
<div v-on:click="show_msg">
點擊
</div>
</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo",
seen: true,
url: "http://www.baidu.com"
},
methods: {
show_msg: function () {
console.log("click on")
}
}
}
)
</script>
</body>
</html>
動態參數
從 2.6.0 開始,可以用方括號括起來的 JavaScript 表達式作爲一個指令的參數:
<!--
注意,參數表達式的寫法存在一些約束,如之後的“對動態參數表達式的約束”章節所述。
-->
<a v-bind:[attributeName]="url"> ... </a>
這裏的 attributeName 會被作爲一個 JavaScript 表達式進行動態求值,求得的值將會作爲最終的參數來使用。例如,如果你的 Vue 實例有一個 data property attributeName,其值爲 “href”,那麼這個綁定將等價於 v-bind:href。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<!-- 這裏,v-if 指令將根據表達式 seen 的值的真假來插入/移除 <p> 元素 -->
<p v-if="seen">
<a v-bind:[attr]="url">如果seen爲true,才能看到: {{ msg }}</a>
<div v-on:[click_event]="show_msg">
點擊
</div>
</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data : {
msg : "hello , 這個是demo",
seen: true,
click_event: "click",
attr: "href",
url: "http://www.baidu.com"
},
methods: {
show_msg: function () {
console.log("click on")
}
}
}
)
</script>
</body>
</html>
約束
-
對動態參數的值的約束
動態參數預期會求出一個字符串,異常情況下值爲 null。這個特殊的 null 值可以被顯性地用於移除綁定。任何其它非字符串類型的值都將會觸發一個警告。 -
對動態參數表達式的約束
動態參數表達式有一些語法約束,因爲某些字符,如空格和引號,放在 HTML attribute 名裏是無效的。例如:
<!-- 這會觸發一個編譯警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>
- 大小寫約束
在 DOM 中使用模板時 (直接在一個 HTML 文件裏撰寫模板),還需要避免使用大寫字符來命名鍵名,因爲瀏覽器會把 attribute 名全部強制轉爲小寫。
<!--
在 DOM 中使用模板時這段代碼會被轉換爲 `v-bind:[someattr]`。
除非在實例中有一個名爲“someattr”的 property,否則代碼不會工作。
-->
<a v-bind:[someAttr]="value"> ... </a>
修飾符
修飾符 (modifier) 是以半角句號 . 指明的特殊後綴,用於指出一個指令應該以特殊方式綁定。例如,.prevent 修飾符告訴 v-on 指令對於觸發的事件調用 event.preventDefault():
<form v-on:submit.prevent="onSubmit">...</form>
縮寫
Vue 爲 v-bind 和 v-on 這兩個最常用的指令,提供了特定簡寫。
v-bind縮寫
<!-- 完整語法 -->
<a v-bind:href="url">...</a>
<!-- 縮寫 -->
<a :href="url">...</a>
<!-- 動態參數的縮寫 (2.6.0+) -->
<a :[key]="url"> ... </a>
v-on縮寫
<!-- 完整語法 -->
<a v-on:click="doSomething">...</a>
<!-- 縮寫 -->
<a @click="doSomething">...</a>
<!-- 動態參數的縮寫 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
Class和Style綁定
操作元素的 class 列表和內聯樣式style也可以通過v-bind來綁定。v-bind表達式結果的類型除了字符串之外,還可以是對象或數組。
class綁定
對象綁定
可以傳給 v-bind:class 一個對象,以動態地切換 class。
方式一:直接內聯綁定class,通過data傳遞class屬性值
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<!-- v-bind綁定class -->
<div id='app' class="static" v-bind:class="{active: isActive, 'text-danger': hasError}">
<p>vue綁定class</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
// 通過data中傳遞class屬性值
data : {
isActive : true,
hasError: true
}
}
)
console.log(document.getElementById("app").classList)
</script>
</body>
</html>
當 isActive 或者 hasError 變化時,class 列表將相應地更新。例如,如果 hasError 的值爲 true,class 列表將變爲 “static active text-danger”。
瀏覽器效果:
方式二:在data中定義class對象
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<!-- v-bind綁定class -->
<div id='app' class="static" v-bind:class="cls_obj">
<p>vue綁定class</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
// 通過自定義屬性傳遞class屬性值
data: {
cls_obj : {
active: true,
'text-danger': true}
}
}
)
console.log(document.getElementById("app").classList)
</script>
</body>
</html>
方式三:在computed中返回class對象
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<!-- v-bind綁定class -->
<div id='app' class="static" v-bind:class="cls_obj">
<p>vue綁定class</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
active: true,
error: null
},
computed: {
cls_obj: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
}
)
console.log(document.getElementById("app").classList)
</script>
</body>
</html>
數組綁定
我們可以把一個數組傳給 v-bind:class,以應用一個 class 列表。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<!-- v-bind綁定class -->
<div id='app' class="static" v-bind:class="[active_class, error_class]">
<p>vue綁定class</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
active_class: 'active',
error_class: 'text-danger'
}
}
)
console.log(document.getElementById("app").classList)
</script>
</body>
</html>
style綁定
對象綁定
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<!-- v-bind綁定style -->
<div id='app' v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">
<p>vue綁定style</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
activeColor: 'red',
fontSize: 50
}
}
)
</script>
</body>
</html>
數組綁定
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<!-- v-bind綁定style -->
<div id='app' v-bind:style="[color_style, font_style]">
<p>vue綁定style</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
color_style: {
color: "red"
},
font_style: {
fontSize: '30px'
}
}
}
)
</script>
</body>
</html>
語法基礎
條件渲染v-if
v-if
v-if基本用法
v-if 指令用於條件性地渲染一塊內容。這塊內容只會在指令的表達式返回 truthy 值的時候被渲染。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<p v-if="type === 'A'">條件A滿足</p>
<p v-else-if="type === 'A'">條件B滿足</p>
<p v-else>條件A/B都不滿足</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
type: 'A'
}
}
)
</script>
</body>
</html>
在template中使用v-if
因爲 v-if 是一個指令,所以必須將它添加到一個元素上。但是如果想切換多個元素呢?此時可以把一個 <template> 元素當做不可見的包裹元素,並在上面使用 v-if。最終的渲染結果將不包含 <template> 元素。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<template v-if="res === 'success'">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
<template v-else-if="res === 'success'">
<h1>Title2</h1>
<p>Paragraph 21</p>
<p>Paragraph 22</p>
</template>
<template v-else>
<h1>Title3</h1>
<p>Paragraph 31</p>
<p>Paragraph 22</p>
</template>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
res: 'ok'
}
}
)
</script>
</body>
</html>
v-show
另一個用於根據條件展示元素的選項是 v-show 指令。用法大致一樣:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id='app'>
<p v-show="OK">條件A滿足</p>
<p v-show="ERROR">條件B滿足</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
OK: true,
ERROR: false
}
}
)
</script>
</body>
</html>
瀏覽器輸出:
v-if和v-show區別
- v-if 是“真正”的條件渲染,因爲它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷燬和重建。
- v-if 也是惰性的:如果在初始渲染時條件爲假,則什麼也不做——直到條件第一次變爲真時,纔會開始渲染條件塊。
- 相比之下,v-show 就簡單得多——不管初始條件是什麼,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運行時條件很少改變,則使用 v-if 較好。
列表渲染v-for
v-for 指令基於一個數組來渲染一個列表。v-for 指令需要使用 item in items 形式的特殊語法,其中 items 是源數據數組,而 item 則是被迭代的數組元素的別名。
使用v-for遍歷數組
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<ul id="app">
<li v-for="msg in messages">
{{ msg}}
</li>
</ul>
<script>
vm = new Vue(
{
el: "#app",
data: {
messages: ["hello", "vue", "python"]
}
}
)
</script>
</body>
</html>
使用v-for遍歷對象
遍歷對象中的每一個item
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<ul id="app">
<li v-for="msg in messages">
{{ msg}}
</li>
</ul>
<script>
vm = new Vue(
{
el: "#app",
data: {
messages: {
name: "Bruce",
age: 22,
phone: "1234567",
job: "engineer"
}
}
}
)
</script>
</body>
</html>
遍歷獲取對象中的name, value和index
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<ul id="app" class="demo">
<li v-for="(value, name, index) in messages" >
{{ index }}. {{ name }}: {{ value }}
</li>
</ul>
<script>
vm = new Vue(
{
el: "#app",
data: {
messages: {
name: "Bruce",
age: 22,
phone: "1234567",
job: "engineer"
}
}
}
)
</script>
</body>
</html>
瀏覽器效果:
事件處理v-on
v-on監聽事件
用 v-on 指令監聽 DOM 事件,並在觸發時運行一些 JavaScript 代碼。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
counter: 0
}
}
)
</script>
</body>
</html>
事件處理方法
v-on接收調用的方法名稱
v-on 還可以接收一個需要調用的方法名稱,通過執行方法名稱對應的函數實現事件的相應處理過程。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<button v-on:click="add">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
counter: 0
},
methods : {
// `event` 是原生 DOM 事件
add: function(event) {
alert(event.target.tagName)
if (event) {this.counter += 1}
}
}
}
)
</script>
</body>
</html>
v-on內聯 JavaScript 語句中調用方法
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<button v-on:click="add(2)">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
counter: 0
},
methods : {
// `event` 是原生 DOM 事件
add: function(data) {
alert(event.target.tagName)
if (event) {this.counter += data}
}
}
}
)
</script>
</body>
</html>
內聯語句處理器中訪問原始的 DOM 事件
有時也需要在內聯語句處理器中訪問原始的 DOM 事件。可以用特殊變量 $event 把它傳入方法:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<!-- $event獲取DOM事件 -->
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
<script>
vm = new Vue(
{
el: "#app",
data: {
counter: 0
},
methods : {
warn: function (message, event) {
// 訪問原生事件對象
if (event) {
event.preventDefault()
}
alert(message)
}
}
}
)
</script>
</body>
</html>
事件修飾符
v-on 提供了事件修飾符。修飾符是由點開頭的指令後綴來表示的。
<!-- 阻止單擊事件繼續傳播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件監聽器時使用事件捕獲模式 -->
<!-- 即內部元素觸發的事件先在此處理,然後才交由內部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只當在 event.target 是當前元素自身時觸發處理函數 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>
按鍵修飾符
監聽鍵盤事件時,我們經常需要檢查詳細的按鍵。Vue 允許爲 v-on 在監聽鍵盤事件時添加按鍵修飾符:
<!-- 只有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
表單輸入綁定v-model
v-model 指令在表單 <input>、<textarea> 及 <select> 元素上創建雙向數據綁定。它會根據控件類型自動選取正確的方法來更新元素。
本質上它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。
v-model 在內部爲不同的輸入元素使用不同的 property 並拋出不同的事件:
- text 和 textarea 元素使用 value property 和 input 事件;
- checkbox 和 radio 使用 checked property 和 change 事件;
- select 字段將 value 作爲 prop 並將 change 作爲事件。
注意:
v-model 會忽略所有表單元素的 value、checked、selected attribute 的初始值而總是將 Vue 實例的數據作爲數據來源。應該通過 JavaScript 在組件的 data 選項中聲明初始值。
基本用法
文本
<div id="app">
<!-- placeholder中設置的默認值不生效 -->
<input v-model="text_message" placeholder="edit me"/>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值
text_message: "default"
}
}
)
</script>
多行文本
<div id="app">
<span>多行文本</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="textarea_message"></textarea>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值
textarea_message: "輸入多行文本"
}
}
)
</script>
複選框
單個複選框,綁定到布爾值:
<div id="app">
<!-- 單個複選框,綁定到布爾值: -->
<input type="checkbox" id="checkbox" v-model="checked"></input>
<label for="checkbox">{{ checked }}</label>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值
checked: false
}
}
)
</script>
瀏覽器效果:
多個複選框,綁定到同一個數組:
當選項被選擇後,選項對應的value會自動綁定到數組中
<div id="app">
<!-- 多個複選框,綁定到同一個數組: -->
<input type="checkbox" id="checkbox1" value="1" v-model="checkList"></input>
<label for="checkbox1">Python</label>
<br>
<input type="checkbox" id="checkbox2" value="2" v-model="checkList"></input>
<label for="checkbox2">vue.js</label>
<br>
<input type="checkbox" id="checkbox3" value="3" v-model="checkList"></input>
<label for="checkbox3">flask</label>
<br>
<span>Checked list: {{ checkList }}</span>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值
checkList: []
}
}
)
</script>
瀏覽器效果:
單選按鈕
用法和複選框類似,也是可以綁定到一個數組。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<!-- 多單選button,綁定到同一個數組: -->
<input type="radio" id="radio1" value="1" v-model="radioList"></input>
<label for="radio1">Python</label>
<br>
<input type="radio" id="radio2" value="2" v-model="radioList"></input>
<label for="radio2">vue.js</label>
<br>
<span>Radio list: {{ radioList }}</span>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值
radioList: []
}
}
)
</script>
</body>
</html>
選擇框
基本用法和checkbox類似
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<select v-model="selected">
<option disabled value="">請選擇</option>
<option> A </option>
<option> B </option>
<option> C </option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值爲‘’
selected: ''
}
}
)
</script>
</body>
</html>
還可以用 v-for 渲染的動態選項:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>vue小白</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{option.text}}
</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
<script>
vm = new Vue(
{
el: "#app",
data: {
// 在data中設置默認值爲‘’
selected: 'A',
options: [
{text: "1", value: "A"},
{text: "2", value: "B"},
{text: "3", value: "C"}
]
}
}
)
</script>
</body>
</html>
瀏覽器效果:
值綁定
對於單選按鈕,複選框及選擇框的選項,v-model 綁定的值通常是靜態字符串 (對於複選框也可以是布爾值):
<!-- 當選中時,`picked` 爲字符串 "a" -->
<input type="radio" v-model="picked" value="a">
<!-- `toggle` 爲 true 或 false -->
<input type="checkbox" v-model="toggle">
<!-- 當選中第一個選項時,`selected` 爲字符串 "abc" -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
修飾符
.lazy
在默認情況下,v-model 在每次 input 事件觸發後將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加 lazy 修飾符,從而轉爲在 change 事件_之後_進行同步:
<!-- 在“change”時而非“input”時更新 -->
<input v-model.lazy="msg">
.number
如果想自動將用戶的輸入值轉爲數值類型,可以給 v-model 添加 number 修飾符:
<input v-model.number="age" type="number">
.trim
如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:
<input v-model.trim="msg">
參考文獻:
https://blog.csdn.net/weixin_33743703/article/details/91388404