Vue学习记录(二)
过渡动画
1.通过transition双标签嵌套想要执行动画的部分
2.通过v-enter(进入前),v-enter-to(进入后),v-enter-active(进入过程)和
v-leave(离开前),v-leave-to(离开后),v-leave-active(离开过程)的类名方式在css中添加样式,就可以实现动态的动画
实操代码:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
.pic {
width: 300px;
height: 300px;
background-color: red;
}
.v-enter {
opacity: 0;
}
.v-enter-to {
opacity: 1;
}
.v-enter-active {
transition: all 3s;
}
.v-leave {
opacity: 1;
}
.v-leave-to {
opacity: 0;
}
.v-leave-active {
transition: all 3s;
}
</style>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="demo">
<button type="button" @click="toggle">
演示
</button>
<transition>
<div id="" class="pic" v-show="isShow">
</div>
</transition>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app = new Vue({
el: "#demo",
data: {
isShow: false
},
methods: {
toggle() {
this.isShow = !this.isShow;
}
},
directives: {
}
})
</script>
</body>
</html>
过渡动画注意点:
1.一对transition标签只能嵌套一个元素的过渡动画,如果想要控制多个元素的动画效果,则需要通过多个transition标签来嵌套
2.如果想要元素进入页面就有过渡动画的效果,则需要给transition标签添加一个appear属性
3.如果想要多个元素执行不同的动画效果,则需要给transition添加一个name属性,再将name的属性值替换前缀v,演示代码如下:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
.pic {
width: 300px;
height: 300px;
background-color: red;
}
.one-enter {
opacity: 0;
}
.one-enter-to {
margin-left: 500px;
opacity: 1;
}
.one-enter-active {
transition: all 3s;
}
.one-leave {
opacity: 1;
}
.one-leave-to {
opacity: 0;
}
.one-leave-active {
transition: all 3s;
}
.two-enter {
opacity: 0;
}
.two-enter-to {
margin-top: 1000px;
opacity: 1;
}
.two-enter-active {
transition: all 3s;
}
.two-leave {
opacity: 1;
}
.two-leave-to {
opacity: 0;
}
.two-leave-active {
transition: all 3s;
}
</style>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="demo">
<button type="button" @click="toggle">
演示
</button>
<transition appear name="one">
<div id="" class="pic" v-show="isShow">
</div>
</transition>
<transition appear name="two">
<div id="" class="pic" v-show="isShow">
</div>
</transition>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app = new Vue({
el: "#demo",
data: {
isShow: false
},
methods: {
toggle() {
this.isShow = !this.isShow;
}
},
directives: {
}
})
</script>
</body>
</html>
自定义类名
enter-from-class //动画执行之前
enter-active-class //动画执行过程
enter-to-class //动画执行之后
leave-from-class //离开动画之前
leave-active-class //离开动画过程
leave-to-class //离开动画动画之后
通过给transition标签绑定以上属性名,属性值自定义类名后,在css中添加样式
animate css动画框架
1.先引用
2.在enter-active-class属性中添加属性值animated 加动画样式名
附上animate.css官网:http://www.animate.net.cn/
transition-group
可以替代transition嵌套多个元素的动画效果
transition-group的属性
1.tag:属性值设置标签,可以将transition中的元素全部嵌套在tag指定的标签之中
Vue组件
定义:将大界面拆分为小界面就是组件化
好处提高代码的复用性
Vue组件化步骤
1.创建组件构造器
2.注册已经创建好的组件
3.使用组件
<body>
<div id="demo">
<!-- 使用组件 -->
<abc></abc>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
//创建一个组件
let Profile = Vue.extend({
template: `
<div>
<h1>这是一个标题</h1>
<p>这是我的第一个组件</p>
</div>`
});
//注册组件
Vue.component("abc", Profile);
var app = new Vue({
el: "#demo",
data: {
},
methods: {
},
directives: {
}
})
</script>
</body>
注意:
1.template中不要使用单引号,否则换行会报错,如果想换行,则使用感叹号旁边的``。
2.template中不能包含多个主元素
Vue组件化简化方式
以上代码可以有简化方式且可以让我们输入html代码时有提示,提升开发效率,如下:
js部分
Vue.component("abc", {
template: "#tem1"
});
html部分:
<div id="demo">
<!-- 使用组件 -->
<abc></abc>
</div>
<template id="tem1">
<div>
<h1>这是一个标题</h1>
<p>这是我的第一个组件</p>
</div>
</template>
Vue组件化(局部组件)
var app = new Vue({
el: "#demo",
data: {
},
methods: {
},
directives: {
},
components:{
"abc": {
template:"#tem1"
}
}
})
组件中的data和methods
注意:
1.组件中的methods所用函数必须是已经被定义好的
2.组件中的data必须是一个函数,在函数中可以使用return返回一个对象,对象中也必须要使用已经被定义好的key(对象中的key,value中的key)
问题:data为什么必须是一个函数
回答:因为如果多次调用组件,如果data是一个对象,里面的数据将会受到多个组件的共用,容易发生数据混乱。而如果是一个函数,则每个组件所对应的data都是独立的,就避免了数据混乱
动态组件
动态组件通过
<component v-bind:is="name"></component>
//name
可以是已注册组件的名字
或一个组件的选项对象
通过动态组件可以保存一些状态(如input中type属性check的选择状态)
html代码
<div id="demo">
<button type="button" @click="toggle">切换</button>
<!-- 使用组件 -->
<!-- <abc1 v-if="isShow"></abc1>
<abc2 v-else></abc2> -->
<keep-alive>
<component v-bind:is="name"></component>
</keep-alive>
</div>
<template id="tem1">
<div>
<h1>这是一个标题</h1>
<p>这是我的第一个组件</p>
<input type="checkbox" name="" id="" value="" />
</div>
</template>
<template id="tem2">
<div>
<h1>这是二个标题</h1>
<p>这是我的第二个组件</p>
</div>
</template>
Vue代码:
Vue.component("abc1", {
template: "#tem1"
});
Vue.component("abc2", {
template: "#tem2"
});
var app = new Vue({
el: "#demo",
data: {
isShow:true,
name:"abc1"
},
methods: {
toggle(){
// this.isShow = !this.isShow;
// console.log(this.name === "abc1");
this.name = this.name === "abc1"? "abc2": "abc1";
}
},
directives: {
},
components:{
}
})
组件动画
使用方法参照过渡动画
注意点:
过渡模式:
in-out:新元素先进行过渡,完成之后当前元素过渡离开。
out-in:当前元素先进行过渡,完成之后新元素过渡进入。
<component v-bind:is="name" mode="in-out"></component>
父子组件
定义:在一个组件中又定义了其他的组件,我们称之为父子组件
基础的父子组件
<body>
<div id="demo">
<father>
<!-- <son></son>并不是定义在这个地方 不然不会报错的同时子组件也不会渲染-->
</father>
</div>
<template id="father">
<div id="">
<p>我是父组件</p>
<son></son><!-- <son></son>定义在此处 -->
</div>
</template>
<template id="son">
<div id="">
<p>我是子组件</p>
</div>
</template>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var app = new Vue({
el: "#demo",
//MVVM中的model
data: {
},
//专门用于存储监听事件中的回调函数
methods: {
},
//计算属性
directives: {
},
//组件
components: {
"father": {
template:"#father",
//注意1:此时下面的components所处位置,这里刚学习时容易出错
components: {
"son":{
template:"#son"
}
}
},
}
})
</script>
</body>
父子组件方法和数据传递
Vue中子组件是不能访问到父组件中的数据的,如果想要访问到父组件中的数据,则需要父子组件传递。
使用步骤:
1.使用中父组件当中的子组件中通过v-bind定义向子组件传递数据
2.在Vue子组件中使用props接收父组件传递过来的一个数据
3.在子组件中使用
具体实操代码如下:
html代码:
<div id="demo">
<father>
</father>
</div>
<template id="father">
<div id="">
<p>我是父组件</p>
<p>{{name}}</p>
<button type="button" @click="say">父组件</button>
<!-- 这里将父组件中的数据和方法传递给子组件 -->
<son :parentname="name" @parentsay="say">
</son>
</div>
</template>
<template id="son">
<div id="">
<!-- 使用子组件中接收到的父组件方法 -->
<button type="button" @click="parentsay">子组件</button>
<p>我是子组件</p>
<!-- 这里接收了父组件传递过来的data -->
<p>{{parentname}}</p>
</div>
</template>
Vue代码:
Vue.component("father", {
template: "#father",
components: {
"son": {
template: "#son",
//这里子组件接收父组件传过来的数据parentname,这里的parentname可以任意命名,自命名然后在子组件中使用
props: ["parentname"],
methods:{
//子组件对父组件传递过来的方法进行一个定义
parentsay(){
this.$emit("parentsay")
}
}
}
},
子组件向父组件中传递数据,只需要在子组件接收方法后加上需要传递的数据,再在父组件方法中接收参数就可以了
Vue.component("father", {
template: "#father",
components: {
"son": {
template: "#son",
//这里子组件接收父组件传过来的数据parentname,这里的parentname可以任意命名,自命名然后在子组件中使用
props: ["parentname"],
methods:{
//子组件对父组件传递过来的方法进行一个定义
parentsay(data){
//$emit方法中第二个参数是给父组件传递的数据
this.$emit("parentsay","传递子组件数据")
}
}
}
},
//组件中的data传递数据只能通过函数reutrn一个对象
data() {
return {
"name": "yxy"
}
},
methods:{
//父组件接收子组件传递过来的数据data
"say"(data){
alert("父组件");
console.log(data)
}
}
})
命名注意点:
1.组件构造时如果使用了驼峰命名(fnSay),则使用的时候就需要使用短横线命名(fn-say)
2.父子组件传递数据的时候,如果用的是驼峰命名,则子组件在接收的时候也需要使用短横线命名
3.父子组件传递方法的时候,是不能使用驼峰式命名的
多级传递
如果想要多级传递,则需要一层一层的往下传递
匿名插槽
如果想在子组件中动态的添加一些标签,则需要在子组件独立部分添加slot标签,此时的slot就属于一个插槽
1.如果在父组件中,没有给子组件动态的添加标签,则插槽中的内容会替换掉子组件中动态添加的数据
2.如果在父组件中,给子组件添加标签和内容了,则插槽中的内容就会被替换
总结,父组件中的子组件添加的标签 > 子组件插槽中的内容
具名插槽
在子组件中的插槽slot中添加一个name属性,属性值再添加给父组件中需要添加的标签元素slot属性中
具名插槽存在的意义,可以有效解决子组件中添加了多个插槽,导致父组件中动态添加的标签产生复制的问题
具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="demo">
<father>
</father>
</div>
<template id="father">
<div id="">
<p>我是父组件</p>
<son>
<div id="" slot="one">
我是父组件中调用的插槽1
</div>
<div id="" slot="one">
我是父组件中调用的插槽11
</div>
<div id="" slot="two">
我是父组件中调用的插槽2
</div>
<div id="" slot="two">
我是父组件中调用的插槽22
</div>
</son>
</div>
</template>
<template id="son">
<div id="">
<slot name="one">我是默认插槽</slot>
<slot name="two">我是默认插槽</slot>
<p>我是子组件</p>
</div>
</template>
</body>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component("father", {
template:"#father",
components:{
"son":{
template:"#son"
}
}
})
var app = new Vue({
el:"#demo",
//MVVM中的model
data:{
},
//专门用于存储监听事件中的回调函数
methods:{
},
//计算属性
directives:{
},
//组件
components:{
}
})
</script>
</html>
v-slot指令(简写#)(具名插槽的改进)
可以给父元素中需要动态创建在子元素中的标签用template标签包裹起来,再给template加上一个v-slot属性,指定需要添加的插槽name属性值,则可以达到和具名插槽一样的效果,
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="demo">
<father></father>
</div>
<template id="father">
<div id="">
<p>我是父组件</p>
<son>
<template #one>
<p>我是添加的v-slot</p>
<p>我是添加的v-slot2</p>
</template>
</son>
</div>
</template>
<template id="son">
<div id="">
<slot name="one">我是默认的插槽</slot>
<p>我是子组件</p>
</div>
</template>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component("father", {
template:"#father",
components:{
"son":{
template:"#son"
}
}
})
var app = new Vue({
el:"#demo",
//MVVM中的model
data:{
},
//专门用于存储监听事件中的回调函数
methods:{
},
//计算属性
directives:{
},
//组件
components:{
}
})
</script>
</body>
</html>
作用域插槽
父组件插槽中能够使用子组件的数据
作用域插槽应用场景:子组件提供数据,父组件决定如何渲染
步骤:
1.先用v-bind指令在子组件中的插槽slot中提取出子组件中的数据
2.在父组件套用子组件中在template中添加属性slot-scope将子组件传递过来的数据接收
3.数据渲染
具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="demo">
<father>
</father>
</div>
<template id="father">
<div id="">
<p>我是父组件</p>
<son>
<!-- 此时的 slot-scope="abc"就是接收子组件插槽中传递过来的数据,并命名为abc-->
<template slot-scope="abc">
<!-- 使用v-for将数组数据渲染出来 -->
<li v-for="(name, value) in abc.names">{{name}}</li>
</template>
</son>
</div>
</template>
<template id="son">
<div id="">
<p>我是子组件</p>
<!-- :names="names"是将子组件中的数据提取出来并命名为names -->
<slot :names="names">我是默认的插槽</slot>
</div>
</template>
</body>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component("father", {
template:"#father",
components:{
"son":{
template:"#son",
data:function(){
return {
names :["zs", "ls", "ww", "zl"]
}
}
}
}
})
var app = new Vue({
el:"#demo",
//MVVM中的model
data:{
},
//专门用于存储监听事件中的回调函数
methods:{
},
//计算属性
directives:{
},
//组件
components:{
}
})
</script>
</html>
slot属性扩充部分(替代slot-scope)
slot属性除了可以替代具名插槽以外,还可以替代slot-scope接收子组件传递过来的数据
替换步骤如下:
将上一板块中slot-scope中的slot-scope属性
<template slot-scope="abc">
<!-- 使用v-for将数组数据渲染出来 -->
<li v-for="(name, value) in abc.names">{{name}}</li>
</template>
替换成
<template #slo="abc">
<!-- 使用v-for将数组数据渲染出来 -->
<li v-for="(name, value) in abc.names">{{name}}</li>
</template>
这里的slo是才插槽中设置的name属性
<slot :names="names" name="slo">我是默认的插槽</slot>
如果没有设置name属性,则默认为#default
注:该篇博客为自己视频学习时记录下的笔记,学习步骤来源于学习视频