Vue 是什么?
- Vue (讀音 /vju?/亲桥,類似于 view) 是一套用于構(gòu)建用戶界面的漸進式框架
- vue 的核心庫只關(guān)注視圖層洛心,不僅易于上手,還便于與第三方庫或既有項目整合
使用Vue將helloworld 渲染到頁面上
指令
- 本質(zhì)就是自定義屬性
- Vue中指令都是以 v- 開頭
v-cloak
- 防止頁面加載時出現(xiàn)閃爍問題
<style type="text/css">
/*1题篷、通過屬性選擇器 選擇到 帶有屬性 v-cloak的標(biāo)簽 讓他隱藏*/
[v-cloak]{
/* 元素隱藏 */
display: none;
}
</style>
<body>
<div id="app">
<!-- 2词身、 讓帶有插值 語法的 添加 v-cloak 屬性
在數(shù)據(jù)渲染完場之后,v-cloak 屬性會被自動去除番枚,
v-cloak一旦移除也就是沒有這個屬性了 屬性選擇器就選擇不到該標(biāo)簽
也就是對應(yīng)的標(biāo)簽會變?yōu)榭梢?-->
<div v-cloak >{{msg}}</div>
</div>
<script type="text/javascript">
/* v-cloak指令的用法
1法严、提供樣式
[v-cloak]{
display: none;
}
2损敷、在插值表達式所在的標(biāo)簽中添加v-cloak指令
背后的原理:先通過樣式隱藏內(nèi)容,然后在內(nèi)存中進行值的替換深啤,替換好之后再顯示最終的結(jié)果*/
var vm = new Vue({
// el 指定元素 id 是 app 的元素
el: '#app',
// data 里面存儲的是數(shù)據(jù)
data: {
msg: 'Hello Vue'
}
});
</script>
</body>
</html>
v-text
- v-text指令用于將數(shù)據(jù)填充到標(biāo)簽中拗馒,作用于插值表達式類似,但是沒有閃動問題
- 如果數(shù)據(jù)中有HTML標(biāo)簽會將html標(biāo)簽一并輸出
- 注意:此處為單向綁定溯街,數(shù)據(jù)對象上的值改變诱桂,插值會發(fā)生變化;但是當(dāng)插值發(fā)生變化并不會影響數(shù)據(jù)對象的值
<div id="app">
<!--
注意:在指令中不要寫插值語法 直接寫對應(yīng)的變量名稱
在 v-text 中 賦值的時候不要在寫 插值語法
一般屬性中不加 {{}} 直接寫 對應(yīng) 的數(shù)據(jù)名
-->
<p v-text="msg"></p>
<p>
<!-- Vue 中只有在標(biāo)簽的 內(nèi)容中 才用插值語法 -->
{{msg}}
</p>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
v-html
- 用法和v-text 相似 但是他可以將HTML片段填充到標(biāo)簽中
- 可能有安全問題, 一般只在可信任內(nèi)容上使用 v-html 呈昔,永不用在用戶提交的內(nèi)容上
- 它與v-text區(qū)別在于v-text輸出的是純文本访诱,瀏覽器不會對其再進行html解析,但v-html會將其當(dāng)html標(biāo)簽解析后輸出韩肝。
<div id="app">
<p v-html="html"></p> <!-- 輸出:html標(biāo)簽在渲染的時候被解析 -->
<p>{{message}}</p> <!-- 輸出: <span>通過雙括號綁定</span> -->
<p v-text="text"></p> <!-- 輸出:<span>html標(biāo)簽在渲染的時候被源碼輸出</span> -->
</div>
<script>
let app = new Vue({
el: "#app",
data: {
message: "<span>通過雙括號綁定</span>",
html: "<span>html標(biāo)簽在渲染的時候被解析</span>",
text: "<span>html標(biāo)簽在渲染的時候被源碼輸出</span>",
}
});
</script>
v-pre
- 顯示原始信息跳過編譯過程
- 跳過這個元素和它的子元素的編譯過程。
- 一些靜態(tài)的內(nèi)容不需要編譯加這個指令可以加快渲染
<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
- 執(zhí)行一次性的插值【當(dāng)數(shù)據(jù)改變時九榔,插值處的內(nèi)容不會繼續(xù)更新】
<!-- 即使data里面定義了msg 后期我們修改了 仍然顯示的是第一次data里面存儲的數(shù)據(jù)即 Hello Vue.js -->
<body>
<div id="app">
<div>{{msg}}</div>
<div v-once>{{info}}</div>
</div>
<script type="text/javascript">
/*v-once的應(yīng)用場景:如果顯示的信息后續(xù)不需要再修改哀峻,你們可以使用v-once,這樣可以提高性能哲泊。*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello Vue',
info: 'nihao'
}
});
</script>
</body>
雙向數(shù)據(jù)綁定
- 當(dāng)數(shù)據(jù)發(fā)生變化的時候剩蟀,視圖也就發(fā)生變化
- 當(dāng)視圖發(fā)生變化的時候,數(shù)據(jù)也會跟著同步變化
v-model
- v-model是一個指令切威,限制在 <input>育特、<select>、<textarea>先朦、components 中使用
<div id="app">
<div>{{msg}}</div>
<div>
/* 當(dāng)輸入框中內(nèi)容改變的時候缰冤, 頁面上的msg 會自動更新 */
<input type="text" v-model='msg'>
</div>
</div>
mvvm
- MVC 是后端的分層開發(fā)概念;MVVM是前端視圖層的概念,主要關(guān)注于 視圖層分離喳魏,也就是說:MVVM把前端的視圖層棉浸,分為了 三部分 Model, View , VM ViewModel
- m model
數(shù)據(jù)層 Vue 中 數(shù)據(jù)層 都放在 data 里面 - v view 視圖
Vue 中 view 即 我們的HTML頁面 - vm (view-model) 控制器 將數(shù)據(jù)和視圖層建立聯(lián)系
vm 即 Vue 的實例 就是 vm
v-on
- 用來綁定事件的
-
形式如:v-on:click 縮寫為 @click;
v-on事件函數(shù)中傳入?yún)?shù)
<body>
<div id="app">
<div>{{num}}</div>
<div>
<!-- 如果事件直接綁定函數(shù)名稱,那么默認(rèn)會傳遞事件對象作為事件函數(shù)的第一個參數(shù) -->
<button v-on:click='handle1'>點擊1</button>
<!-- 2刺彩、如果事件綁定函數(shù)調(diào)用迷郑,那么事件對象必須作為最后一個參數(shù)顯示傳遞,
并且事件對象的名稱必須是$event
-->
<button v-on:click='handle2(123, 456, $event)'>點擊2</button>
</div>
</div>
<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>
事件修飾符
- 在事件處理程序中調(diào)用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求创倔。
- Vue 不推薦我們操作DOM 為了解決這個問題嗡害,Vue.js 為 v-on 提供了事件修飾符
- 修飾符是由點開頭的指令后綴來表示的
<div id="app">
<div>{{num}}</div>
<div v-on:click='handle0'>
<button v-on:click.stop='handle1'>點擊1</button>
</div>
<div>
<a v-on:click.prevent='handle2'>百度</a>
</div>
</div>
<script type="text/javascript">
/*事件綁定-事件修飾符*/
var vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handle0: function(){
this.num++;
},
handle1: function(event){
// 阻止冒泡
// event.stopPropagation();
},
handle2: function(event){
// 阻止默認(rèn)行為
// event.preventDefault();
}
}
});
</script>
- 使用修飾符時,順序很重要畦攘;相應(yīng)的代碼會以同樣的順序產(chǎn)生霸妹。因此,用 v-on:click.prevent.self 會阻止所有的點擊知押,而 v-on:click.self.prevent 只會阻止對元素自身的點擊抑堡。
按鍵修飾符
- 在做項目中有時會用到鍵盤事件摆出,在監(jiān)聽鍵盤事件時,我們經(jīng)常需要檢查詳細的按鍵首妖。Vue 允許為 v-on 在監(jiān)聽鍵盤事件時添加按鍵修飾符
<!-- 只有在 `keyCode` 是 13 時調(diào)用 `vm.submit()` -->
<input v-on:keyup.13="submit">
<!-- -當(dāng)點擊enter 時調(diào)用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<!--當(dāng)點擊enter或者space時 時調(diào)用 `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>
<div id="app">
<form action="">
<div>
用戶名:
<input type="text" v-on:keyup.delete='clearContent' v-model='uname'>
</div>
<div>
密碼:
<input type="text" v-on:keyup.f1='handleSubmit' v-model='pwd'>
</div>
<div>
<input type="button" v-on:click='handleSubmit' value="提交">
</div>
</form>
</div>
<script type="text/javascript">
/* 事件綁定-按鍵修飾符*/
Vue.config.keyCodes.f1 = 113
var vm = new Vue({
el: '#app',
data: {
uname: '',
pwd: '',
age: 0
},
methods: {
clearContent:function(){
// 按delete鍵的時候偎漫,清空用戶名
this.uname = '';
},
handleSubmit: function(){
console.log(this.uname,this.pwd)
}
}
});
</script>
自定義按鍵修飾符別名
- 在Vue中可以通過 config.keyCodes 自定義按鍵修飾符別名
<div id="app">
<input type="text" v-on:keyup.aaa='handle' v-model='info'>
</div>
<script type="text/javascript">
/*事件綁定-自定義按鍵修飾符
規(guī)則:自定義按鍵修飾符名字是自定義的,但是對應(yīng)的值必須是按鍵對應(yīng)event.keyCode值*/
Vue.config.keyCodes.aaa = 65;
var vm = new Vue({
el: '#app',
data: {
info: ''
},
methods: {
handle: function(event){
console.log(event.keyCode)
}
}
});
</script>
v-bind
- v-bind 指令被用來響應(yīng)地更新 HTML 屬性
- v-bind:href 可以縮寫為 :href;
<div id="app">
<a v-bind:href="url">百度</a>
<a :href="url">百度1</a>
<button v-on:click='handle'>切換</button>
</div>
<script type="text/javascript">
/*屬性綁定*/
var vm = new Vue({
el: '#app',
data: {
url: 'http://www.baidu.com'
},
methods: {
handle: function(){
// 修改URL地址
this.url = 'http://itcast.cn';
}
}
});
</script>
- v-model指令的本質(zhì)
<div id="app">
<div>{{msg}}</div>
<input type="text" v-bind:value="msg" v-on:input='handle'>
<input type="text" v-bind:value="msg" v-on:input='msg=$event.target.value'>
<input type="text" v-model='msg'>
</div>
<script type="text/javascript">
/*v-model指令的本質(zhì)*/
var vm = new Vue({
el: '#app',
data: {
msg: 'hello'
},
methods: {
handle: function(event){
// 使用輸入域中的最新的數(shù)據(jù)覆蓋原來的數(shù)據(jù)
this.msg = event.target.value;
}
}
});
</script>
綁定對象
- 我們可以給v-bind:class 一個對象有缆,以動態(tài)地切換class象踊。
- 注意:v-bind:class指令可以與普通的class特性共存
1、 v-bind 中支持綁定一個對象
如果綁定的是一個對象 則 鍵為 對應(yīng)的類名 值 為對應(yīng)data中的數(shù)據(jù)
<!--HTML最終渲染為 <ul class="box textColor textSize"></ul>
注意:
textColor棚壁,textSize 對應(yīng)的渲染到頁面上的CSS類名
isColor杯矩,isSize 對應(yīng)vue data中的數(shù)據(jù) 如果為true 則對應(yīng)的類名 渲染到頁面上
當(dāng) isColor 和 isSize 變化時,class列表將相應(yīng)的更新袖外,
例如史隆,將isSize改成false,
class列表將變?yōu)?<ul class="box textColor"></ul>-->
<ul class="box" v-bind:class="{textColor:isColor, textSize:isSize}">
<li>學(xué)習(xí)Vue</li>
<li>學(xué)習(xí)Node</li>
<li>學(xué)習(xí)React</li>
</ul>
<div v-bind:style="{color:activeColor,fontSize:activeSize}">對象語法</div>
<script>
var vm= new Vue({
el:'.box',
data:{
isColor:true,
isSize:true曼验,
activeColor:"red",
activeSize:"25px",
}
})
</script>
<style>
.box{
border:1px dashed #f0f;
}
.textColor{
color:#f00;
background-color:#eef;
}
.textSize{
font-size:30px;
font-weight:bold;
}
</style>
綁定class數(shù)組
2泌射、 v-bind 中支持綁定一個數(shù)組 數(shù)組中classA和 classB 對應(yīng)為data中的數(shù)據(jù)
- 這里的classA 對用data 中的 classA
- 這里的classB 對用data 中的 classB
<ul class="box" :class="[classA, classB]">
<li>學(xué)習(xí)Vue</li>
<li>學(xué)習(xí)Node</li>
<li>學(xué)習(xí)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>
綁定對象和綁定數(shù)組 的區(qū)別
- 綁定對象的時候 對象的屬性 即要渲染的類名 對象的屬性值對應(yīng)的是 data 中的數(shù)據(jù)
- 綁定數(shù)組的時候數(shù)組里面存的是data 中的數(shù)據(jù)
樣式綁定之class綁定3個細節(jié)用法
<div id="app">
<div v-bind:class='[activeClass, errorClass, {test: isTest}]'>測試樣式</div>
<div v-bind:class='arrClasses'></div>
<div v-bind:class='objClasses'></div>
<div class="base" v-bind:class='objClasses'></div>
<button v-on:click='handle'>切換</button>
</div>
<script type="text/javascript">
/*樣式綁定相關(guān)語法細節(jié):
1、對象綁定和數(shù)組綁定可以結(jié)合使用
2鬓照、class綁定的值可以簡化操作
3熔酷、默認(rèn)的class如何處理?默認(rèn)的class會保留*/
var vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'error',
isTest: true,
arrClasses: ['active','error'],
objClasses: {
active: true,
error: true
}
},
methods: {
handle: function(){
// this.isTest = false;
this.objClasses.error = false;
}
}
});
</script>
<style type="text/css">
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error {
background-color: orange;
}
.test {
color: blue;
}
.base {
font-size: 28px;
}
</style>
綁定style
<div id="app">
<!-- CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case豺裆,記得用單引號括起來) -->
<div v-bind:style='{border: borderStyle, width: widthStyle, height: heightStyle}'>綁定樣式對象</div>
<div v-bind:style='objStyles'></div>
<!--組語法可以將多個樣式對象應(yīng)用到同一個元素 -->
<div v-bind:style='[objStyles, overrideStyles]'></div>
<button v-on:click='handle'>切換</button>
</div>
<script type="text/javascript">
/*樣式綁定之內(nèi)聯(lián)樣式Style:*/
var vm = new Vue({
el: '#app',
data: {
borderStyle: '1px solid blue',
widthStyle: '100px',
heightStyle: '200px',
objStyles: {
border: '1px solid green',
width: '200px',
height: '100px'
},
overrideStyles: {
border: '5px solid orange',
backgroundColor: 'blue'
}
},
methods: {
handle: function(){
this.heightStyle = '100px';
this.objStyles.width = '100px';
}
}
});
</script>
分支結(jié)構(gòu)
v-if 使用場景
- 1- 多個元素 通過條件判斷展示或者隱藏某個元素拒秘。或者多個元素
- 2- 進行兩個視圖之間的切換
<div id="app">
<div v-if='score>=90'>優(yōu)秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else-if='score<80&&score>60'>一般</div>
<div v-else>比較差</div>
<div v-show='flag'>測試v-show</div>
<button v-on:click='handle'>點擊</button>
</div>
<script type="text/javascript">
/*分支結(jié)構(gòu)
v-show的原理:控制元素樣式是否顯示 display:none*/
var vm = new Vue({
el: '#app',
data: {
score: 10,
flag: false
},
methods: {
handle: function(){
this.flag = !this.flag;
}
}
});
</script>
v-show 和 v-if的區(qū)別
- v-show本質(zhì)就是標(biāo)簽display設(shè)置為none臭猜,控制隱藏
v-show只編譯一次躺酒,后面其實就是控制css,而v-if不停的銷毀和創(chuàng)建蔑歌,故v-show性能更好一點阴颖。 - v-if是動態(tài)的向DOM樹內(nèi)添加或者刪除DOM元素
v-if切換有一個局部編譯/卸載的過程,切換過程中合適地銷毀和重建內(nèi)部的事件監(jiān)聽和子組件
循環(huán)結(jié)構(gòu)
v-for
- 用于循環(huán)的數(shù)組里面的值可以是對象丐膝,也可以是普通元素
<div id="app">
<div>水果列表</div>
<ul>
<!-- 循環(huán)結(jié)構(gòu)-遍歷數(shù)組
item 是我們自己定義的一個名 字 代表數(shù)組里面的每一項
items對應(yīng)的是 data中的數(shù)組-->
<li v-for='item in fruits'>{{item}}</li>
<li v-for='(item, index) in fruits'>{{item + '---' + index}}</li>
<li :key='item.id' v-for='(item, index) in myFruits'>
<span>{{item.ename}}</span>
<span>-----</span>
<span>{{item.cname}}</span>
</li>
</ul>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
fruits: ['apple', 'orange', 'banana'],
myFruits: [{
id: 1,
ename: 'apple',
cname: '蘋果'
},{
id: 2,
ename: 'orange',
cname: '橘子'
},{
id: 3,
ename: 'banana',
cname: '香蕉'
}]
}
});
</script>
- 不推薦同時使用 v-if 和 v-for
- 當(dāng) v-if 與 v-for 一起使用時量愧, v-for 具有比 v-if 更高的優(yōu)先級。
<div id="app">
<!-- 循環(huán)結(jié)構(gòu)-遍歷對象
v 代表 對象的value
k 代表對象的 鍵
i 代表索引--->
<div v-if='v==13' v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
</div>
<script type="text/javascript">
// 使用原生js遍歷對象
var obj = {
uname: 'lisi',
age: 12,
gender: 'male'
}
for(var key in obj) {
console.log(key, obj[key])
}
/*循環(huán)結(jié)構(gòu)*/
var vm = new Vue({
el: '#app',
data: {
obj: {
uname: 'zhangsan',
age: 13,
gender: 'female'
}
}
});
</script>
key 的作用
- key來給每個節(jié)點做一個唯一標(biāo)識
- key的作用主要是為了高效的更新虛擬DOM
<ul>
<li v-for="item in items" :key="item.id">...</li>
</ul>
案例:選項卡
1帅矗、 HTML 結(jié)構(gòu)
2偎肃、 提供的數(shù)據(jù)list:[]
3、 把數(shù)據(jù)渲染到頁面
- 把tab欄 中的數(shù)替換到頁面上
1浑此、把 data 中 title 利用 v-for 循環(huán)渲染到頁面上
2累颂、把 data 中 path利用 v-for 循環(huán)渲染到頁面上
4、 給每一個tab欄添加事件,并讓選中的高亮
- 4.1 、讓默認(rèn)的第一項tab欄高亮
(1)tab欄高亮 通過添加類名active 來實現(xiàn) (CSS active 的樣式已經(jīng)提前寫好)
(2)在data 中定義一個 默認(rèn)的 索引 currentIndex 為 0
(3)給第一個li 添加 active 的類名
(3.1)通過動態(tài)綁定class 來實現(xiàn) 第一個li 的索引為 0 和 currentIndex 的值剛好相等
(3.2)currentIndex === index 如果相等 則添加類名 active 否則 添加 空類名 - 4.2 紊馏、讓默認(rèn)的第一項tab欄對應(yīng)的div 顯示
實現(xiàn)思路 和 第一個 tab 實現(xiàn)思路一樣 只不過 這里控制第一個div 顯示的類名是 current - 4.3 料饥、點擊每一個tab欄 當(dāng)前的高亮 其他的取消高亮
(1)給每一個li添加點擊事件
(2)讓當(dāng)前的索引 index 和 當(dāng)前 currentIndex 的 值 進項比較
(3)如果相等 則當(dāng)前l(fā)i 添加active 類名 當(dāng)前的 li 高亮 當(dāng)前對應(yīng)索引的 div 添加 current 當(dāng)前div 顯示 其他隱藏
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor: pointer;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<p>
增加tab欄 <input type="text">
</p>
<div class="tab">
<ul>
<!--1、綁定key的作用 提高Vue的性能
2朱监、 key 需要是唯一的標(biāo)識 所以需要使用id岸啡, 也可以使用index ,index 也是唯一的
3赫编、 item 是 數(shù)組中對應(yīng)的每一項
4巡蘸、 index 是 每一項的 索引-->
<!-- 通過v-on 添加點擊事件 需要把當(dāng)前l(fā)i 的索引傳過去-->
<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'>
<!-- : 是 v-bind 的簡寫 綁定屬性使用 v-bind -->
<img :src="item.path">
</div>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
currentIndex: 0, // 選項卡當(dāng)前的索引
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) {
// 在這里實現(xiàn)選項卡切換操作:本質(zhì)就是操作類名
// 如何操作類名?就是通過傳入過來的索引來讓當(dāng)前的 currentIndex 和點擊的index 值 相等擂送,從而實現(xiàn)控制類名
this.currentIndex = index;
}
}
});
</script>
</body>