一、技術(shù)棧
二、參考文獻(xiàn)
- 官網(wǎng)
https://cn.vuejs.org/v2/guide/ - 菜鳥(niǎo)教程
https://www.runoob.com/vue2/vue-tutorial.html
三、引入
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
[v-cloak]{
display:none;
}
</style>
<!-- 2. 使用CDN -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue"></script> -->
<!-- 3. npm加載 npm i vue -->
</head>
<body>
<div id="app" v-cloak>
<h1>{{ msg }}</h1>
狀態(tài)碼是:<span>{{ code }}</span>
</div>
<!-- 1. 直接下載源碼,使用script標(biāo)簽引入 -->
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el:'#app', //element 掛載在DOM節(jié)點(diǎn)上
data:{
msg:"歡迎學(xué)習(xí)VUE",
code:"200"
}
});
</script>
</body>
</html>
四、常用指令
1、v-bind(簡(jiǎn)寫(xiě)為:)
動(dòng)態(tài)地綁定一個(gè)或多個(gè)特性,或一個(gè)組件 prop 到表達(dá)式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
.bg-color-red{
background: red;
}
.color-white{
color:#fff;
}
.color-blue{
color:blue;
}
</style>
</head>
<body>
<div id="app">
<span :class="cla" :style="style">這里是文字</span>
</div>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
cla:{
"bg-color-red":true,
"color-white":true
},
style:{
background:"yellow",
color:"lightgreen"
}
}
})
</script>
</body>
</html>
2、v-on(簡(jiǎn)寫(xiě)為:@)
綁定事件監(jiān)聽(tīng)器。事件類型由參數(shù)指定。表達(dá)式可以是一個(gè)方法的名字或一個(gè)內(nèi)聯(lián)語(yǔ)句,如果沒(méi)有修飾符也可以省略。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
</head>
<body>
<div id="app">
<input type="button" value="點(diǎn)擊" v-on:click="sayhello">
</div>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el:'#app',
data:{},
methods:{
sayhello(){
alert('hello')
}
}
});
</script>
</body>
</html>
案例:跑馬燈
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<input type="button" value="浪起來(lái)" @click="lang">
<input type="button" value="猥瑣發(fā)育" @click="weisuo">
<p>{{msg}}</p>
</div>
</body>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script>
new Vue({
el:"#app",
data:{
msg:"猥瑣發(fā)育,別浪~",
timer:null
},
methods:{
lang(){
clearInterval(this.timer);
this.timer = setInterval(()=>{
this.msg = this.msg.substring(1)+this.msg.substring(0,1);
},300)
},
weisuo(){
clearInterval(this.timer);
}
}
})
</script>
</html>
3、v-model
在表單控件或者組件上創(chuàng)建雙向綁定
案例:計(jì)算器
<!DOCTYPE html>
<html lang="zh">
<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></title>
<style type="text/css">
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<input type="text" v-model:value="num1">
<select v-model:value="fuhao">
<option value ="+" >+</option>
<option value ="-">-</option>
<option value ="*">×</option>
<option value ="/">÷</option>
</select>
<input type="text" v-model:value="num2">
<button @click="cal()">=</button>
<span v-text="re"></span>
</div>
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
num1: '',
num2:'',
fuhao:'',
re: ''
},
methods:{
cal:function(){
this.re = eval(this.num1 + this.fuhao + this.num2) ;
}
},
computed:{
}
});
</script>
</body>
</html>
4、v-for
遍歷
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<div id="app" v-cloak>
<ul>
<li v-for="user in users" :key="user.id"><input type="checkbox">{{user.id}}-----{{user.name}}</li>
</ul>
<button @click="del">shanchu</button>
<!-- <ol>
<li v-for="(iten,key) in zhangsan">{{iten}}--{{key}}</li>
</ol> -->
</div>
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
users:[
{id:2,name:'zengke'},
{id:3,name:'zhangzhen'},
{id:4,name:'lihaoshuahg'},
{id:7,name:'xiongli'},
{id:9,name:'yanhe'}
],
zhangsan:{
age:19,
sex:"man",
grade:'大三年級(jí)'
},
},
methods:{
del(){
this.users.shift()
}
}
});
</script>
</body>
</html>
五、filter
過(guò)濾器
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<div id="app" v-cloak>
<p>{{ msg | change('--') | dada('**') }}</p>
</div>
<div id="dapp">
{{msg | dada('xixi')}}
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
//全局過(guò)濾器.任何一個(gè)Vue節(jié)點(diǎn)都可以使用
Vue.filter('change',function(data,arg){
return data.replace(/天真/g,arg);
});
Vue.filter('dada',function(data,arg){
return data.replace(/我/g,arg);
});
new Vue({
el:"#app",
data:{
msg:"天真的我對(duì)天真的自己說(shuō),我是這個(gè)世界上最天真的人呢!"
},
// 局部過(guò)濾器
filters:{
dada:function(data,arg){
return data.replace(/我/g,arg)+'--------------------'; //就近原則
}
}
});
new Vue({
el:"#dapp",
data:{
msg:"快樂(lè)的池塘里我有一只快樂(lè)的我小青蛙"
}
})
</script>
</body>
</html>
六、鍵盤事件
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<div id="app" v-cloak>
<input type="text" @keyup.82="print">
{{ msg }}
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
//自定義鍵盤事件修飾符
// Vue.config.keyCodes.add = 82;
new Vue({
el:"#app",
data:{
msg:''
},
methods:{
print(event){
this.msg = event.target.value;
}
}
});
</script>
</body>
</html>
七、自定義指令
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<form action="" id="app">
用戶名<input type="text" id="user" v-focus><br><br>
<!-- 使用自定義的指令必須要添加v-前綴 vue指令的規(guī)范是所有的指令都是以v-前綴開(kāi)始的 -->
密碼<input type="text"><br><br>
<input type="submit">
</form>
</body>
<script src="../day1/vue.js" type="text/javascript" charset="utf-8"></script>
<script>
/*
window.onload = function(){
document.getElementById('user').focus();
}
*/
//擴(kuò)展VUE指令,自定義指令
//全局的
//參數(shù)一:指令的名稱,注意這里的指令的名稱是定義的時(shí)候,不需要添加v-前綴
//參數(shù)二:是一個(gè)指令的配置對(duì)象
Vue.directive('focus',{
//配置項(xiàng),鉤子函數(shù)
//第一個(gè)參數(shù),指令操作的節(jié)點(diǎn)
bind:function(el){
//指令在第一次調(diào)用的時(shí)候出發(fā),VUE的虛擬dom在進(jìn)行渲染的時(shí)候觸發(fā).這個(gè)時(shí)候節(jié)點(diǎn)還沒(méi)有進(jìn)入真實(shí)dom
},
inserted:function(el){
//在虛擬dom進(jìn)去到真實(shí)dom的時(shí)候調(diào)用
el.focus();
},
update:function(el){
//在節(jié)點(diǎn)更新的時(shí)候使用
}
});
new Vue({
el:"#app",
data:{
}
});
</script>
</html>
八、自定義有值指令
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<div id="app" v-cloak>
<p v-fontsize:style="'20px'" >要經(jīng)常給媽媽點(diǎn)錢,讓媽媽去揮霍吧!</p>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
Vue.directive('fontsize',{
bind:function(el,binding){
// binding.arg 元素的鍵(style)
el[binding.arg].fontSize = binding.value;
console.log(binding)
},
inserted:function(){},
update:function(){}
})
Vue.directive('name',function(el,song){
// el.操作
})
new Vue({
el:"#app",
data:{
}
});
</script>
</body>
</html>
九、自定義指令對(duì)象傳參
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div>div{
width:20px;
height:20px;
background: #2AC845;
}
.show{
border: 1px dashed #007AFF;
}
.size{
width:200px;
height: 200px;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<div v-bind:class="style" v-style:style="{'font-size':'20px',background:'red'}">
lalalala
</div>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
Vue.directive('style',function(el,bin){
for(let i in bin.value){
el.style[i] = bin.value[i];
}
})
new Vue({
el:"#app",
data:{
style:{
show: true,
size:true
}
}
});
</script>
</body>
</html>
十、局部定義
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<!-- <input type="text" v-focus> -->
</div>
<footer id="dapp">
<input type="text" v-focus>
</footer>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
/*
Vue.directive('focus',{
bind:function(){},
inserted:function(el){
el.focus();
},
update:function(){}
})
*/
new Vue({
el:"#app",
data:{
},
directives:{
focus:{
bind:function(){},
inserted:function(el){
el.focus();
},
update:function(){}
}
}
});
new Vue({
el:"#dapp",
data:{
}
});
</script>
</body>
</html>
十一、vue-resource
網(wǎng)絡(luò)請(qǐng)求
<!DOCTYPE html>
<html lang="zh">
<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></title>
<style>
ul{
list-style: none;
}
ul li {
width:100px;
height:150px;
border:1px solid #ccc;
margin: 20px;
}
ul li img{
width:100%;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<ul>
<li v-for="user in list">
<img v-bind:src="user.avatar_url" alt="user.login">
{{user.login}}
</li>
</ul>
</div>
<script src="../day1/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
list:[]
},
created:function(){
this.$http.get('https://api.github.com/users').then(function(response){
this.list = response.body;
},function(){
});
}
});
</script>
</body>
</html>
十二、axios
基于promise用于瀏覽器和node.js的http客戶端
特點(diǎn)
- 支持瀏覽器和node.js
- 支持promise
- 能攔截請(qǐng)求和響應(yīng)
- 能轉(zhuǎn)換請(qǐng)求和響應(yīng)數(shù)據(jù)
- 能取消請(qǐng)求
- 自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù)
- 瀏覽器端支持防止CSRF(跨站請(qǐng)求偽造)
發(fā)送請(qǐng)求的兩種方式
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<div id="app" v-cloak>
<input type="button" value="獲取" @click="getlist">
<ul>
<li v-for="item in list" :key="item.id">item.name</li>
</ul>
</div>
<script src="../day1/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
list:[]
},
methods:{
getlist:function(){
axios.get('http://localhost/vue_api/index.php?m=api&a=getlist').then(response=>{
this.list = response.data;
console.log(this.list);
}).catch(error=>{
//處理錯(cuò)誤
})
}
},
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<input type="text" v-model:value="id">
<input type="text" v-model:value="name">
<input type="button" value="提交" @click="add">
</div>
<script src="../day1/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
id:"",
name:''
},methods:{
add(){
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/*
axios.post('http://localhost/vue_api/index.php?m=api&a=addcar',{id:this.id,name:this.name,ctime:new Date().toUTCString()}).then(response=>{
console.log(response.data);
})
*/
axios({
method:'post',
url:'http://localhost/vue_api/index.php?m=api&a=addcar',
data:{
id:this.id,
name:this.name,
ctime:new Date().toUTCString()
},
headers:{
'Content-Type':'application/x-www-form-urlencoded'
},
//在傳遞post數(shù)據(jù)的時(shí)候如果沒(méi)有經(jīng)過(guò)這樣的處理,那么后端接收數(shù)據(jù)會(huì)非常麻煩.
/*
transformRequest:[
data=>{
let params = '';
for (var index in data) {
params += index + '=' + data[index] + '&'
}
return params;
}
]
*/
}).then(response=>{
console.log(response.data);
})
}
}
});
</script>
</body>
</html>
十三、動(dòng)畫(huà)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
@keyframes boom{
0%{
transform: scale(0);
}
50%{
transform: scale(1.5);
}
100%{
transform: scale(1);
}
}
.v-enter-active{
animation: boom 1s ease;
}
.v-leave-active{
animation: boom 1s reverse;
}
p{
width:200px;
height:200px;
background: #4CD964;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<button @click="flag=!flag">boom</button>
<!-- 所有需要進(jìn)行動(dòng)畫(huà)或者過(guò)度的元素必須添加在transition標(biāo)簽里面 -->
<transition>
<p v-show="flag">好煩你呀</p>
</transition>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
flag:true
}
});
</script>
</body>
</html>
十四、使用動(dòng)畫(huà)類實(shí)現(xiàn)動(dòng)畫(huà)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" >
</head>
<body>
<div id="app" v-cloak>
<button @click="flag=!flag">animate</button>
<!-- 如果傳入的值是一個(gè)固定的值,那么這個(gè)值表示的是進(jìn)場(chǎng)與離場(chǎng)動(dòng)畫(huà)相同的時(shí)間 -->
<!-- :duration="1000" -->
<transition name="my"
enter-active-class="bounceInDown"
leave-active-class="bounceOutDown"
:duration="{enter:800,leave:500}"
>
<div v-show="flag" class="animated">中午睡覺(jué)吃了一只蚊子</div>
</transition>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
flag:false
}
});
</script>
</body>
</html>
十五、鉤子函數(shù)實(shí)現(xiàn)動(dòng)畫(huà)效果
<!DOCTYPE html>
<html lang="zh">
<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></title>
<style>
#app div{
width:50px;
height:50px;
background: cyan;
border-radius: 50%;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<button @click="flag=!flag">動(dòng)畫(huà)</button>
<transition
@before-enter="before"
@enter="enter"
@after-enter="after"
>
<div v-show="flag"></div>
</transition>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
flag:false
},
methods:{
// el表示要操作的DOM對(duì)象
before(el){
el.style.transform = 'translate(0,0)';
},
enter(el,done){
el.offsetWidth ;
// 需要使用offset系列實(shí)現(xiàn)動(dòng)畫(huà)的刷新或者平滑過(guò)渡
el.style.transform = 'translate(350px,150px)';
el.style.transition = 'all .3s ease';
done(); //down回調(diào)函數(shù)就是指下面after函數(shù)
},
after(el){
this.flag= !this.flag;
}
}
});
</script>
</body>
</html>
十六、列表過(guò)渡
<!DOCTYPE html>
<html lang="zh">
<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></title>
<style>
li{
line-height: 50px;
padding:5px;
border:1px dashed #333;
margin-bottom: 10px;
text-indent: 1em;
width:100%
}
li:hover{
background: lightseagreen;
transition: all 0.3s ease;
}
input {
margin-left:40px;
height:60px;
width:200px;
font-size: 20px;
text-indent: 20px;
}
.my-enter,
.my-leave-to{
transform: translateY(200px);
opacity: 0;
}
.my-enter-active,
.my-leave-active{
transition: all 1s ease-in-out;
}
.my-move{
transition : all 1s ;
}
.my-leave-active {
position: absolute;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<input type="text" v-model:value="id">
<input type="text" v-model:value="name">
<input type="button" value="添加" @click="add">
<transition-group name="my" tag="ul" appear >
<li v-for="(item,index) in list" :key="item.id" @click="del(index)">{{item.id}}. {{item.name}}</li>
</transition-group>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
id:'',
name:'',
list:[
{id:1,name:'魏忠賢'},
{id:3,name:'趙高'},
{id:4,name:'曹正淳'},
{id:6,name:'李公公'},
]
},
methods:{
add(){
this.list.push({id:this.id,name:this.name});
this.id = this.name = '';
},
del(i){
this.list.splice(i,1);
}
}
});
</script>
</body>
</html>
十七、生命周期函數(shù)
參考文獻(xiàn):https://segmentfault.com/a/1190000011381906
Vue生命周期中mounted和created的區(qū)別
beforeCreate
類型:
Function
-
詳細(xì):
在實(shí)例初始化之后,數(shù)據(jù)觀測(cè) (data observer) 和 event/watcher 事件配置之前被調(diào)用。
參考:生命周期圖示
created
類型:
Function
-
詳細(xì):
在實(shí)例創(chuàng)建完成后被立即調(diào)用。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(cè) (data observer),屬性和方法的運(yùn)算,watch/event 事件回調(diào)。然而,掛載階段還沒(méi)開(kāi)始,
$el
屬性目前不可見(jiàn)。 參考:生命周期圖示
beforeMount
類型:
Function
-
詳細(xì):
在掛載開(kāi)始之前被調(diào)用:相關(guān)的
render
函數(shù)首次被調(diào)用。該鉤子在服務(wù)器端渲染期間不被調(diào)用。
參考:生命周期圖示
mounted
類型:
Function
-
詳細(xì):
el
被新創(chuàng)建的vm.$el
替換,并掛載到實(shí)例上去之后調(diào)用該鉤子。如果 root 實(shí)例掛載了一個(gè)文檔內(nèi)元素,當(dāng)mounted
被調(diào)用時(shí)vm.$el
也在文檔內(nèi)。注意
mounted
不會(huì)承諾所有的子組件也都一起被掛載。如果你希望等到整個(gè)視圖都渲染完畢,可以用 vm.$nextTick 替換掉mounted
:mounted: function () { this.$nextTick(function () { // Code that will run only after the // entire view has been rendered }) }
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
參考:生命周期圖示
beforeUpdate
類型:
Function
-
詳細(xì):
數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬 DOM 打補(bǔ)丁之前。這里適合在更新之前訪問(wèn)現(xiàn)有的 DOM,比如手動(dòng)移除已添加的事件監(jiān)聽(tīng)器。
該鉤子在服務(wù)器端渲染期間不被調(diào)用,因?yàn)橹挥谐醮武秩緯?huì)在服務(wù)端進(jìn)行。
參考:生命周期圖示
updated
類型:
Function
-
詳細(xì):
由于數(shù)據(jù)更改導(dǎo)致的虛擬 DOM 重新渲染和打補(bǔ)丁,在這之后會(huì)調(diào)用該鉤子。
當(dāng)這個(gè)鉤子被調(diào)用時(shí),組件 DOM 已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴于 DOM 的操作。然而在大多數(shù)情況下,你應(yīng)該避免在此期間更改狀態(tài)。如果要相應(yīng)狀態(tài)改變,通常最好使用計(jì)算屬性或 watcher 取而代之。
注意
updated
不會(huì)承諾所有的子組件也都一起被重繪。如果你希望等到整個(gè)視圖都重繪完畢,可以用 vm.$nextTick 替換掉updated
:updated: function () { this.$nextTick(function () { // Code that will run only after the // entire view has been re-rendered }) }
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
參考:生命周期圖示
activated
類型:
Function
-
詳細(xì):
keep-alive 組件激活時(shí)調(diào)用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
-
參考:
deactivated
類型:
Function
-
詳細(xì):
keep-alive 組件停用時(shí)調(diào)用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
-
參考:
beforeDestroy
類型:
Function
-
詳細(xì):
實(shí)例銷毀之前調(diào)用。在這一步,實(shí)例仍然完全可用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
參考:生命周期圖示
destroyed
類型:
Function
-
詳細(xì):
Vue 實(shí)例銷毀后調(diào)用。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷毀。
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
errorCaptured
2.5.0+ 新增
類型:
(err: Error, vm: Component, info: string) => ?boolean
-
詳細(xì):
當(dāng)捕獲一個(gè)來(lái)自子孫組件的錯(cuò)誤時(shí)被調(diào)用。此鉤子會(huì)收到三個(gè)參數(shù):錯(cuò)誤對(duì)象、發(fā)生錯(cuò)誤的組件實(shí)例以及一個(gè)包含錯(cuò)誤來(lái)源信息的字符串。此鉤子可以返回
false
以阻止該錯(cuò)誤繼續(xù)向上傳播。你可以在此鉤子中修改組件的狀態(tài)。因此在模板或渲染函數(shù)中設(shè)置其它內(nèi)容的短路條件非常重要,它可以防止當(dāng)一個(gè)錯(cuò)誤被捕獲時(shí)該組件進(jìn)入一個(gè)無(wú)限的渲染循環(huán)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<button @click="msg='還好吧'">改變</button>
{{msg}}
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
msg:'今天真是個(gè)好日子呀'
},
methods:{},
computed:{},
filters:{},
directives:{},
components:{}, //組件
beforeCreate:function(){
alert('beforeCreate');
},
created:function(){
alert('created');
},
beforeMount:function(){
alert('beforeMount');
},
mouted:function(){
alert('mouted');
},
beforeUpdate:function(){
alert('beforeUpdate');
},
updated:function(){
alert('updated');
},
beforeDestroy:function(){
alert('beforeDestroy');
},
destroyed:function(){
alert('destroyed');
}
});
</script>
</body>
</html>
十八、創(chuàng)建組建的方式
//法一
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<!-- //全局組件可以使用在任何一個(gè)VUE所掛載的DOM上。 -->
<!-- //使用的組件的方式是將組建用于類似于HTML的結(jié)構(gòu),按照HTML雙標(biāo)簽的格式書(shū)寫(xiě) -->
<mycom></mycom>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
/*
//創(chuàng)建組件對(duì)象
var com= Vue.extend({
template:'<h3>這里是組件在內(nèi)容</h3>'
});
//注冊(cè)組件
//參數(shù)1是組件的名稱,使用組件的時(shí)候要使用這個(gè)名稱
//參數(shù)2是組件的對(duì)象
Vue.component('mycom',com);
*/
Vue.component('mycom',Vue.extend({
template:'<h3>也行</h3>'
}))
new Vue({
el:"#app",
data:{
}
});
</script>
</body>
</html>
//法二
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<my-com></my-com>
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
//組件的名稱可以是駝峰法命名,但是在使用的時(shí)候要替換成以中劃線分隔的形式
Vue.component('my-com',{
template:'<h3>這里是組件模板</h3>'
});
new Vue({
el:"#app",
data:{
}
});
</script>
</body>
</html>
//法三
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<mycom></mycom>
</div>
<!-- //需注意模板必須是放置在掛載節(jié)點(diǎn)之外。 -->
<!-- 使用id作為組件的標(biāo)識(shí) -->
<!-- 組件的模板只允許具有一個(gè)根節(jié)點(diǎn) -->
<template id="tl">
<div>
<h3>這里是組件</h3>
<div>lalalal</div>
</div>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
Vue.component('mycom',{
template: '#tl'
})
new Vue({
el:"#app",
data:{
}
});
</script>
</body>
</html>
//法四
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<mycom></mycom>
</div>
<!-- 每一個(gè)組件都是一個(gè)VUE的實(shí)例 -->
<script id="el" type="x-template">
<div>這里是組件內(nèi)容</div>
</script>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
Vue.component('mycom',{
template:"#el",
//組件的數(shù)據(jù)必須是一個(gè)函授,而且這個(gè)函數(shù)必須返回的是一個(gè)對(duì)象,而且這個(gè)對(duì)象必須是內(nèi)置定義的對(duì)象
data:function(){
return {};
}
})
new Vue({
el:"#app",
data:{
}
});
</script>
</body>
</html>
案例:組件計(jì)算器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<mycom></mycom>
<mycom></mycom>
<mycom></mycom>
<mycom></mycom>
<mycom></mycom>
</div>
<div id="dapp">
<mycom></mycom>
</div>
<template id="el">
<div>
<button @click="add">+1</button>
{{count}}
</div>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
Vue.component('mycom',{
template:'#el',
data:function(){
//每一次返回的是一個(gè)新的對(duì)象,不同的組件之間是不會(huì)相互影響的
return {
count:0
};
},
methods:{
add(){
this.count++;
}
}
})
new Vue({
el:"#app",
data:{
}
});
new Vue({
el:'#dapp'
})
</script>
</body>
</html>
十九、私有組件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<mycom></mycom>
</div>
<div id="dapp">
<mycom></mycom>
</div>
<template id="cc">
<div>
這里是私有組件
</div>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
},
components:{
mycom:{
template:"#cc"
}
}
});
new Vue({
el:"#dapp"
})
</script>
</body>
</html>
二十、組件切換
//法一:v-if
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
<a href="" @click.prevent="flag=true">登錄</a>
<a href="" @click.prevent="flag=false">注冊(cè)</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
<template id="login">
<div><h3>這里是登錄組件</h3></div>
</template>
<template id="register">
<div>
<h3>這里是注冊(cè)組件</h3>
</div>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
flag:false
},
components:{
login:{
template:"#login"
},
register:{
template:"#register"
}
}
});
</script>
</body>
</html>
//法二:components
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
h3{
width:80%;
height:300px;
background: lightgreen;
margin:80px auto;
}
.my-animate-enter,
.my-animate-leave-to{
opacity: 0;
transform: translateX(50px);
}
.my-animate-enter-active,
.my-animate-leave-active{
transition: all 1s ease;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<a href="" @click.prevent="com='login'">登錄</a>
<a href="" @click.prevent="com='register'">注冊(cè)</a>
<transition name="my-animate" mode="out-in">
<component :is="com"></component>
</transition>
<!-- component 組件切換-->
<!-- trasnition 過(guò)度動(dòng)畫(huà)-->
<!-- transition-group 列表的過(guò)度動(dòng)畫(huà)-->
<!-- template 組件的模板-->
</div>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
com:'login'
},
components:{
login:{
template:'<h3>這是登錄組件</h3>'
},
register:{
template:'<h3>這是注冊(cè)組件</h3>'
}
}
});
</script>
</body>
</html>
二十一、組件傳值
//父組件向子組件傳值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
父組件向子組件傳值,使用數(shù)據(jù)綁定的方式傳遞。:后面的值必須在組建中使用pros接收。否則在子組件中沒(méi)有辦法獲取到父組件通過(guò)這種方式傳過(guò)來(lái)的值
<mycom :pmsg="parentmsg" ></mycom>
</div>
<template id="el">
<div>
<h2>這里是我創(chuàng)建的組件:{{msg}}-{{pmsg}}</h2>
</div>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
parentmsg:'古道西風(fēng)瘦馬'
},
components:{
mycom:{
template:'#el',
data(){
return {
msg:'風(fēng)吹草低見(jiàn)牛羊',
}
},
methods:{
},
//這里使用pros接受的數(shù)據(jù)的名稱與組件傳遞的時(shí)候綁定的名稱是一模一樣的
props:['pmsg']
}
},
});
</script>
</body>
</html>
//父組件向子組件傳遞方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
{{conso('不怕熱')}}
對(duì)于方法來(lái)說(shuō),傳遞到子組件要是用事件綁定的形式
<mycom v-on:func="conso"></mycom>
</div>
<template id="el">
<button @click="tirrger">點(diǎn)擊觸發(fā)父組件的conso方法</button>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
},
methods:{
conso(i){
console.log('30度的日子就要來(lái)臨了---'+i)
}
},
components:{
mycom:{
template:'#el',
data:function(){
return {};
},
props:[],
methods:{
tirrger(){
//對(duì)于父組件傳遞的方法而言,其實(shí)并不是將這個(gè)方法傳遞給子組件,而是要求子組件將這個(gè)方法進(jìn)行觸發(fā).
//$emit 函數(shù)觸發(fā)的函數(shù)如果是需要傳遞參數(shù),那么按照參數(shù)的順序從第二個(gè)參數(shù)開(kāi)始進(jìn)行傳遞
this.$emit('func','不怕辣');
}
}
}
}
});
</script>
</body>
</html>
//子組件向父組件傳遞方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app" v-cloak>
{{conso('不怕熱')}}
對(duì)于方法來(lái)說(shuō),傳遞到子組件要是用事件綁定的形式
<mycom v-on:func="conso"></mycom>
</div>
<template id="el">
<button @click="tirrger">點(diǎn)擊觸發(fā)父組件的conso方法</button>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
msg:''
},
methods:{
conso(i){
this.msg = i;
}
},
components:{
mycom:{
template:'#el',
data:function(){
return {
msg:'僵小魚(yú)'
};
},
props:[],
methods:{
tirrger(){
//對(duì)于父組件傳遞的方法而言,其實(shí)并不是將這個(gè)方法傳遞給子組件,而是要求子組件將這個(gè)方法進(jìn)行觸發(fā).
//$emit 函數(shù)觸發(fā)的函數(shù)如果是需要傳遞參數(shù),那么按照參數(shù)的順序從第二個(gè)參數(shù)開(kāi)始進(jìn)行傳遞
this.$emit('func',this.msg);
}
}
}
}
});
</script>
</body>
</html>
案例:列表評(píng)論
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet">
</head>
<body>
<div id="app" v-cloak>
<discuss @func="flash"></discuss>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">{{item.name}}</span>
{{item.content}}
</li>
</ul>
</div>
<template id="el">
<form action="">
<div class="form-group">
<label for="author">作者</label>
<input type="text" class="form-control" id="author" v-model:value="author">
</div>
<div class="form-group">
<label for="content">內(nèi)容</label>
<textarea id="content" class="form-control" v-model:value="content"></textarea>
</div>
<div class="form-group">
<input type="button" class="form-control btn-primary" value="發(fā)表" @click="add">
</div>
</form>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
list:[]
},
methods:{
flash(){
this.list = JSON.parse(localStorage.getItem('discuss-list') || '[]');
}
},
components:{
discuss:{
template:'#el',
data(){
return {
author:'',
content:''
};
},
methods:{
add(){
let list = JSON.parse(localStorage.getItem('discuss-list') || '[]');
list.push({id:Math.random(100),name:this.author,content:this.content});
localStorage.setItem('discuss-list',JSON.stringify(list));
this.author=this.content = '';
this.$emit('func');
}
}
}
},
created:function(){
this.flash();
}
});
</script>
</body>
</html>
二十二、插槽
<!DOCTYPE html>
<html lang="zh">
<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></title>
</head>
<body>
<div id="app" v-cloak>
<com>
<!-- 插槽機(jī)制也能夠幫助我們實(shí)現(xiàn)數(shù)據(jù)的傳遞,只是這種傳遞是停留在視圖層的,并沒(méi)有進(jìn)入到代碼層 -->
here is the best place!---{{pm}}
</com>
</div>
<template id="el">
<div>
<h1>這里是組件</h1>
{{msg}}
<slot></slot>
</div>
</template>
<script src="../day1/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
pm:'my name is pm'
},
components:{
com:{
template:"#el",
data(){
return {
msg:"這是組件數(shù)據(jù)"
};
}
}
}
});
</script>
</body>
</html>
二十三、路由
參考文獻(xiàn):https://router.vuejs.org/zh/
什么是路由?
- 我們認(rèn)識(shí)的路由
進(jìn)入到網(wǎng)站的根目錄,然后根據(jù)文件夾的名稱或者文件名去找到對(duì)應(yīng)的文件,然后運(yùn)行
- 后端的路由
指網(wǎng)絡(luò)上的某一個(gè)資源URL
后端框架的出現(xiàn),以及安全性的考慮,后端一般做單一的入口
例如:http://localhost/vue_api/index.php?m=api&a=getlist
單一的入口是指在這個(gè)入口文件中,通過(guò)路由參數(shù)的方式(m=api&a=getlist)將請(qǐng)求分發(fā)給不同的資源或者文件處理
- 前端路由
錨點(diǎn)實(shí)現(xiàn)的路由
前端的路由是不會(huì)發(fā)生頁(yè)面的刷新或者頁(yè)面的重啟請(qǐng)求的
hash值的變化是不會(huì)造成頁(yè)面重新請(qǐng)求的
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
/* mint-active */
.router-link-active{
background: #00FFFF;
color:lightseagreen;
font-size: 20px;
}
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(200px);
}
.v-enter-active,
.v-leave-active{
transition: all 1s ease;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<!-- 使用router-link的標(biāo)簽實(shí)現(xiàn)路由的連接 -->
<router-link to="/login" tag="span">登錄</router-link>
<router-link to="/register" tag="span">注冊(cè)</router-link>
<!-- <router-link to="/guanggai" tag="span">逛街</router-link> -->
<!-- <a href="#/login">登錄</a>
<a href="#/register">注冊(cè)</a> -->
<transition mode="out-in">
<router-view></router-view>
</transition>
</div>
<script src="../lib/vue.js"></script>
<script src="../lib/vue-router.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
const login = {
template:`
<div>
這是登錄組件
</div>
`,
};
const register = {
template:`
<div>
這是注冊(cè)組件
</div>
`,
}
new Vue({
el:"#app",
data:{
},
//不能這樣使用
<!--components:{
guanggai:{
template:'<div>這是逛街</div>'
}
},-->
//路由規(guī)則
router: new VueRouter({
routes:[
//redirect重定向,將符合規(guī)則的路由發(fā)送到指定的路由
{path:'/',redirect:'/login'},
{path:'/login',component:login},
{path:'/register',component:register},
// {path:'/guanggai',component:guanggai}
],
linkActiveClass:'is_selected'
})
});
</script>
</body>
</html>
二十四、vuex
參考文獻(xiàn):https://vuex.vuejs.org/zh/
概念:在多個(gè)組件中共享狀態(tài)(需要多個(gè)組件共享的變量全部存儲(chǔ)在一個(gè)對(duì)象里面,然后將這個(gè)對(duì)象放在頂層的Vue實(shí)例中,讓其他組件可以使用,并且是響應(yīng)式)
適用情況:用戶登陸狀態(tài)、用戶名稱、頭像、地理位置,商品收藏、購(gòu)物車中的物品等等