1. directives-自定義指令
a.簡介
除了核心功能默認內(nèi)置的指令 (v-model 和 v-show)椭坚,Vue 也允許注冊自定義指令。注意,在 Vue2.0 中龙宏,代碼復(fù)用和抽象的主要形式是組件玛界。然而万矾,有的情況下,你仍然需要對普通 DOM 元素進行底層操作慎框,這時候就會用到自定義指令。舉個聚焦輸入框的例子鲤脏,如下:
當(dāng)頁面加載時,該元素將獲得焦點 (注意:autofocus 在移動版 Safari 上不工作)猎醇。事實上窥突,只要你在打開這個頁面后還沒點擊過任何內(nèi)容硫嘶,這個輸入框就應(yīng)當(dāng)還是處于聚焦?fàn)顟B(tài)。現(xiàn)在讓我們用指令來實現(xiàn)這個功能:
// 注冊一個全局自定義指令 `v-focus`
Vue.directive('focus', {
// 當(dāng)被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
如果想注冊局部指令沦疾,組件中也接受一個 directives 的選項:
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
然后你可以在模板中任何元素上使用新的 v-focus 屬性称近,如下:
<input v-focus>
b. 案例
directives ---- vue自定義指令
?作用
???1. 要操作dom時候
???2. 使用集成第三方插件時候
?定義:
directives:{
img:{
inserted(el,binding){
// el 當(dāng)前指令所在的html節(jié)點
// binding.value 指令的值
}
}
}
使用
<div v-img="xxxxx">
單詞:
- directives 指令
- inserted 已插入
- binding 綁定
案例1-自定義指令 v-img
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定義指令</title>
<style>
.box{width: 180px;height: 320px;}
</style>
</head>
<body>
<div id="app">
<div class="box" v-img="pics[0]"></div>
<div class="box" v-img="pics[1]"></div>
<div class="box" v-img="pics[2]"></div>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{pics:[
"http://images.entgroup.cn/group2/M00/02/96/wKgAS13gt0WAS3CjAABoTRx_PZ8927.jpg",
"http://images.entgroup.cn/group1/M00/05/2C/wKgASV34PqSAQliYAABmxNg1oI0829.jpg",
"http://images.entgroup.cn/group2/M00/02/93/wKgAS12lOvCAP93oAACEwKNAR90206.jpg"]},
// 自定義指令 最大作用可以獲取到自定義指令所在的 html 元素節(jié)點
directives:{
img:{
// bind update inserted 當(dāng)被插入到父節(jié)點
inserted(el,binding){
// el 自定義指令所再的元素
// binding 綁定的數(shù)據(jù) value 自定義指令的值
let color = Math.floor(Math.random()*1000000);
el.style.backgroundColor="#"+color;
// 加載圖片
let img = new Image();
// 創(chuàng)造一個新的圖片;
img.src = binding.value;
console.log(el,binding);
img.onload=function(){
el.style.backgroundImage=`url(${binding.value})`;
// 賦值背景圖片
}
}
}
}
})
</script>
</body>
</html>
2. class綁定
a. 簡介
- 屬性綁定
:class="'red blue'" - 動態(tài)綁定
:class="{'red':flag}"
<div :class="isActive?'yellow':'red'">111</div>
:class="{'active':index==current}" - 數(shù)組綁定
:class="['red','em','small']" - 對象綁定
:class="classobj"
data:{
classobj:{
a:true,
b:true
}
}
b.案例 1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>class綁定</title>
<style>
.red{color:red;}
.em{font-style: italic;}
.small{font-size:12px;}
</style>
</head>
<body>
<div id="app">
<!-- 在指令的值是js表達式不是字符串 -->
<h1 :class="'red'">class是一個屬性 可通過屬性綁定</h1>
<h1 :class="{'red':flag}">class 對象方式綁定</h1>
<h1 :class="['red','em','small']">數(shù)組的方法綁定多個</h1>
<button @click="flag=!flag">{{flag}}</button>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
flag:true,
red:'red'
}
})
</script>
</body>
</html>
c. 案例2-選項卡切換
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>選項卡案例</title>
<style>
.content{
width: 300px;
height: 300px;
clear:both;
border: 1px solid #ccc;
}
.title{
display: inline-block;
padding: 5px 15px;
background-color: #ccc;
}
.active{color:#fff;background-color: dodgerblue;}
</style>
</head>
<body>
<div id="app">
<div class="title"
v-for="(item,index) in list"
:key="index"
@click="current=index"
:class="{'active':index==current}"
>{{item.title}}</div>
<!-- 當(dāng)單擊標(biāo)題 設(shè)置current為當(dāng)前的index(單擊改變current) -->
<!-- 類名active 的綁定 如果當(dāng)前current與index相等 就綁定activeclass -->
<div class="content">{{list[current].content}}</div>
<!-- 內(nèi)容根據(jù) current值不同來顯示不同內(nèi)容 -->
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
list:[
{title:"jquery",content:"jquery內(nèi)容"},
{title:"vue",content:"vue內(nèi)容"},
{title:"react",content:"react內(nèi)容"},
],
current:0,//默認顯示第幾個div
}
})
</script>
</body>
</html>
3. style綁定
動態(tài)綁定
- 三目寫法
- 對象寫法
- 數(shù)組寫法
a.結(jié)構(gòu)
style 綁定
對象
<h1 :style="{fontSize:'14px',color:'red'}">style的綁定</h1>
<h1 :style="obj">對象變量方式</h1>
data:{
obj:{'font-size':"48px",fontStyle:'italic',color:red}
}
b. 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>style綁定</title>
<style> </style>
</head>
<body>
<div id="app">
<h1 :style="{fontSize:'14px',color:'red'}">style的綁定</h1>
<div :style="'background:'+(isActive?'red':'yello')">動態(tài)三目寫法</div>
<h1 :style="obj">對象變量方式</h1>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
obj:{
"font-size":"100px",
fontStyle:'italic',
color:'blue'
}
}
})
</script>
</body>
</html>
4. 綜合案例--購物車
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>購物車案例</title>
</head>
<body>
<div id="app">
<table>
<tr>
<td >全選 <input type="checkbox" v-model="all" @change="checkAll"></td>
<td>id</td> <td>書名</td> <td>日期</td> <td>價格</td><td>數(shù)量</td> <td>操作</td>
</tr>
<tr v-for="(item,index) in books" :key="index">
<td><input type="checkbox" v-model="item.sel"></td>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>{{item.price}}</td>
<td>
<button @click="item.num--">-</button>
<input type="text" v-model.number="item.num">
<button @click="item.num++">+</button>
</td>
<td> <button @click="delItem(item)">刪除</button></td>
</tr>
</table>
總價格:{{total}}
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
books:[
{sel:true,id:1,name:"小紅書",date:"2020/12/24",price:100,num:1},
{sel:true,id:2,name:"小藍書",date:"2020/12/25",price:20,num:1},
{sel:true,id:3,name:"小綠書",date:"2020/12/26",price:80,num:1},
{sel:true,id:4,name:"小白書",date:"2020/11/24",price:300,num:1},
{sel:true,id:5,name:"vue精通",date:"2020/10/05",price:175,num:2}
],
all:true,
},
computed:{
"total":function(){
var n=0;
this.books.forEach(item=>{
if(item.sel){
n+=item.price*item.num;
// 加上每項 單價*數(shù)量
}
})
return n;
// 返回n;
}
},
watch:{
"books":{
handler:function(nval){
this.all = this.books.every(item=>item.sel);
// every 每一個都返回為true衡未,則最終返回為true,有一個返回為false最終都返回為false
// 當(dāng)books有任何變化的時候都檢測全選是否為true or false
},
deep:true
}
},
methods:{
delItem(item){
var re = window.confirm("你確定要刪除么");
if(re){
let ind = this.books.indexOf(item);
this.books.splice(ind,1);
}
},
checkAll(){
this.books.forEach(item=>item.sel=this.all);
// 當(dāng)全選按鈕發(fā)生改變是 缓醋,所有的books項目的sel值都等于 all的值
}
}
})
</script>
</body>
</html>
5. Vue 動畫
1. vue它不能直接實現(xiàn)動畫送粱,它提供動畫各階段需要的class
2. <transition> 組件提供class
3. 在vue中掂之,動畫是在元素顯示與隱藏的過程中脆丁,添加 class實現(xiàn)的
v-if v-else v-show
4. transition組件提供
v-enter-active 元素整個進入的過程
v-enter 元素進入的初始狀態(tài)
v-enter-to 元素進入的結(jié)束狀態(tài)
v-leave-active 元素整個離開的過程
v-leave 元素的離開初始狀態(tài)
v-leave-to 元素的離開結(jié)束狀態(tài)
自定義動畫名
enter-active-class=“xxx”
leave-active-class=“xxx”
要引入第三方css animate.css
動畫模式 mode
in-out 先執(zhí)行進入動畫偎快,再執(zhí)行離開動畫
out-in 先執(zhí)行離開動畫洽胶,再執(zhí)行進入動畫
5. transition-group組件
tag 指定標(biāo)簽
move-class 給正在移動中的元素添加class
name 動畫名稱
指定進入離開class
enter-active-class
leave-active-class
案例 1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>動畫</title>
<script src="./js/vue.js"></script>
<style>
.fade-enter-active{ transition: all 2s ease;}
/* 元素進入的整個過程 */
.fade-leave-active{ transition: all .5s ease;}
/* 元素離開的整個過程 */
.fade-enter{opacity: 0;}
/* 進入的初始狀態(tài) */
.fade-enter-to{opacity: 1;}
/* 進入的結(jié)束狀態(tài) */
.fade-leave{opacity: 1;}
/* 離開的初始狀態(tài) */
.fade-leave-to{opacity: 0;}
/* 離開的結(jié)束狀態(tài) */
</style>
</head>
<body>
<div id="app">
<button @click="flag=!flag">切換</button> <br>
<transition name="fade">
<img src="./img/sun.jpg" v-if="flag" alt="" width="120">
</transition>
</div>
<script>
new Vue({
el:"#app",
data:{flag:true}
})
</script>
</body>
</html>
案例 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>動畫</title>
<script src="./js/vue.js"></script>
<style>
/* keyframes定義關(guān)鍵幀 fadeIn 動畫名稱 */
@keyframes fadeIn {
from{opacity: 0; transform:translate(-100px,0) rotate(-180deg)}
/* 從{透明度:0,變換:位置變換(x位置-100姊氓,y位置0) 旋轉(zhuǎn)變換(-180度)} */
to{opacity: 1; transform:translate(0,0) rotate(0deg)}
}
@keyframes fadeOut {
0%{opacity: 1;transform:translate(0,0) rotate(0deg)}
100%{opacity: 0;transform:translate(100px,0) rotate(180deg)}
}
.fade-enter-active{ animation: fadeIn ease 1s; }
/* 元素進入的整個過程 */
.fade-leave-active{ animation: fadeOut ease 1s;}
/* 元素離開的整個過程 */
</style>
</head>
<body>
<div id="app">
<button @click="flag=!flag">切換</button> <br>
<transition name="fade">
<img src="./img/sun.jpg" v-if="flag" alt="" width="120">
</transition>
<!-- transition是vue內(nèi)置的一個組件,只要是動畫都要包裹再里面 深读跷,動態(tài)給img 再離開和進入是添加6個不同的class -->
</div>
<script>
new Vue({
el:"#app",
data:{flag:true}
})
</script>
</body>
</html>
6. animate引入動畫
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>動畫</title>
<link rel="stylesheet" href="./css/animate.min.css">
<!-- 著名的css動畫庫引入 -->
<script src="./js/vue.js"></script>
<style>
</style>
</head>
<body>
<div id="app">
<button @click="flag=!flag">切換</button> <br>
<transition enter-active-class="slideInDown animated" leave-active-class=" hinge animated">
<img src="./img/sun.jpg" v-if="flag" alt="" width="120">
</transition>
<!-- 定義進入的動畫名稱 定義離開的動畫名稱 -->
<!-- transition是vue內(nèi)置的一個組件效览,只要是動畫都要包裹再里面 深荡短,動態(tài)給img 再離開和進入是添加6個不同的class -->
</div>
<script>
new Vue({
el:"#app",
data:{flag:true}
})
</script>
</body>
</html>
7. 動畫模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>動畫組</title>
<link rel="stylesheet" href="./css/animate.min.css">
<script src="./js/vue.js"></script>
<style>
.fadeOutUp{ position: absolute;}
.move{ transition: all ease .6s;}
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="temp" placeholder="添加內(nèi)容"
@keyup.enter="list.unshift(temp);temp=''">
<transition-group tag="div"
enter-active-class="fadeInDown animated"
leave-active-class="fadeOutUp animated"
move-class="move"
>
<div v-for="(item,index) in list" :key="item">
{{item}} <button @click="delItem(item)">x</button>
</div>
</transition-group>
</div>
<script>
new Vue({
el:"#app",
data:{
temp:"",
list:['vue','react','angular']
},
methods:{
delItem(item){
var ind = this.list.indexOf(item);
this.list.splice(ind,1)
}
}
})
</script>
</body>
</html>