Vue的计算属性:computed
这里处理数据的要求是:让显示变量 message 的字符串翻转
<div id="app">
<!--使用Vue计算属性不能在后面加上(),因为它是一个属性不是函数(方法)-->
<p>{{reversedMessage}}</p>
</div>
<script>
//2.创建Vue的实例对象-->这里就是MVVM中的View Model
let vue = new Vue({
//3.告诉Vue的实例对象,将来需要控制界面的上的哪个区域
el:"#app",
//4.告诉Vue的实例对象,被控制区域的数据是什么 -->这里就是MVVM中的Model
data:{
message:"abcdefg"
},
//5.专门用于储存监听事件回调函数
methods:{},
//6.专门用于定义计算属性的
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
let res = this.message.split('').reverse().join('');
return res;
}
}
});
</script>
结果:
计算属性和函数的区别:
- 函数的特点:每次调用都会执行;
- 计算属性的特点:只要返回的结果没有发生变化,那么计算属性只会被执行一次;
- 函数的应用场景:如果数据需要经常发生变化,推荐使用函数处理数据;
- 计算属性的应用场景:如果数据发生变化的频率不高,推荐使用计算属性处理数据,因为计算属性会将返回的结果缓存起来 如果返回的数据不会频繁的发生改变,使用计算属性会比函数的性能高;
<div id="app">
<p>{{msg1()}}</p>
<p>{{msg1()}}</p>
<p>{{msg1()}}</p>
</div>
let vue = new Vue({
el:"#app",
data:{
message:"abcdefg"
},
//专门用于储存监听事件回调函数
methods:{
/*函数的特点:每次调用都会执行*/
msg1(){
console.log("msg1被执行了");
let res = this.message.split('').reverse().join('');
return res;
}
}
});
函数处理数据的结果:
<div id="app">
<p>{{reversedMessage}}</p>
<p>{{reversedMessage}}</p>
<p>{{reversedMessage}}</p>
</div>
let vue = new Vue({
el:"#app",
data:{
message:"abcdefg"
},
//专门用于储存监听事件回调函数
methods:{
},
//专门用于定义计算属性的
computed: {
/*计算属性的特点:只要返回的结果没有发生变化,那么计算属性只会被执行一次 */
// 计算属性的 getter
reversedMessage: function () {
console.log("reversedMessage被执行了");
// `this` 指向 vm 实例
let res = this.message.split('').reverse().join('');
return res;
}
}
});
计算属性处理数据的结果:
Vue的过滤器:filter/filters
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号“|”指示;
- 自定义全局过滤器 :在任何一个vue实例控制区域内都可以使用
<div id="app">
<!--Vue会把name交给指定的过滤器处理之后,再把处理后的结果插入到指定的元素中-->
<p>{{name|formatStr1|formatStr2}}</p>
</div>
//自定义全局的过滤器
/*接受两个参数:1.过滤器名称 2.处理数据的函数
注意点:默认情况下处理数据的函数接受一个参数,就是当前要被处理的数据*/
Vue.filter('formatStr1', function (value) {
value = value.replace(/学院/g,"大学");
console.log(value);
return value;
});
Vue.filter('formatStr2', function (value) {
value = value.replace(/大学/g,"幼儿园");
console.log(value);
return value;
});
//Vue的实例对象中的Model
data:{
name:"南方学院,北方学院,东方学院,西方学院"
},
结果:
- 自定义局部过滤器 :只能在自定义的内个vue实例控制区域内使用
<div id="app1">
<p>{{name|formatStr1}}</p>
</div>
<div id="app2">
<!--Vue会把name交给指定的过滤器处理之后,再把处理后的结果插入到指定的元素中-->
<p>{{name|formatStr2}}</p>
</div>
<script>
let vue1 = new Vue({
el:"#app1",
data:{
name:"南方学院,北方学院,东方学院,西方学院"
},
//专门用于储存监听事件回调函数
methods:{},
//专门用于定义计算属性的
computed:{},
//专门用于定义局部过滤器的
filters:{
}
});
let vue2 = new Vue({
el:"#app2",
data:{
name:"南方学院,北方学院,东方学院,西方学院"
},
//专门用于储存监听事件回调函数
methods:{},
//专门用于定义计算属性的
computed:{},
//专门用于定义局部过滤器的
filters:{
"formatStr2":function (value) {
value = value.replace(/学院/g,"大学");
console.log(value);
return value;
}
}
});
</script>
结果:
- 过滤器常用于格式化时间
<div id="app">
<p>{{time | dateFormart("yyyy-MM-dd")}}</p>
</div>
<script>
//自定义全局的过滤器
/*接受两个参数:1.过滤器名称 2.处理数据的函数
注意点:默认情况下处理数据的函数接受一个参数,就是当前要被处理的数据
在使用过滤器的时候,可以再过滤器的名称后面加()
如果给过滤器的名称后面加上(),就可以给过滤器传递参数*/
Vue.filter("dateFormart", function (value, fmStr) {
// console.log(fmStr); // yyyy-MM-dd
let date = new Date(value);
let year = date.getFullYear();
let month = date.getMonth() + 1 + "";
let day = date.getDate() + "";
let hour = date.getHours() + "";
let minute = date.getMinutes() + "";
let second = date.getSeconds() + "";
if(fmStr && fmStr === "yyyy-MM-dd"){ //过滤器dateFormart是否传递了参数且参数格式为 yyyy-MM-dd
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
}
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")} ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}:${second.padStart(2, "0")}`;
});
//2.创建Vue的实例对象-->这里就是MVVM中的View Model
let vue = new Vue({
//3.告诉Vue的实例对象,将来需要控制界面的上的哪个区域
el:"#app",
//4.告诉Vue的实例对象,被控制区域的数据是什么 -->这里就是MVVM中的Model
data:{
time: Date.now()
},
//5.专门用于储存监听事件回调函数
methods:{},
//6.专门用于定义计算属性的
computed:{}
});
</script>
padStart()方法用另一个字符串填充当前字符串(重复,如果需要的话),以便产生的字符串达到给定的长度。
语法:str.padStart(当前字符串需要填充到的目标长度。 填充字符串)
Vue控制元素添加过渡动画
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
-
使用默认类名(v-xxx)来指定过渡动画
1.将执行动画的元素添加到transition组件中
2.当transition组件显示时会自动查找v-enter/v-enter-active/v-enter-to;
当transition组件隐藏时会自动查找v-leave/v-leave-active/v-leave-to;
过渡的类名
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用默认类名(v-xxx)来指定过渡动画</title>
<script src="js/vue.js"></script>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#app{
position:absolute;
left:50%;
top:50%;
margin-left:-50px;
margin-top:-50px;
}
.box{
font-size: 20px;
color: palevioletred;
margin-top: 20px;
}
.v-enter{
opacity: 0;
}
.v-enter-active{
transition: all 1s;
}
.v-enter-to{
opacity: 1;
}
.v-leave{
opacity: 1;
}
.v-leave-active{
transition: all 1s;
}
.v-leave-to{
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<button type="button" @click="toggle">
toggle
</button>
<transition>
<p class="box" v-if="isShow">Hello</p>
</transition>
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
toggle(){
this.isShow = !this.isShow;
}
},
computed:{}
});
</script>
</body>
</html>
效果:点击按钮后显示,再次点击后隐藏
-
使用自定义类名前缀(yyy-xx)来指定过渡动画(transition name="yyy")
注意点:
1.一个transition组件中只能有一个执行动画的元素;
2.想要元素一开始就显示过渡动画,需要在包裹执行动画的元素的transition组件上添加appear属性;
3.如果有多个transition组件同时执行不同的过渡动画,需要在包裹执行动画的元素的transition组件上添加name="xxx"查找类名的前缀,过渡动画的类名以什么开头就写什么;
根据类名绑定的过渡动画执行完毕后会复位,应为在执行的过程中类名被绑定到元素上,执行完毕后绑定的类名的消失了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用自定义类名前缀(yyy-xx)来指定过渡动画</title>
<script src="js/vue.js"></script>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#app{
position: absolute;
left: 50%;
top: 50%;
margin-left:-50px;
margin-top:-50px;
}
.box{
font-size: 25px;
color: plum;
text-align: center;
margin-top: 20px;
}
.slide-fade-enter{
opacity: 0;
}
.slide-fade-enter-active{
transition: all .8s ease;
}
.slide-fade-enter-to{
opacity: 1;
}
.slide-fade-leave{
opacity: 1;
}
.slide-fade-leave-active{
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); /*贝塞尔曲线*/
}
.slide-fade-leave-to{
opacity: 0;
transform: translateX(50px); /*向右平移50px*/
}
</style>
</head>
<body>
<div id="app">
<button type="button" @click="toggle">
toggle render
</button>
<!--加appear:一开始就出来-->
<transition appear name="slide-fade">
<p class="box" v-if="isShow">Hello</p>
</transition>
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
isShow:true
},
methods:{
toggle(){
this.isShow = !this.isShow;
}
},
computed:{}
});
</script>
</body>
</html>
效果:打开界面一开始就显示Hello,点击按钮后Hello向右淡出
-
使用JS钩子函数来指定过渡动画
v-on:before-enter="beforeEnter" 进去动画之前
v-on:enter="enter" 进去动画执行过程中
v-on:after-enter="afterEnter" 进去动画完成之后
v-on:enter-cancelled="enterCancelled" 进去动画被取消
温馨提示:如果你只想设置组件过渡进入的效果而不想有组件过渡离开的效果,这时你就可以用钩子函数,只设置beforeEnter、enter、afterEnter这几个钩子函数就可以了。v-on:before-leave="beforeLeave" 离开动画之前
v-on:leave="leave" 离开动画执行过程中
v-on:after-leave="afterLeave" 离开动画完成之后
v-on:leave-cancelled="leaveCancelled" 离开动画被取消
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用JS钩子函数来指定过渡动画</title>
<script src="js/vue.js"></script>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#app{
position: absolute;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}
.box{
font-size: '1.4rem';
color: #DB7093;
margin-top: 20px;
}
.v-enter{
opacity: 0;
}
.v-enter-to{
opacity: 1;
margin-left: 500px;
}
.v-enter-active{
transition: all 3s;
}
</style>
</head>
<body>
<div id="app">
<button @click="toggle">toggle</button>
<!--注意点:虽然是通过vue钩子函数来实现过渡动画,
但默认vue还是回去查找类名,所以为了不让vue去查找名
可以给transition添加v-bind:css="false"
-->
<transition appear
v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
>
<p class="box" v-if="isShow">Demo</p>
</transition>
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
toggle(){
this.isShow = !this.isShow;
},
beforeEnter(el){//el是要执行过渡动画的元素
el.style.opacity = 0;
el.style.transformOrigin = 'left'
},
enter(el,done){//done是回调函数,告诉Vue我的动画已经执行完毕了
/*
注意点:如果通过JS钩子函数来实现过度动画
那么必须在动画执行过程的回调函数中写上
el.offsetWidth或el.offsetHeight
*/
el.offsetWidth;
el.style.transition = "all 3s";
/*
注意点:想要元素一开始就显示过渡动画
需要在包裹执行动画的元素的transition组件上添加appear
还需要在延迟一下在调用done();
*/
setTimeout(function () {
done();
},0);
},
afterEnter(el){
el.style.opacity = 1;
el.style.transform = "translateX(15px) rotateZ(50deg)";
}
},
computed:{}
})
</script>
</body>
</html>
效果:点击按钮后Demo淡出并开始旋转,在淡出
-
使用自定义类名的方式来指定过渡动画
enter-class:"xx" 进去动画之前
enter-active-class:"xx" 进去动画执行过程中
enter-to-class:"xx" 进去动画完成之后
leave-class:"xx" 离开动画之前
leave-active-class:"xx" 离开动画执行过程中
leave-to-class:"xx" 离开动画完成之后
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自定义过渡类名xxx-class</title>
<script src="js/vue.js"></script>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#app{
position: absolute;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}
.box{
font-size: '1.4em';
color: yellowgreen;
margin-top: 20px;
}
.a{
opacity: 0;
transform-origin:left ;
}
.b{
transition: all 3s;
}
.c{
opacity: 1;
font-size: '1em';
}
.d{
opacity: 1;
transform: translateX(15px) rotateZ(50deg);
}
.e{
transition: all .6s;
}
.f{
opacity: 0;
transform:rotateZ(45deg) translateY(30px) translateX(30px);
}
,
</style>
</head>
<body>
<div id="app">
<button type="button" @click="toggle">
toggle
</button>
<transition appear
enter-class="a"
enter-active-class="b"
enter-to-class="c"
leave-class="d"
leave-active-class="e"
leave-to-class="f">
<p class="box" v-if="isShow">Hello</p>
</transition>
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
isShow:true,
},
methods:{
toggle(){
this.isShow = !this.isShow;
}
},
computed:{}
})
</script>
</body>
</html>
效果:打开界面一开始就显示Hello,点击按钮后Hello开始旋转并淡出
-
利用第三方JavaScript动画库Velocity.js实现过渡动画
1. 引入Velocity.js文件:
<script src="js/velocity.js"></script>
2.给指定的元素加上指定的动画样式名(Velocity.js和钩子函数搭配使用):
v-on:before-enter="beforeEnter" 进去动画之前
v-on:enter="enter" 进去动画执行过程中
v-on:leave="leave" 离开动画执行过程中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Velocity-js来实现过渡动画</title>
<script src="js/vue.js"></script>
<script src="js/velocity.js"></script>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#app{
position: absolute;
top: 50%;
left: 50%;
margin-left:-50px;
margin-top:-50px;
}
.box{
margin-top: 20px;
}
</style>
</head>
<body>
<div id="app">
<button @click="toggle">toggle</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false">
<p class="box" v-if="isShow">Dome</p>
</transition>
</div>
<script type="text/javascript">
let vue =new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
toggle(){
this.isShow = !this.isShow;
},
beforeEnter(el){
el.style.opacity = 0
el.style.transformOrigin = 'left'
Velocity(el, { opacity: 1, fontSize: '1.4em' });
},
enter(el,done){
Velocity(el, { fontSize: '1em' }, { duration: 300 }, { complete: done });
},
leave(el,done){
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 });
Velocity(el, { rotateZ: '100deg' }, { loop: 2 });
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done });
},
},
computed:{}
})
</script>
</body>
</html>
效果:点击按钮后Dome出现且开始字体大小缩放的动画,再次点击按钮后Dome开始做旋转且摇摆两下之后掉落淡出
-
利用第三方CSS动画库Animate.css实现过渡动画
1. 引入animate.css文件:
<link rel="stylesheet" href="animate.min.css">
2.给指定的元素加上指定的动画样式名(Animate.css配合自定义过渡类名使用):
enter-active-class:"animated XXX"进去动画执行过程中
leave-active-class:"animated XXX"离开动画执行过程中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Animate.css实现过渡动画</title>
<script src="js/vue.js"></script>
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#app{
position: absolute;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}
.box{
margin-top: 20px;
color: #DDA0DD;
}
</style>
</head>
<body>
<div id="app">
<button @click="toggle">toggle</button>
<transition
appear
enter-active-class="animated tada"
leave-active-class="animated bounceOutLeft">
<p class="box" v-if="isShow">Hello</p>
</transition>
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
isShow:true
},
methods:{
toggle(){
this.isShow = !this.isShow;
}
},
computed:{}
})
</script>
</body>
</html>
效果:打开界面一开始就显示Hello,点击按钮后Hello迅速向左淡出
网友评论