1.生命周期
生命周期:描述了一个组件从创建、初始化、[运行<=>阻塞]、最终被销毁的完整过程
Vue实例从创建开始到网页DOM结构加载并渲染数据完成时的过程,主要包含的生命周期函数如下:
创建过程
breforeCreate() :实例初始化之前的生命周期钩子
是否可以调用实例数据:否
是否可以调用DOM对象:可以访问已有元素,不可以访问Vue实例标签元素
created():实例创建后的生命周期钩子
是否可以调用实例数据:是
是否可以调用DOM对象:可以访问已有元素,不可以访问Vue实例标签元素
beforeMount() :DOM结构渲染前的生命周期钩子
是否可以调用实例数据:是
是否可以调用DOM对象:可以访问已有元素,不可以访问Vue实例标签元素
mounted():DOM结构渲染后的生命周期钩子
是否可以调用实例数据:是
是否可以调用DOM对象:可以访问已有元素,可以访问Vue实例标签元素
生命周期函数,也经常被称为生命周期钩子
生命周期函数在实例从创建、运行到销毁过程中,根据实例的不同的状态自动执行调用(通过事件和回调函数的方式进行执行调用的,所以称为钩子函数)
<div id='app'>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
msg:'我是dom数据'
},
beforeCreate() {
console.log('beforeCreate被调用了',this.msg ? this.msg:'未获取到msg')
},
created() {
console.log('created被调用了',this.msg ? this.msg:'未获取到msg')
},
beforeMount(){
console.log('beforeMount被调用了',this.msg ? this.msg:'未获取到msg')
},
mounted(){
console.log('beforeCreate被调用了',this.msg ? this.msg:'未获取到msg')
}
})
</script>
运行过程
Vue实例运行过程中,主要体现的是数据同步通信和自动渲染的操作,主要包含了两个生命周期
beforeUpdate() 更新前
updated() 更新后
beforeUpdate(){
console.log('beforeUpdate被调用了')
}
updated(){
console.log('updated被调用了')
}
销毁过程
实例销毁过程,主要是在组件项目开发时,有些组件使用结束后需要销毁释放占用的系统资源,让系统资源加载其他组件服务项目应用,提高组件在有效资源的情况下的最大利用率,主要包含两个生命周期
beforeDestory() :销毁之前调用的生命周期
destoryed():销毁之后调用的生命周期
beforeDestory(){
console.log('beforeDestory被调用了')
}
destoryed(){
console.log('destoryed被调用了')
}
2.侦听器
侦听器,也称为监听器,Vue框架提供给开发人员的一个用来监控变量数据的组件,一旦监控的变量数据发生变化, 侦听器对应的函数就会执行,函数内部就可以针对变化的数据进行业务处理/数据运算
Vue实例中:watch,声明监听器
<div id='#app'>
<input type='text' v-model.lazy='msg'>
<h2>{{msg}}</h2>
</div>
...
<script>
...
data:{
msg: '我是监听的数据'
},
watch:{
msg:{
handler(newVal,oldVal) {
alert('数据发生了变化'+newVal+'《---'+oldVal)
}
}
}
...
</script>
注意:当项目中需要在数据变化是执行异步或开销较大的操作时,可以使用侦听器
3.计算属性
Vue提供了根据已知数据自动完成运算过程,得到结果数据的组件
Vue实例中:computed,实现计算属性的功能
<div id='#app'>
<p>单价:{{price}}</p>
购买数量:<input type='number' v-mode='count'>
<h2>小计:{{total}}</h2>
</div>
...
<script>
...
data:{
price: '21',
count:0
},
computed:{
total() { //本质上一个函数,可以当成属性变量一样使用
return this.price * this.price
}
}
...
</script>
计算属性和普通函数
当数据发生变化,计算属性会自动调用并缓存结果、普通函数必须通过函数名称进行调用直接执行代码
当数据没有发生变化、计算属性不会重复执行函数代码(直接使用上一次运算缓存的结果数据),普通函数会再次执行代码(消耗资源)
计算属性和侦听器
相同:当目标数据发生变化时,都会自动调用并执行相关函数
计算属性本质上就是函数的运行结果,侦听器仅仅是监听了数据的变化
当需要针对每个数据的变化执行不同的业务操作或者数据运算时建议使用监听器
当多个变量中数据的变化互相关联时,建议使用计算属性
4.过滤器
过滤器是对页面视图中展示的数据进行格式化处理的组件
过滤器使用时分为两种
组件过滤器、私有过滤器:只能被当前组件、实例使用
...
fiters:{
过滤器名称(待处理数据){
return ...
}
}
...
全局过滤器:可以被所有Vue组件/实例使用
Vue.filter('过滤器名称',function(){
return ...
})
案例操作:
<div id="app">
<h2>商品管理</h2>
<table border=1 width=500>
<tr>
<td>编号</td>
<td>名称</td>
<td>单价</td>
<td>添加时间</td>
<td>操作</td>
</tr>
<tr v-for="(goods, index) in goodses" :key="goods.id">
<td>{{index}}</td>
<td>{{goods.name|formatName}}</td>
<!-- 私有过滤器 -->
<td>{{ goods.price|formatPrice }}</td>
<!-- 全局过滤器 -->
<td>{{goods.time|formatTime}}</td>
<td>
<button>添加</button>
<button>编辑</button>
</td>
</tr>
</table>
</div>
<script src="./vue.js"></script>
<script>
// 2.定义全局过滤器
Vue.filter('formatTime', function(dat) {
var date = new Date(dat)
return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
})
const vm = new Vue({
el: '#app',
data: {
goodses: [
{id: 3, name: "白菜", price: 8.00, time: Date.now()},
{id: 2, name: "上海青", price: 12.00, time: Date.now()},
{id: 1, name: "腐竹", price: 9.00, time: Date.now()},
]
},
filters: { // 1.定义组件过滤器/私有过滤器
formatPrice(dat) {
return "¥" + dat + "元/斤"
},
formatName(dat) {
return "[" + dat + "]"
}
}
})
</script>
5.动画过渡
Vue框架对页面视图中的标签动画,提供了自己特有的处理方式
页面中的任何标签的动画操作,区分为进入动画、离开动画
进入动画:进入前: .v-enter、进入中: .v-enter-active、进入后 .v-enter-to
离开动画:离开前.v-leave、离开中.v-leave-active、离开后.v-leave-to
基本过度效果
基本过度动画,是通过Vue框架提供的6个基本类型实现自动动画
<style>
.v-enter-to,
.v-leave {
left:0
}
.v-enter-active,
.v-leave-active{
position: relative,
transition: all 2s
}
.v-enter,
.v-leave-to{
left: 200px
}
</style>
<body>
<div id='#app'>
<button @click='toggleC'>切换</button>
<transition appear>
<h3 v-show='seen'></h3>
</transition>
</div>
...
<script>
...
data:{
seen:true
},
methods:{
toggleC(){
this.seen = !this.seen
}
}
...
</script>
</body>
自定义动画名称
一个单独的HTML网页中,需要动画效果控制的标签对象非常多,并且它们各自的动画风格不一定相同,需要自定义名称的动画进行区分
<style>
.fade-enter-to,
.fade-leave{ /* 进入之后,离开之前 */
opacity:1;
}
.fade-enter-active,
.fade-leave-active{ /* 离开中:动画,进入中 */
transition: all 2s;
}
.fade-enter,
.fade-leave-to{ /* 离开之后,进入之前 */
opacity:0;
}
</style>
<body>
<div id="app">
<button @click="toggleF">切换</button>
<transition appear name="fade">
<h3 v-show="seen2">透明度过渡动画</h3>
</transition>
</div>
...
<script>
...
data: {
seen2: true,
},
methods: {
toggleF() {
this.seen2 = !this.seen2
}
}
})
</script>
列表组动画
Vue中使用包裹的标签实现过度动画,只支持单节点动画效果,如果内部包含了多个标签就无法实现动画效果
//不支持
<transition>
<div><span>1</span> <span>第一个</span> </div>
<div><span>2</span> <span>第二个</span> </div>
</transition>
Vue针对多个子节点的情况,提供了过度动画组实现
<transition>
<div><span>1</span> <span>第一个</span> </div>
<div><span>2</span> <span>第二个</span> </div>
</transition>
<style>
.top-enter-to,
.top-leave{
top:0;
}
.top-enter-active,
.top-leave-active{
position: relative;
transition: all 2s;
}
.top-enter,
.top-leave-to{
top:-500px;
}
</style>
<body>
<div id="app">
<button @click="toggleT">动画组 切换显示/隐藏</button>
<transition-group appear name="top">
<div v-show="seen3" key="1"><span>1</span><span>第一个</span></div>
<div v-show="seen3" key="2"><span>2</span><span>第二个</span></div>
</transition-group>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
seen3: true
},
methods: {
toggleT() {
this.seen3 = !this.seen3
},
}
})
</script>
</body>
第三方动画库
项目中的动画效果,对于用户的使用体验的提升有一定的好处,自己独立开发的动画效果往往比较单一,此时可以结束动画库完成复杂的操作,如Animate.css
官方网站:https://animate.style
注:animate.css提供的动画,区分进入的动画和离开的动画,混淆使用会导致动画失效
animate.css提供的动画类名称,不要借助官方复制样式名称,将样式名称自己复制过来使用
- 官方复制名称:
animate__hinge
,实际使用时这个名称无效 - 手工复制名称:
hinge
,实际使用时:xxxx-active-class="animated hinge"
<transition appear enter-active-class="animated rollIn" leave-active-class="animated hinge">
<h1 v-show="seen">animate.css动画效果</h1>
</transition>