Vue基礎篇(一)
Vue基礎篇(一)
文章目錄
Vue的概述
Vue 是什麼?
- Vue (讀音 /vjuː/,類似於 view) 是一套用於構建使用者介面的漸進式框架
- vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合
- 官網:https://cn.vuejs.org/v2/guide/
框架和庫的區別
-
框架:是一套完整的解決方案;對專案的侵入性較大,專案如果需要更換框架,則需要重新架構整個專案。
- node 中的 express;
-
庫(外掛):提供某一個小功能,對專案的侵入性較小,如果某個庫無法完成某些需求,可以很容易切換到其它庫實現需求。
- 從Jquery 切換到 Zepto
- 從 EJS 切換到 art-template
Vue的創始人和發展
尤雨溪:Vue.js的建立者
- 2014年2月,Vue.js正式釋出
- 2015年10月27日,正式釋出1.0.0
- 2016年4月27日,釋出2.0的預覽版本
Vue的好處
- 易用:熟悉HTML、CSS、JavaScript知識後,可快速上手Vue
- 靈活:在一個庫和一套完整框架之間自如伸縮
- 高效:20kB執行大小,超快虛擬DOM
MVC 與 MVVM 之間的區別
- MVC 是後端的分層開發概念; MVVM是前端檢視層的概念,主要關注於 檢視層分離,也就是說:MVVM把前端的檢視層,分為了 三部分 Model, View , VM ViewModel
- m model
- 資料層 Vue 中 資料層 都放在 data 裡面
- v view 檢視
- Vue 中 view 即 我們的HTML頁面
- vm (view-model) 控制器 將資料和檢視層建立聯絡
- vm 即 Vue 的例項 就是 vm
Vue初體驗(插值表示式)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="css/mui.css" rel="stylesheet" />
</head>
<body>
<div id="test">
<span>{{msg}}</span>
<div>{{1+2}}</div>
<div>{{msg+'-------'+123}}</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
Vue的基本使用步驟
1、需要提供標籤用於填充資料
2、引入vue.js庫檔案
3、可以使用vue的語法做功能了
4、把vue提供的資料填充到標籤裡面
*/
var vm=new Vue({
el:'#test',
data:{
msg:'helloWorld'
}
})
</script>
</body>
</html>
Vue.js之HelloWorld細節分析
- 插值表示式用法
- 將資料填充到HTML標籤中
- 插值表示式支援基本的計算操作
- 例項引數分析
- el: 元素的掛載位置(值可以是CSS選擇器或者DOM元素)
- data:模型資料(值是一個物件)
- Vue程式碼執行原理分析
- 概述編譯過程的概念(Vue語法→原生語法)
- Vue不是直接顯示到頁面的,而且要通過Vue框架把Vue程式碼解析成原聲的js程式碼
- [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-icmAAU3k-1611194823972)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201201140731899.png)]
Vue模板語法學習
- 插值表示式
- 指令
- 事件繫結
- 屬性繫結
- 樣式繫結
- 分支迴圈結構
插值表示式
其實就是把值插入到標籤的語法
<span>{{msg}}</span>
<div>{{1+2}}</div>
<div>{{msg+'-------'+123}}</div>
指令
- 本質就是自定義屬性
- Vue中指定都是以 v- 開頭
v-cloak
-
防止頁面載入時出現閃爍問題
<head> <meta charset="utf-8"> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <link href="css/mui.css" rel="stylesheet" /> <style type="text/css"> /* 1、通過屬性選擇器 選擇到 帶有屬性 v-cloak的標籤 讓他隱藏 */ *[v-cloak]{ display: none; } </style> </head> <body> <div id="test"> <!-- 讓帶有插值 語法的 新增 v-cloak 屬性 在 資料渲染完場之後,v-cloak 屬性會被自動去除, v-cloak一旦移除也就是沒有這個屬性了 屬性選擇器就選擇不到該標籤 也就是對應的標籤會變為可見 --> <span v-cloak>{{msg}}</span> <div v-cloak>{{1+2}}</div> <div v-cloak>{{msg+'-------'+123}}</div> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> /* Vue的基本使用步驟 1、需要提供標籤用於填充資料 2、引入vue.js庫檔案 3、可以使用vue的語法做功能了 4、把vue提供的資料填充到標籤裡面 */ var vm=new Vue({ // el 指定元素 id 是 app 的元素 el:'#test', // data 裡面儲存的是資料 data:{ msg:'helloWorld' } }) </script> </body>
v-text
- v-text指令用於將資料填充到標籤中,作用於插值表示式類似,但是沒有閃動問題
- 如果資料中有HTML標籤會將html標籤一併輸出
- 注意:此處為單向繫結,資料物件上的值改變,插值會發生變化;但是當插值發生變化並不會影響資料物件的值
<div id="app">
<!--
注意:在指令中不要寫插值語法 直接寫對應的變數名稱
在 v-text 中 賦值的時候不要在寫 插值語法
一般屬性中不加 {{}} 直接寫 對應 的資料名
-->
<p v-text="msg"></p>
<p>
<!-- Vue 中只有在標籤的 內容中 才用插值語法 -->
{{msg}}
</p>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
v-html
-
用法和v-text 相似 但是他可以將HTML片段填充到標籤中
-
可能有安全問題, 一般只在可信任內容上使用
v-html
,永不用在使用者提交的內容上 -
它與v-text區別在於v-text輸出的是純文字,瀏覽器不會對其再進行html解析,但v-html會將其當html標籤解析後輸出。
<div id="app"> <p v-html="html"></p> <!-- 輸出:html標籤在渲染的時候被解析 --> <p>{{message}}</p> <!-- 輸出:<span>通過雙括號繫結</span> --> <p v-text="text"></p> <!-- 輸出:<span>html標籤在渲染的時候被原始碼輸出</span> --> </div> <script> let app = new Vue({ el: "#app", data: { message: "<span>通過雙括號繫結</span>", html: "<span>html標籤在渲染的時候被解析</span>", text: "<span>html標籤在渲染的時候被原始碼輸出</span>", } }); </script>
v-pre
- 顯示原始資訊跳過編譯過程
- 跳過這個元素和它的子元素的編譯過程。
- 一些靜態的內容不需要編譯加這個指令可以加快渲染
<span v-pre>{{ this will not be compiled }}</span>
<!-- 顯示的是{{ this will not be compiled }} -->
<span v-pre>{{msg}}</span>
<!-- 即使data裡面定義了msg這裡仍然是顯示的{{msg}} -->
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
v-once
- 執行一次性的插值【當資料改變時,插值處的內容不會繼續更新】
<!-- 即使data裡面定義了msg 後期我們修改了 仍然顯示的是第一次data裡面儲存的資料即 Hello Vue.js -->
<span v-once>{{ msg}}</span>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
雙向資料繫結的介紹
- 當資料發生變化的時候,檢視也就發生變化
- 當檢視發生變化的時候,資料也會跟著同步變化
v-model
- v-model是一個指令,限制在
<input>、<select>、<textarea>、components
中使用
<div id="app">
<div>{{msg}}</div>
<div>
當輸入框中內容改變的時候, 頁面上的msg 會自動更新
<input type="text" v-model='msg'>
</div>
</div>
v-on
- 用來繫結事件的
- 形式如:v-on:click 縮寫為 @click;
v-on事件函式中傳入引數
<body>
<div id="app">
<div>{{num}}</div>
<div>
<!-- 如果事件直接繫結函式名稱,那麼預設會傳遞事件物件作為事件函式的第一個引數 -->
<button v-on:click='handle1'>點選1</button>
<!-- 2、如果事件繫結函式呼叫,那麼事件物件必須作為最後一個引數顯示傳遞,
並且事件物件的名稱必須是$event
-->
<button v-on:click='handle2(123, 456, $event)'>點選2</button>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handle1: function(event) {
console.log(event.target.innerHTML)
},
handle2: function(p, p1, event) {
console.log(p, p1)
console.log(event.target.innerHTML)
this.num++;
}
}
});
</script>
事件修飾符
- 在事件處理程式中呼叫
event.preventDefault()
或event.stopPropagation()
是非常常見的需求。 - Vue 不推薦我們操作DOM 為了解決這個問題,Vue.js 為
v-on
提供了事件修飾符 - 修飾符是由點開頭的指令字尾來表示的
- 修改符也可以結合使用,但是要注意順序,順序會影響效果
<!-- 阻止單擊事件繼續傳播(阻止冒泡) -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再過載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修飾符可以串聯 即阻止冒泡也阻止預設事件 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只當在 event.target 是當前元素自身時觸發處理函式 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>
使用修飾符時,順序很重要;相應的程式碼會以同樣的順序產生。因此,用 v-on:click.prevent.self 會阻止所有的點選,而 v-on:click.self.prevent 只會阻止對元素自身的點選。
按鍵修飾符
- 在做專案中有時會用到鍵盤事件,在監聽鍵盤事件時,我們經常需要檢查詳細的按鍵。Vue 允許為
v-on
在監聽鍵盤事件時新增按鍵修飾符 - 在程式中,為鍵盤每一個按鈕都設定了值,鍵盤按下就會獲取對應的值,監聽鍵盤事件,實際就是監聽鍵盤的值。
<!-- 只有在 `keyCode` 是 13 時呼叫 `vm.submit()` -->
<input v-on:keyup.13="submit">
<!-- -當點選enter 時呼叫 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<!--當點選enter或者space時 時呼叫 `vm.alertMe()` -->
<input type="text" v-on:keyup.enter.space="alertMe" >
常用的按鍵修飾符
.enter => enter鍵
.tab => tab鍵
.delete (捕獲“刪除”和“退格”按鍵) => 刪除鍵
.esc => 取消鍵
.space => 空格鍵
.up => 上
.down => 下
.left => 左
.right => 右
<script>
var vm = new Vue({
el:"#app",
methods: {
submit:function(){},
alertMe:function(){},
}
})
</script>
自定義按鍵修飾符別名
- 在Vue中可以通過
config.keyCodes
自定義按鍵修飾符別名
<div id="app">
預先定義了keycode 116(即F5)的別名為f5,因此在文字輸入框中按下F5,會觸發prompt方法
<input type="text" v-on:keydown.f5="prompt()">
</div>
<script>
Vue.config.keyCodes.f5 = 116;
let app = new Vue({
el: '#app',
methods: {
prompt: function() {
alert('我是 F5!');
}
}
});
</script>
v-bind
- v-bind 指令被用來響應地更新 HTML 屬性
- v-bind:href 可以縮寫為 :href;
<!-- 繫結一個屬性 -->
<img v-bind:src="imageSrc">
<!-- 縮寫 -->
<img :src="imageSrc">
繫結物件
- 我們可以給v-bind:class 一個物件,以動態地切換class。
- 注意:v-bind:class指令可以與普通的class特性共存
1、 v-bind 中支援繫結一個物件
如果繫結的是一個物件 則 鍵為 對應的類名 值 為對應data中的資料
<!--
HTML最終渲染為 <ul class="box textColor textSize"></ul>
注意:
textColor,textSize 對應的渲染到頁面上的CSS類名
isColor,isSize 對應vue data中的資料 如果為true 則對應的類名 渲染到頁面上
當 isColor 和 isSize 變化時,class列表將相應的更新,
例如,將isSize改成false,
class列表將變為 <ul class="box textColor"></ul>
-->
<ul class="box" v-bind:class="{textColor:isColor, textSize:isSize}">
<li>學習Vue</li>
<li>學習Node</li>
<li>學習React</li>
</ul>
<div v-bind:style="{color:activeColor,fontSize:activeSize}">物件語法</div>
<sript>
var vm= new Vue({
el:'.box',
data:{
isColor:true,
isSize:true,
activeColor:"red",
activeSize:"25px",
}
})
</sript>
<style>
.box{
border:1px dashed #f0f;
}
.textColor{
color:#f00;
background-color:#eef;
}
.textSize{
font-size:30px;
font-weight:bold;
}
</style>
繫結陣列
2、 v-bind 中支援繫結一個數組 陣列中classA和 classB 對應為data中的資料
這裡的classA 對用data 中的 classA
這裡的classB 對用data 中的 classB
<ul class="box" :class="[classA, classB]">
<li>學習Vue</li>
<li>學習Node</li>
<li>學習React</li>
</ul>
<script>
var vm= new Vue({
el:'.box',
data:{
classA:‘textColor‘,
classB:‘textSize‘
}
})
</script>
<style>
.box{
border:1px dashed #f0f;
}
.textColor{
color:#f00;
background-color:#eef;
}
.textSize{
font-size:30px;
font-weight:bold;
}
</style>
繫結物件和繫結陣列 的區別
- 繫結物件的時候 物件的屬性 即要渲染的類名 物件的屬性值對應的是 data 中的資料
- 繫結陣列的時候數組裡面存的是data 中的資料
繫結style
<div v-bind:style="styleObject">繫結樣式物件</div>'
<!-- CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號括起來) -->
<div v-bind:style="{ color: activeColor, fontSize: fontSize,background:'red' }">內聯樣式</div>
<!--組語法可以將多個樣式物件應用到同一個元素 -->
<div v-bind:style="[styleObj1, styleObj2]"></div>
<script>
new Vue({
el: '#app',
data: {
styleObject: {
color: 'green',
fontSize: '30px',
background:'red'
},
activeColor: 'green',
fontSize: "30px"
},
styleObj1: {
color: 'red'
},
styleObj2: {
fontSize: '30px'
}
</script>
分支結構
v-if 使用場景
- 1- 多個元素 通過條件判斷展示或者隱藏某個元素。或者多個元素
- 2- 進行兩個檢視之間的切換
<div id="app">
<!-- 判斷是否載入,如果為真,就載入,否則不載入-->
<span v-if="flag">
如果flag為true則顯示,false不顯示!
</span>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
flag:true
}
})
</script>
----------------------------------------------------------
<div v-if="type === 'A'">
A
</div>
<!-- v-else-if緊跟在v-if或v-else-if之後 表示v-if條件不成立時執行-->
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<!-- v-else緊跟在v-if或v-else-if之後-->
<div v-else>
Not A/B/C
</div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
</script>
v-show 和 v-if的區別
- v-show本質就是標籤display設定為none,控制隱藏
- v-show只編譯一次,後面其實就是控制css,而v-if不停的銷燬和建立,故v-show效能更好一點。
- v-if是動態的向DOM樹內新增或者刪除DOM元素
- v-if切換有一個區域性編譯/解除安裝的過程,切換過程中合適地銷燬和重建內部的事件監聽和子元件
- 基於以上區別,因此,如果需要非常頻繁地切換,則使用v-show較好;如果在執行時條件很少改變,則使用v-if較好
迴圈結構
v-for
- 用於迴圈的數組裡面的值可以是物件,也可以是普通元素
<ul id="example-1">
<!-- 迴圈結構-遍歷陣列
item 是我們自己定義的一個名字 代表數組裡面的每一項
items對應的是 data中的陣列-->
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
<script>
new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
}
})
</script>
- 不推薦同時使用
v-if
和v-for
- 當
v-if
與v-for
一起使用時,v-for
具有比v-if
更高的優先順序。
<!-- 迴圈結構-遍歷物件
v 代表 物件的value
k 代表物件的 鍵
i 代表索引
--->
<div v-if='v==13' v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
<script>
new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
obj: {
uname: 'zhangsan',
age: 13,
gender: 'female'
}
}
})
</script>
- key 的作用
- key來給每個節點做一個唯一標識
- key的作用主要是為了高效的更新虛擬DOM
<ul>
<li v-for="item in items" :key="item.id">...</li>
</ul>
案例選項卡
1、 HTML 結構
`
<div id="app">
<div class="tab">
<!-- tab欄 -->
<ul>
<li class="active">apple</li>
<li class="">orange</li>
<li class="">lemon</li>
</ul>
<!-- 對應顯示的圖片 -->
<div class="current"><img src="img/apple.png"></div>
<div class=""><img src="img/orange.png"></div>
<div class=""><img src="img/lemon.png"></div>
</div>
</div>`
2、 提供的資料
list: [{
id: 1,
title: 'apple',
path: 'img/apple.png'
}, {
id: 2,
title: 'orange',
path: 'img/orange.png'
}, {
id: 3,
title: 'lemon',
path: 'img/lemon.png'
}]
3、 把資料渲染到頁面
-
把tab欄 中的數替換到頁面上
- 把 data 中 title 利用 v-for 迴圈渲染到頁面上
- 把 data 中 path利用 v-for 迴圈渲染到頁面上
<div id="app"> <div class="tab"> <ul> <!-- 1、繫結key的作用 提高Vue的效能 2、 key 需要是唯一的標識 所以需要使用id, 也可以使用index , index 也是唯一的 3、 item 是 陣列中對應的每一項 4、 index 是 每一項的 索引 --> <li :key='item.id' v-for='(item,index) in list'>{{item.title}}</li> </ul> <div :key='item.id' v-for='(item, index) in list'> <!-- : 是 v-bind 的簡寫 繫結屬性使用 v-bind --> <img :src="item.path"> </div> </div> </div> <script> new Vue({ // 指定 操作元素 是 id 為app 的 el: '#app', data: { list: [{ id: 1, title: 'apple', path: 'img/apple.png' }, { id: 2, title: 'orange', path: 'img/orange.png' }, { id: 3, title: 'lemon', path: 'img/lemon.png' }] } }) </script>
4、 給每一個tab欄新增事件,並讓選中的高亮
-
4.1 、讓預設的第一項tab欄高亮
- tab欄高亮 通過新增類名active 來實現 (CSS active 的樣式已經提前寫好)
- 在data 中定義一個 預設的 索引 currentIndex 為 0
- 給第一個li 新增 active 的類名
- 通過動態繫結class 來實現 第一個li 的索引為 0 和 currentIndex 的值剛好相等
- currentIndex === index 如果相等 則新增類名 active 否則 新增 空類名
- tab欄高亮 通過新增類名active 來實現 (CSS active 的樣式已經提前寫好)
-
4.2 、讓預設的第一項tab欄對應的div 顯示
- 實現思路 和 第一個 tab 實現思路一樣 只不過 這裡控制第一個div 顯示的類名是 current
<ul> <!-- 動態繫結class 有 active 類名高亮 無 active 不高亮--> <li :class='currentIndex==index?"active":""' :key='item.id' v-for='(item,index) in list' >{{item.title}}</li> </ul> <!-- 動態繫結class 有 current 類名顯示 無 current 隱藏--> <div :class='currentIndex==index?"current":""' :key='item.id' v-for='(item, index) in list'> <!-- : 是 v-bind 的簡寫 繫結屬性使用 v-bind --> <img :src="item.path"> </div> <script> new Vue({ el: '#app', data: { currentIndex: 0, // 選項卡當前的索引 預設為 0 list: [{ id: 1, title: 'apple', path: 'img/apple.png' }, { id: 2, title: 'orange', path: 'img/orange.png' }, { id: 3, title: 'lemon', path: 'img/lemon.png' }] } }) </script>
-
4.3 、點選每一個tab欄 當前的高亮 其他的取消高亮
-
給每一個li新增點選事件
-
讓當前的索引 index 和 當前 currentIndex 的 值 進項比較
-
如果相等 則當前li 新增active 類名 當前的 li 高亮 當前對應索引的 div 新增 current 當前div 顯示 其他隱藏
<div id="app"> <div class="tab"> <ul> <!-- 通過v-on 新增點選事件 需要把當前li 的索引傳過去 --> <li v-on:click='change(index)' :class='currentIndex==index?"active":""' :key='item.id' v-for='(item,index) in list'>{{item.title}}</li> </ul> <div :class='currentIndex==index?"current":""' :key='item.id' v-for='(item, index) in list'> <img :src="item.path"> </div> </div> </div> <script> new Vue({ el: '#app', data: { currentIndex: 0, // 選項卡當前的索引 預設為 0 list: [{ id: 1, title: 'apple', path: 'img/apple.png' }, { id: 2, title: 'orange', path: 'img/orange.png' }, { id: 3, title: 'lemon', path: 'img/lemon.png' }] }, methods: { change: function(index) { // 通過傳入過來的索引來讓當前的 currentIndex 和點選的index 值 相等 // 從而實現 控制類名 this.currentIndex = index; } } }) </script>
data: {
currentIndex: 0, // 選項卡當前的索引 預設為 0
list: [{
id: 1,
title: ‘apple’,
path: ‘img/apple.png’
}, {
id: 2,
title: ‘orange’,
path: ‘img/orange.png’
}, {
id: 3,
title: ‘lemon’,
path: ‘img/lemon.png’
}]
},
methods: {
change: function(index) {
// 通過傳入過來的索引來讓當前的 currentIndex 和點選的index 值 相等
// 從而實現 控制類名
this.currentIndex = index;
}
}
```})
-