vue-05-自定义指令

vue的自定义指令和上一篇的过滤器一样,也分为全局自定义指令,和组件内的自定义指令

vue的指令都是以v-开头的,所以自定义的vue指令也不例外,v-开头,后面的指令名称自定义

1、全局自定义指令

main.js内部实现该指令

    1.1、不带参数的自定义指令

例如我在这个h2标签中添加了一个自定义指令,但是单纯的添加指令是无效的,我们需要在main.js文件内部实现这个指令

 <h2 v-texTcolor>{{blog.title}}</h2>

在 Vue 下面的 directive 就是专门来实现自定义指令的,存在两个参数,

第一个参数是字符串,字符串内部就是自定义的指令名称,(ps:这里的名称不能带on)

第二个参数是一个对象,对象内部存在一个bind钩子函数,一个inserted钩子函数,一个update钩子函数,该方法内部也存在三个参数,

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

  钩子函数的参数:

  第一个是el,也就是这个指令绑定的对象,可以用来直接操作 DOM。

  第二个则是binding可以来对页面进行操作,通过取到 binding内部的属性来操作当前页面的状态

  第三个参数是vnode,也就是虚拟dom节点

//自定义指令,改变标题颜色随机
Vue.directive('texTcolor' , {
  bind(el , binding ,vnode){
    el.style.color = '#' + Math.random().toString(16).slice(2,8)	//取0≤?<1的数字,然后转化为16进制的数值,截取第二位到第八位,然后拼接上前面地 # 键,形成颜色值
  }
})

这个自定义指令在main.js文件内部实现之后,表现出来的就是,我页面上的所有h2标签每次刷新颜色都是随机的

   

    1.2、带参数的自定义指令

可以看到我在最外层 div 上添加了 一个自定义的指令 v-theme,这个指令后面戴上了参数,这里需要注意的是,这个参数可以为对象,数组,字符串等等类型,但是,在参数为字符串的时候,需要在加上一层单引号将字符串包裹

<template>
    <div id="show-blogs" v-theme="'narrow'">
    <h1>博客总览</h1>
    <input type="text"  placeholder="搜索">
    <div  class="single-blog" v-for="blog in blogs">
        <h2 v-texTcolor>{{blog.title}}</h2>
        <article>
            {{blog.body}}
        </article>
    </div>
  </div>
</template>

//自定义指令,改变宽度
Vue.directive('theme' , {
  bind(el , binding , vnode){

    if (binding.value == 'wide') {

      el.style.maxWidth = '1200px'

    } else if(binding.value == 'narrow'){

      el.style.maxWidth = '560px'
    }
  }
})

同上所说,binding可以用来显示绑定的参数,以此来加以判断,若是自定义指令的参数满足某种条件,则执行下一步代码,这里是判断自定义指令的参数值是否为 wide 或 narrow 以此来规定最外层盒子的最大宽度

    1.2、带 动态参数  的自定义指令

同时,我们除了v-for、v-text等等直接带参数的指令,也经常使用v-on:click=“”,这一类的带 :xxxx 的指令,这里我们也可以使用自定义指令来实现

很明显,我在最外层的自定义指令上添加了 :column 这个属性,而在自定义指令内部,可以通过  binding.arg  来取到这个动态参数

ps:column 属性值可以在data 内部定义变量来实现动态改变

<template>
    <div id="show-blogs" v-theme:column="'narrow'">
    <h1>博客总览</h1>
    <input type="text"  placeholder="搜索">
    <div  class="single-blog" v-for="blog in blogs">
        <h2 v-texTcolor>{{blog.title}}</h2>
        <article>
            {{blog.body}}
        </article>
    </div>
  </div>
</template>

//自定义指令,改变宽度
Vue.directive('theme' , {
  bind(el , binding , vnode){
    if (binding.value == 'wide') {
      el.style.maxWidth = '1200px'
    } else if(binding.value == 'narrow'){
      el.style.maxWidth = '560px'
    }
    
    //在这里获取动态参数,进行页面渲染
    if(binding.arg == 'column'){
      el.style.background = '#666'
    }
  }
})

2、组件内部自定义指令

类似的,组件内的自定义指令,directives 代表的就是组件内部的自定义指令集合,所有的自定义指令都写在内部,而且,每个自定义指令都是一个对象

texTcolor、theme都是自定义组件名字,字符串参数 'narrow' 必须这样写 ,用 binding.value 来接收、column 需要用 binding.arg来接收

<template>
    <div id="show-blogs" v-theme:column="'narrow'">
        <h1>博客总览</h1>
        <input type="text"  placeholder="搜索" v-model="search">
        <!-- <h3 @click="scarchBlog">点击搜索</h3> -->
        <h2>{{search}}</h2>
        <div  class="single-blog" v-for="blog in scarchBlogs">
            <h2 v-texTcolor>{{blog.title | to-upcase}}</h2>
            <article>
                {{blog.body | overflower}}
            </article>
        </div>
    </div>
</template>


directives: {
    'texTcolor' : {
        bind(el ,binding , vnode){
            el.style.color = '#' + Math.random().toString(16).slice(2,8)
        }
    },
    'theme':{
        bind(el , binding , vnode){
            if (binding.value == 'wide') {
                el.style.maxWidth = '1200px'
            }else if (binding.value == 'narrow') {
                el.style.maxWidth = '560px'
            }

            if (binding.arg == 'column') {
                el.style.background = '#ddd'
            }
        }
    }
} 
发布了13 篇原创文章 · 获赞 0 · 访问量 107

猜你喜欢

转载自blog.csdn.net/qq_40792800/article/details/105531758