一、自定义全局指令 Vue.directive
自定义指令的生命周期,有5个事件钩子,可以设置指令在某一个事件发生时的具体行为:
-
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
-
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
-
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
-
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
-
unbind: 只调用一次, 指令与元素解绑时调用。
接下来我们来看一下钩子函数的参数 (包括 el,binding,vnode,oldVnode) -
el: 指令所绑定的元素,可以用来直接操作 DOM 。
-
binding: 一个对象,包含以下属性:
-
name: 指令名,不包括 v- 前缀。
-
value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
-
oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
-
expression: 绑定值的字符串形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
-
arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
-
modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
-
vnode: Vue 编译生成的虚拟节点,查阅 VNode API 了解更多详情。
-
oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
除了 el 之外,其它参数都应该是只读的,尽量不要修改他们。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。
<div ref="newsList" class="newsList" v-scroll='vis' dis="300" v-top><!--自定义指令,v-是固定的后缀随意-->
import Vue from 'vue'
Vue.directive("scroll",(el,binding)=>{ //el是指令绑定的那个元素 binding是指令v-scroll传过来的值 这两个是固定写法
var dis = Number(el.getAttribute("dis"))
el.addEventListener("scroll",()=>{
if(el.scrollTop>dis){
binding.value.flag=true
}else{
binding.value.flag=false
}
})
})
Vue.directive("top",(el,binding)=>{
el.onClick=function(){
el.parentNode.scrollTop=0
console.log(11)
}
})
节流操作:
<div ref="newsList" class="newsList" v-scroll='vis' dis="300" v-gd >
Vue.directive("gd",{ //监听下拉加载的滚动事件
bind(el){
var dis = Number(el.getAttribute("dis"));
var flag = false
el.addEventListener("scroll",()=>{
if(el.scrollTop>dis){
console.log("满足条件")
if(flag) return; //节流操作,如果符合条件就触发一次
flag = true;
setTimeout(()=>{
console.log("ajax操作")
flag=false;
el.scrollTop=0
},1000)
}
})
}
})
防抖操作:
<div ref="newsList" class="newsList" v-scroll='vis' dis="300" v-gd >
Vue.directive("gd",{ //监听下拉加载的滚动事件
bind(el){
var dis = Number(el.getAttribute("dis"));
var timer = null;
el.addEventListener("scroll",()=>{
if(el.scrollTop>dis){
console.log("满足条件")
if(timer) clearInterval(timer) // 防抖 如果timer存在就清除定时器
timer=setTimeout(()=>{
console.log("ajax操作")
el.scrollTop=0
},1000)
}
})
}
})
二、自定义全局过滤器
定义一个全局的自定义过滤器,需要使用Vue.filter()构造器。这个构造器需要两个参数。
三、匿名插槽 和 具名插槽
vue里提供了一种将父组件的内容和子组件的模板整合的方法:内容分发,通过slot插槽来实现
1. 匿名插槽
<aaa>abc</aaa>
template:"<h1><slot></slot></h1>"
在父组件中使用子组件的时候,在子组件标签内部写的内容,在子组件的模板中可以通过<slot></slot>来使用
2. 具名插槽
父组件在子组件标签内写的多个内容我们可以给其设置slot属性来命名,在子组件的模板中通过使用带有name属性的slot标签来放置对应的slot,当slot不存在的时候,slot标签内写的内容就出现
<body>
<div id="box">
<com><span slot='left'>搜索</span><span slot='right'>查找</span></com> //在子组件中添加插槽的内容
</div>
<script type="text/javascript">
var com ={
template:`<div ><slot name="left"></slot>这是模板中的内容它的两边可以通过插槽插入内容<slot name="right"></slot></div>`
}
new Vue({
el:"#box",
components:{
com
}
})
</script>
</body>
四、混合 mixins 可以通过mixins 在不同的组件中调用相同的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src='js/vue.js'></script>
</head>
<body>
<div id='box1'>
<p @click="text">one</p>
</div>
<div id='box2'>
<p @click="text">two</p>
</div>
<script type="text/javascript">
var obj={
methods:{
text(){
console.log("hahaha")
}
}
}
new Vue({
el:"#box1",
mixins:[obj] //可以通过mixins 在不同的组件中调用相同的方法
})
new Vue({
el:"#box2",
mixins:[obj]
})
</script>
</body>
</html>