【云+社区年度征文】Vue深入dom到组件动画
toc
dom和vue对比
Helloworld
注意:下载官方js开发vue.js引入项目
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello world</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">{{content}}</div>
<script>
// dom
// var dom = document.getElementById('app');
// dom.innerHTML = 'hello world'
// vue
var app = new Vue({
el: '#app',
data:{
content: 'hello world'
}
})
</script>
</body>
</html>
计时器对比
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello world</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">{{content}}</div>
<script>
// dom
// var dom = document.getElementById('app');
// dom.innerHTML = 'hello world'
// setTimeout(function() {
// dom.innerHTML = 'bye world'
// }, 2000)
// vue
var app = new Vue({
el: '#app',
data:{
content: 'hello world'
}
})
setTimeout(function(){
app.$data.content = 'bye world'
}, 2000)
</script>
</body>
</html>
todoList练习
添加任务标记
V-for,方法绑定,双向绑定v-model
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue"/>
<button type="button" v-on:click="handleBtnClick" >添加</button>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: [],
inputValue: ''
},
methods:{
handleBtnClick: function() {
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html>
mvp对比MVVM
mvp,p层处理逻辑,关注dom操作 比如jq案例2-4
MV,VM是Vue提供,关注model操作(es5:obj.properties(对象性能、内容)+虚拟dom)
代码量提升30-60%
组件化-todoList
一个页面拆分层多个便于单独管理的组件
todoList中拆分li标签组件化
全局组件Vue.component、局部组件var TodoItem = {、组件传值接收父值v-bind:content="item" props:'content',
简写 点击事件@click=“” 等价 v-on:click=""
简写 传递变量:xxx 等价 v-bind:xxx=""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue"/>
<button type="button" v-on:click="handleBtnClick" >添加</button>
<ul>
<!-- v-bind:xx 简写 :xx 给子组件传入一个绑定 -->
<todo-item :content="item"
:index="index"
v-for="(item, index) in list"
@delete="handleItemDelete"></todo-item>
</ul>
</div>
<script>
// 全局组件 注意大写,引用时默认-连接大写
// props接收父组件的变量
// Vue.component("TodoItem", {
// props:['content'],
// template: "<li>{{content}}</li>"
// })
//局部组件,必须去vue实例中注册组件
var TodoItem = {
props:['content', 'index'],
template: "<li @click='handleItemClick' >{{content}}</li>",
methods: {
handleItemClick: function(){
//子组件触发父组件
this.$emit("delete", this.index)
}
}
}
var app = new Vue({
el: '#app',
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods:{
handleBtnClick: function() {
this.list.push(this.inputValue)
this.inputValue = ''
},
// 子组件触发的父组件删除
handleItemDelete: function(index) {
// splice从传入的下标开始删除一项
this.list.splice(index, 1)
}
}
})
</script>
</body>
</html>
Vue实例的生命周期钩子
8个生命周期 api中查看有11个
创建、渲染(后有更新)、销毁各两个+active+error
Vue模板语法
其他点击绑定变量见组件化的案例
显示文本,并支持js
插值{{}}和v-text一样,进行文本转义可以正常显示标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue模板语法</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 显示文本,并支持js -->
{{msg + ' add'}}
<div v-text="msg + ' add'"></div>
<div v-html="msg + ' add'"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
msg: '<h1>hello</h1>'
}
})
</script>
</body>
</html>
<img src="//jkboy.com/wp-content/uploads/i30aA.D.e6/https://kz.cx/wp-content/uploads/2023/01/20230106113649-63b7975105e5f.png" alt="image-20201115154854389" style="zoom:50%;" />
/images/vue/Vue2.5开发去哪儿网App/Vue%20起步.assets/https://kz.cx/wp-content/uploads/2023/01/20230106113649-63b7975105e5f.png
https://bennyrhys_mr.gitee.io/images/vue/Vue2.5%E5%BC%80%E5%8F%91%E5%8E%BB%E5%93%AA%E5%84%BF%E7%BD%91App/Vue%20%E8%B5%B7%E6%AD%A5.assets/https://kz.cx/wp-content/uploads/2023/01/20230106113649-63b7975105e5f.png
i30aA.D.e6/https://kz.cx/wp-content/uploads/2023/01/20230106113649-63b7975105e5f.png
计算属性、方法、监听
意义:不要在插值属性中进行计算拼接。单独通过computed缓存属性计算并返回
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 计算属性 触发无需加() -->
<!-- {{fullName}}
{{age}} -->
<!-- 方法实现计算属性 触发需加() -->
<!-- {{fullName()}}
{{age}} -->
<!-- 监听器 -->
{{fullName}}
{{age}}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
firstName: 'benny',
lastName: 'rhys',
fullName: 'benny rhys',
age: 28
},
// 监听器 (不建议,有类缓存机制,但代码量多)
watch: {
// 监听的字段
firstName: function() {
console.log("加载一次");
this.fullName = this.firstName + " " + this.lastName;
},
lastName: function() {
console.log("加载一次");
this.fullName = this.firstName + " " + this.lastName;
}
}
//方法 (不建议,无缓存机制)
// methods: {
// //实现计算属性
// fullName: function() {
// console.log("加载一次")
// return this.firstName + " " + this.lastName;
// }
// }
//计算属性(缓存机制,所依赖的变量改变才重新加载)
// computed: {
// fullName: function() {
// console.log("加载一次")
// return this.firstName + " " + this.lastName;
// }
// }
})
</script>
</body>
</html>
计算属性的get/set
控制台通过set修改属性,进行数据处理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 计算属性 触发无需加() -->
{{fullName}}
{{age}}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
firstName: 'benny',
lastName: 'rhys',
},
//计算属性(缓存机制,所依赖的变量改变才重新加载)
computed: {
fullName: {
get: function() {
return this.firstName + " " + this.lastName;
},
set: function(value) {
var arr = value.split(" ");
this.firstName = arr[0];
this.lastName = arr[1];
}
}
}
})
</script>
</body>
</html>
样式
class的对象绑定 :class="{activated: isActivated}"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick"
:class="{activated: isActivated}"
>
hello world
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
isActivated: false
},
methods: {
handleDivClick: function() {
this.isActivated = !this.isActivated
}
}
})
</script>
</body>
</html>
clss数组绑定(代表变量,可多变量)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick"
:class="[activated, two]"
>
hello world
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
activated: "",
two: "two"
},
methods: {
handleDivClick: function() {
this.activated = this.activated === "activated" ? "" : this.activated="activated";
}
}
})
</script>
</body>
</html>
Style按变量绑定 :style="styleObj"
或者数组 :style="styleObj, {fontSize: '20px'}"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<div @click="handleDivClick"
:style="[styleObj, {fontSize: '20px'}]"
>
hello world
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
styleObj: {
color: "black"
}
},
methods: {
handleDivClick: function() {
this.styleObj.color = this.styleObj.color === "black" ? "red" : "black";
}
}
})
</script>
</body>
</html>
条件语句
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 不显示在dom中也不存在
key值添加防止虚拟dom复用导致数据复用-->
<div v-if="show === 'a'">v-if</div>
<div v-else-if="show === 'b'">v-else-if</div>
<div v-else >v-else</div>
<!-- 及时不显示,在dom中存在。display: none; -->
<div v-show="show">v-show</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
show: "a"
},
methods: {
}
})
</script>
</body>
</html>
列表渲染
数组
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!--
修改直接同步数据的2种方式:1list.push、pop、re、 2指向的对象体
不能同步的修改:指定数组下标赋值
key值尽量不要用index,应该用后端传递的唯一id
template页面不显示
-->
<template v-for="(item, index) of list" :key="item.id">
<div>{{item.text}}---{{index}}</div>
<span>{{item.text}}</span>
</template>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: [
{id: 1, text: "zhangsan"},
{id: 2, text: "lisi"}
]
},
methods: {
}
})
</script>
</body>
</html>
对象有key
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>todoList</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!--
同步更新:修改部分属性、修改指向
不同步:增删
bennyrhys--name--0 23--age--1 boy--gender--2
-->
<template v-for="(key, item, index) of userInfo">
{{key}}--{{item}}--{{index}}
</template>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
userInfo: {
name: "bennyrhys",
age: 23,
gender: "boy"
}
},
methods: {
}
})
</script>
</body>
</html>
深入理解 Vue 组件
父子元素is配合组件 子组件返回data
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 父子关系的组件 is="row" 避免出现渲染bug -->
<table>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</table>
</div>
<script>
Vue.component('row', {
// 子组件,data要写成函数,才能防止报错
data: function() {
return {
content: 'this is row'
}
},
template:'<tr><td>{{content}}</td></tr>'
})
var app = new Vue({
el: '#app',
})
</script>
</body>
</html>
标签ref引用的页面dom
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 标签使用ref,为了可以使用dom -->
<div
ref="hello"
@click="handleClick">
hello
</div>
</div>
<script>
var app = new Vue({
el: '#app',
methods:{
handleClick: function() {
alert(this.$refs.hello.innerHTML)
}
}
})
</script>
</body>
</html>
组件ref引用的是子组件的数据
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 组件使用ref,引用子组件的data -->
<team ref="t1" @change="handleChange"></team>
<team ref="t2" @change="handleChange"></team>
<div>{{total}}</div>
</div>
<script>
Vue.component('team', {
data: function() {
return {
number: 0
}
},
methods:{
handleClick: function() {
this.number ++
// 子组件给父组件的时间触发,父组件需要接收绑定
this.$emit('change')
}
},
template: '<div @click="handleClick">{{number}}</div>'
})
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods:{
handleChange: function() {
this.total = this.$refs.t1.number + this.$refs.t2.number
}
}
})
</script>
</body>
</html>
父子组件传值:
父->子
注意:单项数据流概念,(父传子,子不可修改父值。因为父值是基本类型还可以,但是引用类型的对象,可能修改之后会影响其他子组件)
解决:单项数据流。使用子组件变量保存
案例:子组件 两个数值
父<-子
案例:两个子组件的数值累加传出
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>父->子组价传值</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 父->子属性传值
:xxx="",表示传递js表达式
xxx="",表示传递字符
-->
<counter :count="3" @cin="handelCountAdd"></counter>
<counter :count="2" @cin="handelCountAdd"></counter>
<!-- 父<-子属性传值
this.$emit('changeAdd', 1)
@changeAdd="handelCountAdd"
-->
<div >{{total}}</div>
</div>
<script>
var counter = {
// 接收组件值
props: ['count'],
template: '<div @click="handleClick">{{number}}</div>',
data: function(){
return {
number: this.count
}
},
methods: {
handleClick: function() {
this.number = this.number + 1;
this.$emit('cin', 1)
}
}
}
var app = new Vue({
el: '#app',
data: {
total: 5
},
components:{
// 将局部组件注册进实例
counter: counter
},
methods:{
handelCountAdd: function(step) {
this.total += step
}
}
})
</script>
</body>
</html>
组件参数校验
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>组件参数校验非props特性</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<child count="xxxxxxxxxx"></child>
<!-- <child :count="{a:1}"></child> -->
</div>
<script>
Vue.component('child', {
// props:[] 参数检测按照下面方法
props: {
// count: Number // 数值
// count: [String, Number] // 数组
count: {
type: String,
// required: false
// default: 'xxx'
validator:function(value) {
return (value.length > 5)
}
}
},
template:'<div>{{count}}</div>'
})
var app = new Vue({
el: '#app'
})
</script>
</body>
</html>
非props特性
不可父组件传子组件值,标签会带有传值属性
props特性,父子属性值对接传递 标签没有属性
给组件绑定原生事件
通过子组件->组件 转两次触发
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>组件参数校验非props特性</title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<child @click="handleClick"></child>
</div>
<script>
Vue.component('child', {
template:'<div @click="handleClick">xxx</div>',
methods:{
handleClick: function() {
alert("click click");
this.$emit('click')
}
}
})
var app = new Vue({
el: '#app',
methods:{
handleClick:function() {
alert("click")
}
}
})
</script>
</body>
</html>
组件上直接原生触发@click.native="handleClick"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- <child @click="handleClick"></child> -->
<child @click.native="handleClick"></child>
</div>
<script>
Vue.component('child', {
template:'<div,
// template:'<div @click="handleClick">xxx</div>',
// methods:{
// handleClick: function() {
// alert("click click");
// this.$emit('click')
// }
// }
})
var app = new Vue({
el: '#app',
methods:{
handleClick:function() {
alert("click")
}
}
})
</script>
</body>
</html>
非父子组件传值
解决非父子组件传值:
- Vue官方提供了:VueX数据层框架
- 发布订阅模式(总线机制/bus/观察者模式)
总线bus 定义 触发 生命周期赋值改变
案例:两个子组件数值,点击变成对方
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<child content="hello"></child>
<child content="world"></child>
</div>
<script>
// 非父子组件传值
// 新增bus总线 装载新属性
Vue.prototype.bus = new Vue()
Vue.component('child', {
props:{
content: String
},
template:'<div @click="handleClick">{{selfContent}}</div>',
// 单项数据流
data: function() {
return {
selfContent: this.content
}
},
methods:{
handleClick: function() {
// 通过bus子组件传值
this.bus.$emit('change', this.selfContent)
}
},
mounted: function(){
// this作用域
var this_ = this
// $on监听
this.bus.$on('change', function(msg) {
// alert(msg)
// 两个子组件会被触发两次
this_.selfContent = msg
})
}
})
var app = new Vue({
el: '#app',
methods:{
}
})
</script>
</body>
</html>
Vue中使用插槽
具名插槽slot
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!--
header
www
footer
-->
<div id="app">
<child>
<div slot="header">header</div>
<div slot="footer">footer</div>
</child>
</div>
<script>
Vue.component('child', {
template:`<div>
<slot name="header"></slot>
<div>www</div>
<slot name="footer"></slot>
</div>`
})
var app = new Vue({
el: '#app',
methods:{
}
})
</script>
</body>
</html>
Vue的作用域插槽
作用域组件必须template标签
场景:列表循环 样式父组件控制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<child>
<!-- 作用域组件必须template标签
1
2
3
4-->
<template slot-scope="props">
<h1>{{props.item}}</h1>
</template>
</child>
</div>
<script>
Vue.component('child', {
data:function() {
return {
list:[1, 2, 3, 4]
}
},
// 子组件给父组件传递插槽的值
template:`<div>
<ul>
<slot
v-for="item of list"
:item=item>
</slot>
</ul>
</div>`
})
var app = new Vue({
el: '#app',
})
</script>
</body>
</html>
动态组件v-once指令
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- v-once通过缓存,解决创建并销毁的性能问题 -->
<!-- <child1 v-if="type === 'child1'"></child1>
<child2 v-if="type === 'child2'"></child2> -->
<!-- 动态组件 -->
<component :is="type"></component>
<button @click="handleClick">点击切换显示</button>
</div>
<script>
Vue.component('child1', {
template:'<div v-once>a</div>'
})
Vue.component('child2', {
template:'<div v-once>b</div>'
})
var app = new Vue({
el: '#app',
data:{
type: "child1"
},
methods:{
handleClick: function() {
this.type = (this.type === "child1" ? "child2" : "child1")
}
}
})
</script>
</body>
</html>
Vue 中的动画特效
Vue中的Css动画
动画出现
动画离开
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style>
.fade-enter,
.fade-leave-to{
opacity: 0
}
.fade-enter-active,
.fade-leave-active{
transition: opacity 3s;
}
</style>
</head>
<body>
<div id="app">
<!--
name绑定和上方样式.fade-对应。如果不起name则样式默认.v-
动画过渡是监控opacity画面出现时为1,监控值变化则开始动画过渡3s
-->
<transition name="fade">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">点击切换显示</button>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
show: true
},
methods:{
handleClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
Animate.css库
先由自定义c3动画效果引入animation
定义动画执行到%多少,文字放大多少倍
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style>
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
.fade-enter-active{
transform-origin: left center;
animation: bounce-in 1s;
}
.fade-leave-active{
transform-origin: left center;
animation: bounce-in 1s reverse;
}
</style>
</head>
<body>
<div id="app">
<transition name="fade">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">点击切换显示</button>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
show: true
},
methods:{
handleClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
// 自定义css名
<style>
.active{
transform-origin: left center;
animation: bounce-in 1s;
}
.leave{
transform-origin: left center;
animation: bounce-in 1s reverse;
}
</style>
<transition
name="fade"
enter-active-class="active"
leave-active-class="leave">
<div v-if="show">hello world</div>
</transition>
开始Animate.css库
官网下载csshttps://animate.style/
引入link css路径
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
</head>
<body>
<div id="app">
<transition
name="fade"
enter-active-class="animate__animated animate__flash"
leave-active-class="animate__animated animate__bounce"
appear
appear-active-class="animate__animated animate__bounce"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">点击切换显示</button>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
show: true
},
methods:{
handleClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
Vue中同时使用过渡和动画
两种动画
- 引入第三方库,使用的是@keyframes修饰的
- 过渡动画transition
动画时长
- 以哪个为准type指定
type="transition"
- 自定义手动设置
:duration="10000"
或者详细:duration="{enter: 5000, leave: 10000}"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style>
.fade-enter, .fade-leave-to {
opacity: 0;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 3s;
}
</style>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
</head>
<body>
<div id="app">
<transition
:duration="{enter: 5000, leave: 10000}"
name="fade"
appear
enter-active-class="animate__animated animate__flash fade-enter-active"
leave-active-class="animate__animated animate__bounce fade-leave-active"
appear-active-class="animate__animated animate__bounce"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">点击切换显示</button>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
show: true
},
methods:{
handleClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
Vue中的Js动画与Velocity.js结合
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
<style>
</style>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
</head>
<body>
<div id="app">
<!-- enter 换成 leave -->
<transition
name="fade"
@before-enter="handleBeforeEnter"
@enter="handleEnter"
@after-enter="handleAfterEnter"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">点击切换显示</button>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
show: true
},
methods:{
handleClick: function() {
this.show = !this.show
},
handleBeforeEnter: function(el) {
el.style.color = 'red'
},
handleEnter:function(el, done) {
setTimeout(() => {
el.style.color = 'green'
}, 2000)
setTimeout(() => {
done()
}, 4000)
},
handleAfterEnter: function(el) {
el.style.color = "#000"
}
}
})
</script>
</body>
</html>
引入velocity.js后钩子函数的简单使用
案例:结合上边点击出现的动画