自定义指令
当Vue提供的系统指令不能满足需求时,就需要自己定义指令来进行扩展。
·例1、定义一个v-focus指令来实现文本框的自动获取焦点功能
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义聚焦指令</title>
<script type="text/javascript" src="../../js/vue.js" ></script>
</head>
<body>
<div id="app">
<input type="text" />
<br />
<input type="text" v-focus v-model='msg' />
</div>
</body>
<script>
//新建一个全局指令,使用在HTML元素属性上
//第一个参数focus是指令名,指令名在声明的时候,不需要加v-
Vue.directive('focus',{
//el参数绑定了这个指令的DOM元素,el 就等价于 document.getElementById('el.id')
inserted(el){
//获取焦点
el.focus()
}
});
new Vue({
el:'#app',
data:{
msg:'aaa'
}
});
</script>
</html>
指令定义函数提供了几个钩子函数(可选)
钩子函数
- bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
- inserted:被绑定元素插入父节点调用(父节点存在即可调用,不必存在于document中)
- update:被绑定元素插入父节点时调用,而不论绑定值是否变化。
- componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
- unbind:只调用一次,指令与元素解绑时调用。
钩子函数参数
- el:指令所绑定的元素,可以直接操作DOM。
- binding:一个对象
简写方案:
当指令的定义对象中只使用update时,只需直接传入函数即可,如下:
Vue.directive('my-directive',function(){//...})
过滤器
过滤器是一个通过输入数据,能够及时对数据进行处理并返回一个数据结果的简单函数。Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。
自定义全局过滤器
定义方式
可以用全局方法Vue.filter()注册一个全局自定义过滤器,它接受两个参数:过滤器ID和过滤器函数。过滤器函数以值为参数,返回转换后的值
定义方法:
Vue.filter("dfmt",function(input,splicchar){
var date = new Date(input);
var year = date.getFullYear();
var mon = date.getMonth()+1;
var day = date.getDate();
var fmtstr = year + splicchar+mon+splicchar+day;
return fmtstr;
});
使用方法:
<div id="app">
{{time | dfmt('-') }}
</div>
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>过滤器</title>
<script type="text/javascript" src="../../js/vue.js" ></script>
</head>
<body>
<div id="app">
{{time | dfmt('-') }}
</div>
</body>
<script>
Vue.filter("dfmt",function(input,splicchar){
var date = new Date(input);
var year = date.getFullYear();
var mon = date.getMonth()+1;
var day = date.getDate();
var fmtstr = year + splicchar+mon+splicchar+day;
return fmtstr;
});
new Vue({
el:'#app',
data:{
time:new Date()
}
});
</script>
</html>
自定义私有过滤器
例子
new Vue({
el:'#app',
data:{
time:new Date()
},
filters:{
dfmt:function(input,splicchar){
var date = new Date(input);
var year = date.getFullYear();
var mon = date.getMonth()+1;
var day = date.getDate();
var fmtstr = year + splicchar+mon+splicchar+day;
return fmtstr;
}
}
});
使用
<div id="app">
{{time | dfmt('-') }}
</div>
Vue过渡动画
通过Vue.js的过渡系统,可以在元素从DOM中插入或移除时自动应用过渡效果。Vue.js会在适当的时机为你触发CSS过渡或动画;
常用场景有:
- 条件渲染 (使用v-if)
- 条件展示 (使用v-show)
- 动态组件
过渡类名
- 组件过渡过程中,会有四个CSS类名进行切换,这四个类名与上面transition的name属性有关,比如name="v",会有以下六个CSS类名:
-
v-enter
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。 -
v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。 -
v-enter-to
: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时v-enter
被移除),在过渡/动画完成之后移除。 -
v-leave
: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。 -
v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。 -
v-leave-to
: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时v-leave
被删除),在过渡/动画完成之后移除。
-
例子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>动画示例</title>
<script type="text/javascript" src="../../js/vue.js" ></script>
<style>
p{
width: 200px;
height: 200px;
background-color: blueviolet;
}
/*整个过程渐变1s*/
.fade-enter-active,.fade-leave-active{
transition: all 1s;
}
/*开始状态*/
.fade-enter,.fade-leave-to{
opacity: 0;
width: 0px;
height: 0px;
background-color: red;
border-radius: 50%;
}
/*结束状态*/
.fade-enter-to,.fade-leave{
opacity: 1;
}
</style>
</head>
<body>
<div id="app">
<button @click="change()">切换</button>
<transition name="fade">
<p v-show="flag"></p>
</transition>
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
flag:true
},
methods:{
change:function(){
this.flag = ! this.flag
}
}
});
</script>
</html>
组件Component
封装一段html代码,便于代码的复用
组件的注册
- 全局组件
- Vue.component(组件名,配置项)
- 局部组件
- components:{'组件名':配置项}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>组件</title>
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="app">
<!--组件的使用-->
<hello></hello>
<develop></develop>
<test></test>
</div>
//template模板
<template id="mytemplate">
<p style="background-color: green;">这是使用html定义的template模板</p>
</template>
</body>
<script>
//注册全局组件
Vue.component('hello',{
template:'<h3>Hello</h3>'
});
Vue.component('test',{template:"#mytemplate"});
new Vue({
el:'#app',
//局部组件的注册-
components:{
"develop":{
template:"<ul><li>java</li><li>python</li></ul>"
}
}
});
</script>
</html>
注意:template的直接子标签只能有一个。如果需要多个标签,那么可以将多个标签的外层再包一个<div>,将该<div>嵌入到template中。
动态组件
让多个组件使用同一个挂载点,并动态切换,这就是动态组件。通过vue内置的<componenntv-bind:is=“要显示的组件名”></component>可实现。
使用步骤
- 第一步:定义不同组件
- 第二步:在挂载点使用component标签,然后使用v-bind:is=”组件名”,会自动去找匹配的组件名
例子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>动态组件</title>
<script src="../../js/vue.js"></script>
</head>
<body>
<div id="app">
<a href="#" @click="msg='login'">登录</a>
<a href="#" @click="msg='register'">注册</a>
<!--component动态组件::is="msg"msg的值决定了渲染出来的组件-->
<component :is="msg"></component>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'login'
},
components: {
'login': {
template: '<h1>登录页面</h1>'
},
'register': {
template: '<h1>注册页面</h1>'
},
}
});
</script>
</body>
</html>
组件的嵌套
理论上组件可以无限嵌套子组件,但是建议不要太多,尽量不要超过3层,否则不好维护。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>动态组件</title>
<script src="../../js/vue.js"></script>
<style>
.compoentdiv{
width: 98%;
height: 400px;
border: 1px gray solid;
}
</style>
</head>
<body>
<div id="app">
<button @click="login()">登录</button><button @click="register()">注册</button>
<component v-bind:is="msg"></component>
</div>
<template id="logintmp">
<div class="compoentdiv">
<label>用户名</label><input type="text" />
<br />
<label>密码</label><input type="password" />
<br />
<!--子组件的使用-->
<mybtn></mybtn>
</div>
</template>
<template id="regtmp">
<div class="compoentdiv">
<label>姓名</label><input type="text" />
<br />
<label>身份证</label><input type="text" />
</div>
</template>
<template id="mybtn">
<button>登录</button>
</template>
<script>
new Vue({
el: '#app',
data: {
msg: 'logincom'
},
//注册局部组件
components: {
'logincom': {
template: '#logintmp',
//定义子组件
components: {
'mybtn': {
template: '#mybtn'
}
}
},
'register': {
template: '#regtmp'
}
},
methods: {
login: function() {
this.msg = 'logincom';
},
register: function() {
this.msg = 'register';
}
}
})
</script>
</body>
</html>
slot
在定义组件的时候,可以使用<slot>标签进行一个占位,该位置放什么内容,是用在组件使用的时候将内容传入slot中显示的。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>solt的使用</title>
<script type="text/javascript" src="../../js/vue.js" ></script>
</head>
<body>
<div id="app">
<testslot>
//使用label替换槽myslot
<label slot="myslot">这是solt里的内容</label>
//使用input替换槽myslot2
<input type="text" slot="myslot2" />
</testslot>
</div>
<template id="myplt">
<div>
<h4>这是组件,下面是solt</h4>
<slot name="myslot"></solt>
<br />
<slot name="myslot2"></solt>
</div>
</template>
</body>
<script>
Vue.component("testslot",{
template:'#myplt'
})
new Vue({
el:'#app'
});
</script>
</html>