本文的意義在于總結(jié)一些因為版本的更迭導致比較常見的地方引起錯誤锋勺,具體說明可以參考vue官網(wǎng)
目錄
1沙庐、組件模板寫法
2、組件定義
3咸这、生命周期
4夷恍、重復數(shù)據(jù)循環(huán)
5、自定義鍵盤指令
6媳维、filter過濾器
7酿雪、組件通信
8、動畫
9侄刽、vue-router
1执虹、組件模板寫法變更
vue2.0不在支持片段代碼,例如以下
//下邊的組件寫法在vue1.0可以正常執(zhí)行唠梨,但vue2.0會給出警告袋励,必須給他一個根節(jié)點,也就是唯一父級
//[Vue warn]: Component template should contain exactly one root element:
<script>
Vue.component('my-aaa',{
template:'<h3>我是組件</h3><strong>我是加粗標簽</strong>'
});
</script>
//推薦此種方式寫組件当叭,必須有根元素茬故,包裹住所有的代碼
<script>
Vue.component('my-aaa',{
template:'#aaa'
});
</script>
<body>
<template id="aaa">
<div>
<h3>我是組件</h3>
<strong>我是加粗標簽</strong>
</div>
</template>
</body>
2、組件定義
//使用組件必須注冊
//[Vue warn]: Unknown custom element: <my-aaa> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
<script>
var Home={ //這是2.0組件
template:'#aaa'
}; //Vue.extend()
Vue.component('my-aaa',Home); //注冊方式1
</script>
<body>
<template id="aaa">
<div>
<h3>我是組件</h3>
<strong>我是加粗標簽</strong>
</div>
</template>
<div id="box">
<my-aaa></my-aaa>
</div>
</body>
//第二種方式
<script>
var Home={ //這是2.0組件
template:'#aaa'
}; //Vue.extend()
window.onload=function(){
new Vue({
el:'#box',
components:{ //注冊方式2
'aaa':Home
}
});
};
</script>
<body>
<template id="aaa">
<div>
<h3>我是組件</h3>
<strong>我是加粗標簽</strong>
</div>
</template>
<div id="box">
<my-aaa></my-aaa>
</div>
</body>
3蚁鳖、生命周期
vue1.0生命周期:
init
created
beforeCompile
compiled
ready √ -> mounted
beforeDestroy
destroyed
vue2.0生命周期:
beforeCreate 組件實例剛剛被創(chuàng)建,屬性都沒有
created 實例已經(jīng)創(chuàng)建完成磺芭,屬性已經(jīng)綁定
beforeMount 模板編譯之前
mounted 模板編譯之后,代替之前ready *
beforeUpdate 組件更新之前
updated 組件更新完畢 *
beforeDestroy 組件銷毀前
destroyed 組件銷毀后
<script>
new Vue({
el:'#box',
beforeCreate(){
console.log('組件實例剛剛被創(chuàng)建');
},
created(){
console.log('實例已經(jīng)創(chuàng)建完成');
},
beforeMount(){
console.log('模板編譯之前');
},
mounted(){
console.log('模板編譯完成');
},
beforeUpdate(){
console.log('組件更新之前');
},
updated(){
console.log('組件更新完畢');
},
beforeDestroy(){
console.log('組件銷毀之前');
},
destroyed(){
console.log('組件銷毀之后');
}
});
</script>
4醉箕、重復數(shù)據(jù)循環(huán)
//[Vue warn]: Duplicate value found in v-for="val in list": "background". Use track-by="$index" if you are expecting duplicate values.
//vue1.0循環(huán)重復數(shù)據(jù)會受限制钾腺,vue2.0正常
<script>
window.onload=function(){
new Vue({
el:'#box',
data:{
list:['width','height','border']
},
methods:{
add(){
this.list.push('background');
}
}
});
};
</script>
<div id="box">
<input type="button" value="添加" @click="add">
<ul>
<li v-for="val in list"> //vue1.0循環(huán)需要添加 track-by="$index"
{{val}}
</li>
//[Vue warn]: Property or method "$key" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
<li v-for="val in list">
{{$index}} {{$key}} //vue2.0去掉了隱式一些變量 $index $key
</li>
<li v-for="(index,val) in list"> //vue1.0循環(huán)寫法v-for="(index,val) in array"
{{val}} {{index}}
</li>
<li v-for="(val,index) in list"> //vue2.0循環(huán)寫法 v-for="(index,val) in array"
{{val}} {{index}} // 傾向于js原生forEach徙垫,先寫val再寫index
</li>
</ul>
</div>
//提高循環(huán)性能 track-by="id" 變成 :key="index"
<script>
window.onload=function(){
new Vue({
el:'#box',
data:{
list:{
a:'apple',
b:'banana',
c:'cell'
}
}
});
};
</script>
<div id="box">
<ul>
<li v-for="(val,key) in list" :key="index">
{{val}} {{key}}
</li>
</ul>
</div>
5、自定義鍵盤指令
<script>
window.onload=function(){
new Vue({
el:'#box',
data:{
},
methods:{
change(){
alert('改變了');
}
}
});
//Vue.directive('on').keyCodes.ctrl=17; //vue1.0寫法
Vue.config.keyCodes.ctrl=17; //vue2.0寫法
};
</script>
<div id="box">
<input type="text" @keyup.ctrl="change">
</div>
6放棒、filter過濾器
vue1.0系統(tǒng)就自帶很多過濾姻报,例如currency/json等等。到了vue2.0间螟,作者刪除全部內(nèi)置過濾器吴旋,保留了自定義過濾器,但自定義過濾器傳參格式有點區(qū)別厢破。
<script>
Vue.filter('toDou',function(n,a,b){
alert(a+','+b);
return n<10?'0'+n:''+n;
});
window.onload=function(){
new Vue({
el:'#box',
data:{
msg:9
}
});
};
</script>
<div id="box">
{{msg | toDou '12' '5'}} //vue1.0寫法
{{msg | toDou('12','5')}} //vue2.0寫法
</div>
7荣瑟、組件通信
子級獲取父級的數(shù)據(jù),通過props
//vue1.0寫法摩泪,子組件可以更改父組件信息笆焰,可以是同步sync
<script>
window.onload=function(){
new Vue({
el:'#box',
data:{
a:'我是父組件數(shù)據(jù)'
},
components:{
'child-com':{
props:['msg'],
template:'#child',
methods:{
change(){
this.msg='被更改了'
}
}
}
}
});
};
</script>
<template id="child">
<div>
<span>我是子組件</span>
<input type="button" value="按鈕" @click="change">
<strong>{{msg}}</strong>
</div>
</template>
<div id="box">
父級: ->{{a}}
<br>
<child-com :msg.sync="a"></child-com> //需要同步更改父級需要加上.sync
</div>
//[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "msg"
//vue2.0寫法跟vue1.0有點區(qū)別,不然會報以上警告见坑。 不允許直接給父級的數(shù)據(jù)仙辟,做賦值操作
//處理方式 a). 父組件每次傳一個對象給子組件, 對象之間引用,推薦 b). 只是不報錯, mounted中轉(zhuǎn)
//方式a
<script>
window.onload=function(){
new Vue({
el:'#box',
data:{
giveData:{
a:'我是父組件數(shù)據(jù)'
}
},
components:{
'child-com':{
props:['msg'],
template:'#child',
methods:{
change(){
this.msg.a='被改了';
}
}
}
}
});
};
</script>
<template id="child">
<div>
<span>我是子組件</span>
<input type="button" value="按鈕" @click="change">
<strong>{{msg.a}}</strong>
</div>
</template>
<div id="box">
父級: ->{{giveData.a}}
<br>
<child-com :msg="giveData"></child-com>
</div>
//方式b
<script>
window.onload=function(){
new Vue({
el:'#box',
data:{
a:'我是父組件數(shù)據(jù)'
},
components:{
'child-com':{
data(){
return {
b:''
}
},
props:['msg'],
template:'#child',
mounted(){
this.b=this.msg;
},
methods:{
change(){
this.b='被改了';
}
}
}
}
});
};
</script>
<template id="child">
<div>
<span>我是子組件</span>
<input type="button" value="按鈕" @click="change">
<strong>{鳄梅}</strong>
</div>
</template>
<div id="box">
父級: ->{{a}}
<br>
<child-com :msg.sync="a"></child-com>
</div>
//注意如果是父子級可以通過以上方式處理叠国。如果是同級組件之間想傳遞數(shù)據(jù),也就是單一事件管理戴尸,通過vm.$emit()傳遞粟焊,vm.$on()接收。類似vuex實現(xiàn)原理孙蒙。
格式參考:
var Event=new Vue();
Event.$emit(事件名稱, 數(shù)據(jù))
Event.$on(事件名稱,function(data){
//data
}.bind(this));
//具體實現(xiàn)
<script>
//準備一個空的實例對象
var Event=new Vue();
var A={
template:`
<div>
<span>我是A組件</span> -> {{a}}
<input type="button" value="把A數(shù)據(jù)給C" @click="send">
</div>
`,
methods:{
send(){
Event.$emit('a-msg',this.a);
}
},
data(){
return {
a:'我是a數(shù)據(jù)'
}
}
};
var B={
template:`
<div>
<span>我是B組件</span> -> {{a}}
<input type="button" value="把B數(shù)據(jù)給C">
</div>
`,
data(){
return {
a:'我是b數(shù)據(jù)'
}
}
};
var C={
template:`
<div>
<h3>我是C組件</h3>
<span>接收過來的A的數(shù)據(jù)為: {{a}}</span>
</div>
`,
data(){
return {
a:'',
b:''
}
},
mounted(){
//var _this=this;
Event.$on('a-msg',function(a){
this.a=a;
}.bind(this));
}
};
window.onload=function(){
new Vue({
el:'#box',
components:{
'com-a':A,
'com-b':B,
'com-c':C
}
});
};
</script>
<div id="box">
<com-a></com-a>
<com-b></com-b>
<com-c></com-c>
</div>
8项棠、動畫
動畫如果有結(jié)合animate,相關配置參數(shù)和效果查看可以參考animate官網(wǎng)
vue1.0寫法,transition是屬性
<p transition="fade"></p>
處理好fade相關樣式就可以實現(xiàn)動畫效果
.fade-transition{}
.fade-enter{}
.fade-leave{}
vue2.0寫法挎峦,transition變成了組件香追,需要把要做動畫的包起來,一般是包router-view
<transition name="fade">
運動東西(元素坦胶,屬性透典、路由....)
</transition>
class定義:
.fade-enter-active,.fade-leave-active{transition:1s all ease;}
.fade-enter{} //初始狀態(tài)
.fade-enter-active{} //變化成什么樣 -> 當元素出來(顯示)
.fade-leave{}
.fade-leave-active{} //變成成什么樣 -> 當元素離開(消失)
動畫可以配合animate.css使用,把fade和name去掉顿苇。給transition加enter-active-class="zoomInleft" leave-active-class="zoomOutRight",給運動的元素本身加class="animated"峭咒。
<transition enter-active-class="animated zoomInLeft" leave-active-class="animated zoomOutRight">
<p v-show="show"></p>
</transition>
多個元素運動需要使用transition-group,并且把每個運動元素加個:key="index":
<transition-group enter-active-class="" leave-active-class="">
<p :key=""></p>
<p :key=""></p>
</transition-group>
9纪岁、vue-router
vue1.0寫法:
<a v-link="{path:'/home'}">我是主頁</a>
router.rediect //重定向 2.0廢棄了
subRoutes //路由嵌套用subRoutes凑队,配置跟父級一樣是json
vue2.0寫法:
<router-link to="/home">我是主頁</router-link> 它會自動解析成a v-link形式
const routes = [ //配置路由
{path:'/home',component:Home},
{path:'*',redirect:'/home'} //重定向
...一個個json
];
children //路由嵌套用children幔翰,配置跟父級一樣是json
路由實例方法:
router.push({path:'home'}); //直接添加一個路由,表現(xiàn)切換路由漩氨,本質(zhì)往歷史記錄里面添加一個
router.replace({path:'news'}) //替換路由西壮,不會往歷史記錄里面添加
帶有參數(shù)的路由配置
<ul>
<li><router-link to="/user/strive/age/10">Strive</router-link></li>
<li><router-link to="/user/blue/age/80">Blue</router-link></li>
<li><router-link to="/user/eric/age/70">Eric</router-link></li>
</ul>
//配置路由
const routes=[
{path:'/home', component:Home},
{
path:'/user',
component:User,
children:[
{path:':username/age/:age', component:UserDetail}
]
},
{path:'*', redirect:'/home'} //找不到的頁面全部重定向到home,相當于404
];