一、開發環境配置
VSCode & 插件安裝
jshint:js代碼規範檢查。
Beautify:一鍵美化代碼的插件。
Vetur:.vue文件識別插件。
Javascript(ES6) code snippets:ES6語法提示。
Auto Rename Tag:自動重命名標籤。標籤都是成對出現的,開始標籤修改了,結束標籤也會跟着修改。
Auto Close Tag:自動閉合標籤。針對一些非標準的標籤,這個插件還是很有用的。
vue helper:一些Vue代碼的快捷代碼。
vscode-icons:可選。提供了很多類型的文件夾icon,不同類型的文件夾使用不同的icon,會讓文件查找更直觀。
open in browser:可選。右鍵可以選擇在默認瀏覽器中打開當前網頁。
二、Vue安裝和使用
需要聯網的方式
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
下載在本地的引用方法
將提前下載好的 vue.js 放在代碼同級目錄下
<script src="./vue.js"></script>
三、基本使用&Vue模板語法
(1)Vue對象、el參數和data參數
創建一個Vue對象,並且在這個對象中傳遞el參數,el參數全稱是element,用來找到一個給vue渲染的根元素。並且我們可以傳遞一個data參數,data中的所有值都可以直接在根元素下使用{{}}來使用,且data中的數據,只能在vue的根元素下使用,在其他地方是不能被vue識別和渲染的
(2)vue對象中添加methods
methods專門用來存儲自己的函數。methods中的函數也可以在模板中使用,並且在methods中的函數來訪問data中的值,只需要通過this.屬性名就可以訪問到了
(3)v-once 文本
變量在第一次渲染完成後,不想要跟着後期數據的更改而更改,那麼可以使用 v-once指令來實現。
<p v-once>{{username}}</p>
(4) v-html 文本
後臺返回給我們一個段原生的html代碼,我們需要渲染出來,那麼如果直接通過{{}}渲染,會把這個html代碼當做字符串。這時候我們就可以通過v-html指令來實現
簡單來說就是跳轉鏈接
<div v-html="code"></div>
(5)屬性綁定 v-bind:
屬性綁定不需要花括號,屬性不同於方法
在html元素的屬性上綁定我們Vue對象中的變量,那麼需要通過v-bind來實現
第一種
<img v-bind:src="image" alt="">
第二種
<img :src="image" alt="">
(6)代碼參考
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 這裏變量來自 vue 模塊中的 data 引用變量的時候需要帶上{{}} -->
<!-- <p>username: {{username}}</p> -->
<!-- 加上 v-once 變量則在第一次渲染出來後 不被更替 -->
<p v-once>username: {{username}}</p>
<p>password:{{password}}</p>
<!-- 方法裏的變量用() -->
{{demo(username)}}
<!-- v-html 跳轉鏈接實現 兩種方式實現結果相同 -->
<p v-html="code">第一種</p>
<p v-html="code">{{code}}</p>
<!-- 按鈕 點擊一下 改變 username 的值 v-on:click -->
<button @click="demo2">按鈕</button>
<!-- src 路徑 這裏是想要綁定屬性 和之前的那些變量的調用不同-->
<!-- 錯誤的 屬性是不需要包裹在{{}} -->
<!-- <img v-bind:src="{{imagesrc}}" alt=""> -->
<!-- <img v-bind:src="imagesrc" alt=""> -->
<div>
<!-- 圖片部分 屬性綁定 -->
<img :src="imagesrc" alt="">
</div>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
// vn 有自動補全
new Vue({
// app 和 body裏面 id 爲 div 的聯繫起來
el: "#app",
data:{
"username":"邏輯教育",
"password": 123,
"code":"<a href='https://www.baidu.com/'>百度一下</a>",
"imagesrc": "https://www.baidu.com/img/bd_logo1.png?qua=high&where=super",
},
// 定義方法
methods:{
// name 形參 可在使用的時候外部傳入一個參數 第一個demo 傳入外部參數的方式
demo: function(name){
return "晚上好," + name
},
demo2: function(){
this.username = "lgcoder"
}
}
})
</script>
四、屬性綁定Class和Style
(1)綁定Class
綁定class或者style
- 數組方式實現
<p v-bind:class="[class1,class2]">武漢,加油!!!</p>
- 對象方式實現
<!-- main-title 有-用''來包裹表示變量 -->
<p :class="{title:class1, 'main-title':class2}">hello world</p>
(2)綁定Style
- 數組方式實現
但是樣式如果有橫線,則都需要變成駝峯命名的方式
用數組的方式
# 讀取對應樣式的值
<li :style="{backgroundColor:pBgColor,fontSize:pFontSize}">首頁</li>
# 或者是直接讀取整個字符串
<li :style="liStyle">首頁</li>
- 對象方式實現
<!-- <p v-bind:style="[pclass1, pclass2]">加油, 中國</p> -->
(3)JavaScript表達式
只能是JavaScript表達式,不能是語句
<p v-bind:style="{color:color?'red':'blue'}">{{username.split(" ").reverse().join(" ")}}</p>
(4)代碼參考
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue模板語法</title>
<!-- 紅色的樣式 style -->
<style>
.title{
font-size: 20px;
color: red;
}
.main-title{
font-weight: 800;
}
</style>
</head>
<body>
<p class="title">中國,加油</p>
<div id="app">
<!-- <p v-bind:class="class1">中國,加油!!!</p> -->
<p v-bind:class="class1">中國,加油!!!</p>
<!-- 通過[] 數組的方式加載兩種 class 給這個p標籤 -->
<!-- <p v-bind:class="[class1,class2]">武漢,加油!!!</p> -->
<!-- 通過對象的方式實現綁定 main-title 有-用''來包裹表示變量 -->
<p :class="{title:class1, 'main-title':class2}">hello world</p>
<!-- 樣式如果有橫線 加單引號'' -->
<p v-bind:style="{'background-color':background}">邏輯</p>
<!-- 樣式如果有橫線 駝峯命名(backgroundColor)的方式 -->
<p v-bind:style="{backgroundColor:background}">教育</p>
<!-- style 屬性 -->
<p :style="pstyle">邏輯教育</p>
<!-- <p v-bind:style="[pclass1, pclass2]">加油, 中國</p> -->
<!-- JavaScript的三目運算符 -->
<!-- color:color 判斷布爾值 true 爲 red 反之 blue -->
<p v-bind:style="{color:color?'red':'blue'}">{{username.split(" ").reverse().join(" ")}}</p>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
// // 這裏的 title 代表引用上面的紅色樣式
// // class1:"title",
// 通過[]數組方式 class1 + class2
// class2:"main-title",
// // 加載 class 的第二種方式(中國,加油!!!)
// class1:"title main-title",
// 通過對象的方式實現綁定
class1:true,
class2:true,
background: 'red',
pstyle:{
// 這裏的顏色可以寫 rgb 顏色代碼 red英文表示
// backgroundColor 駝峯命名也適合於這裏
background: 'rgb(255, 255, 51)',
},
username: "hello world",
color:true,
}
})
</script>
五、事件綁定 & 傳入 event 參數
綁定的是事件,而不是屬性
如果在事件處理函數中,想要獲取原生的DOM事件,那麼在html代碼中,調用的時候,可以傳遞一個$event參數。
<p>{{count}}</p>
<!-- 加的按鈕 v-on:click -->
<button v-on:click="count+=1">加</button>
<!-- 減的按鈕 @click 傳入參數$event -->
<button @click="sub(2,$event)" value="這是一個減按鈕" name="hello world">減</button>
<script>
new Vue({
sub: function(value, event){
// console.log 在控制檯打印信息
//console.log(event)
console.log(event.target.value) // 這是一個減按鈕
console.log(event.target.name) // hello world
this.count -= value
}
})
</script>
六、條件判斷和循環
(1)條件判斷基本使用v-if、 v-else-if、v-else
<div id="app">
<p v-if="weather == 'summer' ">今天去約女神</p>
<p v-else-if="weather == 'rain'">今天在家打遊戲</p>
<p v-else>今天吃火鍋</p>
</div>
(2)使用 template 在一個條件中加載多個html元素
<div id="app">
<template v-if="age < 18">
<p>上網</p>
<p>逃學</p>
</template>
<template v-else-if="age >= 18 && age<25">
<p>找工作</p>
<p>找女朋友</p>
</template>
<template v-else>
<p>工資多少</p>
<p>結婚</p>
</template>
</div>
(3)條件判斷、JavaScript 表達式、key 屬性 & button 切換的應用
在標籤加上 key 元素作爲唯一標識,可以實現條件下的重新渲染對應標籤 key 屬性的 html 元素
可應用在切換登陸方式,跟隨唯一標識的元素
<!-- loginType 爲定義好的登陸方式 username 和 email -->
<!-- vue 中定義函數 changeLoginType 實現來回切換(三目運算) -->
<!-- loginType=='username'?'email':'username' -->
<template v-if="loginType=='username'">
<label for="">用戶名:</label>
<!-- placeholder -->
<input type="text" placeholder="用戶名" key="username" >
</template>
<!-- 郵箱 input key="email" -->
<template v-else-if="loginType=='email'">
<label for="">郵箱:</label>
<input type="text" placeholder="郵箱" key="email">
</template>
<!--button v-on:click 或者 @click 切換登陸方式 -->
<!-- 屬性 click 由 changeLoginType函數實現 -->
<button v-on:click="changeLoginType">切換登錄類型</button>
(4)v-for 循環數組
<table>
<tr>
<th>序號</th>
<th>標題</th>
<th>作者</th>
</tr>
<!-- 循環數組 第一個位置 數據 第二個位置 索引 -->
<tr v-for="(book, index) in books">
<td>{{index+1}}</td>
<td>{{book.title}}</td>
<td>{{book.author}}</td>
</tr>
</table>
###(5)v-for 循環對象
<!-- 循環對象 第一個位置 值 第二個位置 key -->
<div v-for="(value, key) in person">
{{key}}: {{value}}
</div>
// data 中定義對象
person: {
// key value(值)
"username": "juran",
"age": 18,
"address": "csc"
},
(5)代碼參考
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- div#app div id="app" -->
<!-- div.app div class="app" -->
<!-- div*3 生成3個div -->
<!-- 條件判斷 v-if v-else-if v-else -->
<!-- <div id="app">
<p v-if="weather == 'summer' ">今天去約女神</p>
<p v-else-if="weather == 'rain'">今天在家打遊戲</p>
<p v-else>今天吃火鍋</p>
</div> -->
<!-- 一個條件中加載多個html元素 template條件判斷 if else-if else -->
<!-- <div id="app">
<template v-if="age < 18">
<p>上網</p>
<p>逃學</p>
</template>
<template v-else-if="age >= 18 && age<25">
<p>找工作</p>
<p>找女朋友</p>
</template>
<template v-else>
<p>工資多少</p>
<p>結婚</p>
</template>
</div> -->
<!-- 輸入框 placeholder 輸入框提示的內容 -->
<div id="app">
<!-- 用戶名 在這個 username 的標籤加上 key 屬性,可以實現條件下的重新渲染對應 key 屬性的 html 元素 -->
<template v-if="loginType=='username'">
<label for="">用戶名:</label>
<input type="text" placeholder="用戶名" key="username" >
</template>
<!-- 郵箱 input key="email" -->
<template v-else-if="loginType=='email'">
<label for="">郵箱:</label>
<input type="text" placeholder="郵箱" key="email">
</template>
<!--button v-on:click 或者 @click 切換登陸方式 -->
<!-- 屬性 click 由 changeLoginType函數實現 -->
<button v-on:click="changeLoginType">切換登錄類型</button>
<table>
<tr>
<th>序號</th>
<th>標題</th>
<th>作者</th>
</tr>
<!-- tr 循環 v-for -->
<!-- <tr v-for="book in books"> -->
<!-- td 裏面包裹變量{{}} -->
<!-- <td>{{book.title}}</td> -->
<!-- <td>{{book.author}}</td> -->
<!-- </tr> -->
<!-- 循環數組 第一個位置 數據 第二個位置 索引 -->
<tr v-for="(book, index) in books">
<td>{{index+1}}</td>
<td>{{book.title}}</td>
<td>{{book.author}}</td>
</tr>
</table>
<!-- 循環對象 第一個位置 值 第二個位置 key -->
<div v-for="(value, key) in person">
{{key}}: {{value}}
</div>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
weather: "summer",
age: 30,
loginType: 'email',
// book 數組 {} 是元素
books:[
{
'title': 'python',
'author': '龜叔'
},
{
'title': 'java',
'author': 'xxx1'
},
{
'title': 'PHP',
'author': 'xxx2'
},
{
'title': 'C++',
'author': 'xxx3'
},
],
// 對象
person: {
// key value(值)
"username": "juran",
"age": 18,
"address": "csc"
},
},
methods:{
changeLoginType:function(){
// 使用三目運算 實現來回切換
this.loginType = this.loginType=='username'?'email':'username'
}
}
})
</script>
七、觸發視圖更新
(1)push():添加元素的方法。
this.books.push("居然")
(2) pop():刪除數組最後一個元素。
this.books.pop()
(3) shift():刪除數組的第一個元素。
this.books.shift()
(4) unshift(item):在數組的開頭位置添加一個元素。
this.books.unshift("居然")
(5)splice(index,howmany,item1,…,itemX):向數組中添加或者刪除或者替換元素。
// 向books第0個位置添加元素
this.books.splice(0,0,"金瓶梅")
// 下標從0開始,刪除2個元素
this.books.splice(0,2)
// 下標從0開始,替換2個元素
this.books.splice(0,2,'金瓶梅','駱駝祥子')
(6)sort(function):排序。
// 1
this.books.sort(function(x,y){
// 取兩個隨機數排序
a = Math.random();
b = Math.random();
return a-b;
});
// 2
methods:{
changeBooks:function(){
// 對books兩兩排序
this.books.sort(function (a,b){
// 根據返回值 對傳入的兩個參數排序 返回正數true 返回負數false 進行正序或是逆序的
return Math.random() - 0.5
})
}
}
(7)reverse():將數組元素進行反轉。
this.books.reverse();
八、Vue.set()
(1)修改數組中的某個值
this.books[0] = ‘Python’; 不會讓頁面發生數據更新
//方法一 Vue.set
Vue.set(this.books,0,'Python');
//方法二 splice
(2)動態的給對象添加屬性
methods: {
changePerson: function(event){
Vue.set(this.person,'age',18)
}
}
九、計算屬性和監聽器
(1)計算屬性
一般情況下屬性都是放到data中的,但是有些屬性可能是需要經過一些邏輯計算後才能得出來,那麼我們可以把這類屬性變成計算屬性。
區別於 method 計算屬性更加智能,他是基於它們的響應式依賴進行緩存的。也就是說只要相關依賴(比如以上例子中的area)沒有發生改變,那麼這個計算屬性的函數不會重新執行,而是直接返回之前的值。這個緩存功能讓計算屬性訪問更加高效。
<p>{{count}}</p>
<!-- 加的按鈕 v-on:click -->
<button v-on:click="count+=1">加</button>
<!-- 減的按鈕 @click -->
<button @click="sub">減</button>
<script>
new Vue({
// 另外一種寫法 sub(){}
sub:function(){
this.count -= 1
}
})
</script>
(2)計算屬性和雙向綁定 v-model
計算面積
//計算面積
<div id="app">
<label>長</label>
<!-- v-model 雙向綁定,讓data裏面的 length 的數據發生變化 -->
<!-- 簡寫:v-model:"" -->
<input type="number" name="length" v-model:value="length">
<label>寬</label>
<!-- 如果不是 v-model 而是: 則 width 等值不會發生變化 -->
<input type="number" name="width" v-model:value="width">
<label>面積</label>
<!-- 綁定 area 方法 是一個計算屬性 -->
<input type="number" readonly v-bind:value="area">
</div>
……
……
……
<script>
new Vue({
el: "#app",
data:{
// data 裏面的數據根據 input 裏 v-model 的值進行變化
length:0,
width:0
},
// 計算屬性
computed:{
area:function(){
return this.length*this.width
}
}
})
</script>
分割、組合
<!-- 分割整體、組合成整體 -->
<div id="app">
<div>
<label>省:</label>
<input type="text" name="province" v-model:value="province">
</div>
<div>
<label>市:</label>
<input type="text" name="city" v-model:value="city">
</div>
<div>
<label>區:</label>
<input type="text" name="dist" v-model:value="dist">
</div>
<div>
<label>詳細地址:</label>
<input type="text" name="address" v-model:value="address">
</div>
</div>
……
……
……
<script>
new Vue({
el: "#app",
data:{
// data 裏面的數據根據 input 裏 v-model 的值進行變化
province:"",
dist:"",
city:"",
},
// 計算屬性
computed:{
address:{
// get 方法
get:function(){
// 定義一個變量
var result = ""
if(this.province){
result = this.province + "省"
}
if(this.city){
result += this.city + "市"
}
if(this.dist){
result += this.dist + "區"
}
return result
},
set:function(value){
// 分割 split(/省|市|區/)
var result = value.split(/省|市|區/)
// 邏輯不夠全
//if(result && result.length > 0){
// this.province = result[0]
// }
// if(result && result.length > 1){
// this.city = result[1]
// }
// if(result && result.length > 2){
// this.dist = result[2]
// }
}
}
}
})
</script>
(3)監聽器
監聽搜索框輸入的結果,並在短暫的延時之後再頁面中顯示
<div id="app">
<label>搜索</label>
<input type="text" v-model:value="keyword">
<p>結果</p>
{{answer}}
</div>
……
……
……
data:{
// data 裏面的數據根據 input 裏 v-model 的值進行變化
value:"",
answer:"",
keyword:"",
},
// 監聽 監聽到變化就會來執行監聽函數 keyword
// console 的打印是監聽到立刻打印
// 定時器 setTimeout 獲取一個新值之後進入延遲1000ms 1000ms內發生的數值變化不能夠在頁面顯示出
watch:{
keyword: function(newvalue,oldvalue){
console.log(newvalue)
console.log(oldvalue)
this.answer = "加載中……"
// 定時器
setTimeout(() =>{
this.answer = "搜索結果:" + newvalue
// 1000是延時
}, 1000);
}
},