vue组件和过渡操作
Vue
一、组件
1、组件的嵌套
*1、全局组件的嵌套
<div id="box">
<v-head></v-head>
</div>
<template id='head'>
<div>
<h1> 组件111 </h1>
<v-foot></v-foot>
</div>
</template>
<template id='foot'>
<h1>组件222</h1>
</template>
//注册
Vue.component('v-head',Vue.extend({
template:'#head',
}))
Vue.component('v-foot',Vue.extend({
template:'#foot',
}))
*2、私有组件的嵌套
用法同上
//注册
components:{
'v-aa':{
template:'#aa',
components:{
'v-bb':{
template:'#bb'
}
}
}
}
//私有组件的嵌套必须包含在嵌套的组件内,
组件的作用域是独立的,对象的属性是私有的;
2、组件间的传值
*1、父组件的数据传给子组件
父传子:在子组件标签上绑定自定义属性式指令,值为父组件传递的数据,子组件内部通过props接收属性名;
父组件--子组件传值Template 标签内 给子组件设置属性
<v-nav :msg=“msg” :n=“name”></v-nav>
在子组件的components设置 props:[‘msg’,‘n’], /子组件接收数据 /
子组件的template内通过{{}}直接绑定数据即可
<div id="box">
<v-father></v-father>
</div>
————————————————————————————————————————————————————————————————————————————————————————
<template id='father'>
<div>
<h1>父组件————{{str1}}</h1>
<button @click="tap()">传值给子组件</button>
<hr />
<v-child :name='str'></v-child>
</div>
</template>
<template id='child'>
<div>
<h1>子组件</h1>
<h2>接收父的数据————{{name}}</h2>
</div>
</template>
——————————————————————————————————————————————————————————————————————————————————————
var vm = new Vue({
el:'#box',
data:{
info:"hello"
},
methods:{
},
components:{
'v-father':{
template:'#father',
data:function(){
return{
str1:"hhhhhhhfather",
str:''
}
},
methods:{
tap(){
this.str=this.str1;
}
},
components:{
'v-child':{
template:"#child",
props:['name'],
data:function(){
return{
str:''
}
},
methods:{
}
}
}
}
}
})
*2、子组件的数据传给父组件
子传父:在子组件标签上绑定自定义事件,子组件内部通过$emit进行事件数据推送,父组件内部通过事件调用函数的参数接收数据。
、子组件---父组件传值 $emit
<div id="box">
<v-father></v-father>
</div>
——————————————————————————————————————————————————————————————————————————————————————————
<template id='father'>
<div>
<h1>父组件</h1>
<h2>zi组件的数据————{{str1}}</h2>
<hr />
<v-child @toparent="getdata"></v-child> //自定义的事件,调用不要加()
</div>
</template>
<template id='child'>
<div>
<h1>子组件————{{str}}</h1>
<button @click="tap()">传值</button>
</div>
</template>
—————————————————————————————————————————————————————————————————————————————————————————
var vm = new Vue({
el:'#box',
data:{
info:"hello"
},
components:{
'v-father':{
template:'#father',
data:function(){
return{
str1:""
}
},
methods:{
getdata(msg){
console.log(msg);
this.str1=msg;
},
},
components:{
'v-child':{
template:"#child",
data:function(){
return{
str:'hhhhhhhchild'
}
},
methods:{
tap(){
this.$emit('toparent',this.str)
},
}
}
}
}
}
})
*3、平行组件传值
<div id="box">
<v-a></v-a>
<v-b></v-b>
<v-c></v-c>
</div>
————————————————————————————————————————————————————————————————————————————————————
<template id='a'>
<div>
<h1>AAA组件————{{str}}</h1>
<button @click="send()">传值给CCC组件</button>
</div>
</template>
<template id='b'>
<div>
<h1>BBB组件————{{str}}</h1>
<button @click="send()">传值给CCC组件</button>
</div>
</template>
<template id='c'>
<div>
<h1>CCC组件</h1>
<h2>接收AAA的数据————{{stra}}</h2>
<h2>接收BBB的数据————{{strb}}</h2>
</div>
</template>
————————————————————————————————————————————————————————————————————————————————————
var vm1 = new Vue({})
var vm = new Vue({
el:'#box',
data:{
info:"hello"
},
components:{
'v-a':{
template:'#a',
data:function(){
return{
str:"这是AAA的数据"
}
},
methods:{
send(){
vm1.$emit('isa',this.str)
}
}
},
'v-b':{
template:'#b',
data:function(){
return{
str:"这是BBB的数据"
}
},
methods:{
send(){
vm1.$emit('isb',this.str)
}
}
},
'v-c':{
template:'#c',
data:function(){
return{
stra:'',
strb:''
}
},
mounted(){
var _this=this;
vm1.$on('isa',function(data){
_this.stra=data;
});
vm1.$on('isb',function(data){
_this.strb=data;
})
}
}
}
})
3、父子组件的操作
1、操作dom
<h1 ref="tit">hello</h1>
this.$refs.tit.innerHTML
2、父子组件操作
父组件操作子组件---$refs
$parent 子组件直接操作父组件
<div id="box">
<v-p></v-p>
</div>
————————————————————————————————————————————————————————————————————————
<template id='par'>
<div>
<h1>父组件———{{str}}</h1>
<button @click="tap()">操作子组件</button>
<hr>
<v-c ref="child"></v-c>
</div>
</template>
<template id='chd'>
<div>
<h1>子组件———{{str}}</h1>
<button @click="tap()">操作父组件</button>
</div>
</template>
——————————————————————————————————————————————————————————————————————————————————————
var vm = new Vue({
el:'#box',
data:{
info:"hello"
},
components:{
'v-p':{
template:'#par',
data:function(){
return{
str:"this is Parente",
}
},
methods:{
tap(){
console.log(this.$refs.child.str)
}
},
components:{
'v-c':{
template:'#chd',
data:function(){
return{
str:"this is child"
}
},
methods:{
tap(){
console.log(this.$parent.str)
}
}
}
}
}
}
})
3、nextTick
this.$nextTick(function(){ }) 保证挂载完成后,拿到最新的数据
<div id="box">
<h1 ref="tit">{{info}}</h1>
</div>
________________________________________________
var vm = new Vue({
el:'#box',
data:{
info:"hello"
},
mounted(){
this.info="hihihi";
this.$nextTick(function(){
console.log(this.$refs.tit.innerHTML)
})
}
})
4、Slot
使用slot发布内容、Slot标签添加 属性
<slot name="ul-slot">
内容可通过 slot属性值查找
是否显示默认
<ul slot="ul-slot">
<div id="box">
<v-con>
<p slot='bb'>h哈哈哈</p>
</v-con>
</div>
<template id='aa'>
<div>
<slot name="aa">占个位</slot>
<p>hahahahha</p>
<slot name="bb">再占个位</slot>
</div>
</template>
————————————————————————————————————————————————————————————————
var vm = new Vue({
el:'#box',
data:{
info:"hello"
},
components:{
'v-con':{
template:'#aa'
}
}
})
4、Toast提示框
<div id="box">
<button @click="tap()">toast提示框</button>
</div>
————————————————————————————————————————————————————————————————————
var Toast =Vue.component('Toast',{
template:`
<div class='toast' v-if="isshow">
{{text}}
</div>
`,
data:function(){
return{
text:'登录成功!',
isshow:true,
time:2000
}
}
})
var toast=function(){
let vueToast =new Toast({
el:document.createElement('div'),
})
document.body.appendChild(vueToast.$el);
setTimeout(function(){
vueToast.isshow=false;
},vueToast.time)
}
var vm = new Vue({
el:'#box',
methods:{
tap(){
toast()
}
}
})
二、过渡
css3中实现动画效果的两种方式;
transition过渡:需要事件触发;改变的运动形态只有两组关键帧(开始、结束);
animation动画:不需要事件触发;改变的运动形态可以设置多组关键帧 ;
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:
- 在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
1、单元素的过渡——transition封装组件
Vue 提供了 transition
的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡 。
<transition name="fade">
<p v-if="isshow">Lorem ullam dolores veniam!</p>
</transition>
通过给需要过渡的元素加transition封装组件,并添加 name 属性来通过样式控制;
过渡的类名:(假设 name = " fade")
1、fade-enter
定义进入过渡的开始状态;元素进入之前生效。开始进入
2、fade-enter-active
定义进入过渡生效时的状态。在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。进入过程中
3、fade-enter-to
进入过渡的结束状态 ;即进入完成;
4、fade-leave
离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。开始离开
5、fade-leave-active
离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。 离开过程中
6、fade-leave-to
定义离开过渡的结束状态 ;离开结束
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-active {
opacity: 0
}
在css样式中控制过渡中每个过程的动画效果
2、CSS------animation动画实现过渡
CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter
类名在节点插入 DOM 后不会立即删除,而是在 animationend
事件触发时删除。
用法相同,使用name=“bounce”
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
3、与swiper——animate结合使用:自定义过渡的类名
链接swiper的 Animate.css 文件
<transition
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
>
<p v-if="isshow">Lorem , ullam dolores veniam!</p>
</transition>
在transition里加属性,属性值为animated 和动画效果的名称;
4、transition-group
当前有多个元素都需要获得过渡效果是用transition-group,当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。
<transition-group
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
>
<p v-if="isshow" key="1">Lorem, ullam dolores veniam!</p>
<p v-if="isshow" key="2">Lorem, ullam dolores veniam!</p>
</transition-group>
5、过渡相关的事件
<transition-group
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
@before-enter="beforeEnter()" 进入之前
@enter="enter($event)" 进入过程中
@after-enter="afterEnter" 进入完成
@before-leave="beforeLeave()" 离开之前
@leave="leave()" 离开中
@after-leave="afterLeave()" 离开完毕
>
<p v-if="isshow" key="1">Lorem veniam!</p>
</transition-group>
————————————————————————————————————————————
methods:{
beforeEnter(){
console.log(1)
},
enter(e){
e.style.color="yellow";
console.log(2)
},
afterEnter(e){
e.style.color="violet";
console.log(3)
},
beforeLeave(){
console.log(4)
},
leave(){
console.log(5)
},
afterLeave(){
console.log(6)
}
}
函数可通过e.style来设置样式
5、多个组件进行过渡---动态注册组件
<div id="box">
<button @click="view='v-a'">AAA组件</button>
<button @click="view='v-b'">BBB组件</button>
<transition
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
>
<component :is='view'></component>
</transition>
</div>
<template id='a'>
<div>
<h1>AAA组件</h1>
<p>Lorem dam.</p>
</div>
</template>
<template id='b'>
<div>
<h1>BBB组件</h1>
<ul>
<li>bbb</li>
<li>bbb</li>
</ul>
</div>
</template>
_____________________________________________________________
var vm =new Vue({
el:"#box",
data:{
view:'v-a'
},
components:{
'v-a':{
template:'#a'
},
'v-b':{
template:'#b'
}
}
})