分享如何在vue中自定义指令

一. 什么是自定义指令

我们看到的v-开头的行内属性,都是指令,不同的指令可以完成或实现不同的功能,vue中有默认的指令。vue 也允许注册自定义指令对普通 DOM元素进行底层操作。

二. 常见的vue指令

  1. v-once:只会执行一次渲染,当数据发生改变时,不会再变化。
<div id="app">
    <p v-once>{
    
    {
    
    msg}}</p>
    <input v-model="msg" type="text" />  // 当输入值变化的时候msg回发生变化,但是p标签渲染出的msg不会变化了
</div>
<script>
    let vue = new Vue({
    
    
        el:"#app",
        data:{
    
    
            msg:'你好,佳佳'
        }
    })
</script>
  1. v-show:接受一个表达式或一个布尔值。相当于给元素添加一个display属性
<div id="app">
    <div v-show="msg ==  'wangjiajia' ">{
    
    {
    
    msg}}</div>  // 只有当input框输入了wangjiajia,才会显示。在这里相当于给div标签添加了display:none属性
    <input v-model="msg" type="text" />
</div>
<script>
    let vue = new Vue({
    
    
        el:"#app",
        data:{
    
    
            msg:'你好,佳佳',
        }
    })
</script>
  1. v-if、v-else、v-else-if
    • v-if和v-show有同样的效果,不同在于v-if是重新渲染,属于真正意义上的删除,渲染开销大。而v-show使用display:none属性来控制显示隐藏。
    • 频繁切换的话建议使用v-show减少渲染带来的开销。
    • v-if可以单独使用,而v-else-if,v-else必须与v-if组合使用
<div id="app">
    <div v-if="msg ==  'wangjiajia' ">{
    
    {
    
    msg}}</div>  
    <div v-else-if="msg ==  'wangtongtong' ">{
    
    {
    
    msg}}</div> 
    <div v-else>davide</div> 
    <input v-model="msg" type="text" />  //只有在input框输入wangjiajia才会显示wangjiajia,输入wangtongtong才会显示wangtongtong。否则都是显示davide
</div>
<script>
    let vue = new Vue({
    
    
        el:"#app",
        data:{
    
    
            msg:'你好,佳佳',
        }
    })
</script>
  1. v-for:可用来遍历数组、对象、字符串。
<div id="app">
    <div v-for="(item, index) in bookList" :key="index">{
    
    {
    
     item }}</div> 
</div>
<script>
    let vue = new Vue({
    
    
        el:"#app",
        data:{
    
    
            msg:'你好,佳佳',
            bookList:['三国演义', '西游记', '水浒传', '红楼梦']
        }
    })
</script>
  1. v-text:是渲染字符串,和{ { }} 效果类似,推荐使用{ { }}
 <p>{
    
    {
    
    msg}}</p>  等价于  <p v-text='msg'></p>
  1. v-html:渲染为html结构
<div>{
    
    {
    
    innerHtml}}</div>
<div v-text="innerHtml"></div>
<div v-html="innerHtml"></div>
<script>
    let vue = new Vue({
    
    
        el:"#app",
        data:{
    
    
            msg:'你好,佳佳',
            bookList:['三国演义', '西游记', '水浒传', '红楼梦'],
            innerHtml:'<button>一个按钮</button>'
        }
    })
</script>

在这里插入图片描述
7. v-bind:用于数据的传递,语法糖形式为:。即v-bind:value=‘value’ 等价于 :value=‘value’。
8. v-on:用于事件绑定,语法糖形式为@。即v-on:click=“clickfunc” 等价于 @click=“clickfunc”
9. v-model:双向绑定。v-model=‘变量名’。限制在 <input><select>、<textarea>、components中使用。
ps:详见vue2篇:vue指令

三. 如何实现自定义指令

  1. 在vue2中:
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
    
    
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    
    
    // 聚焦元素
    el.focus()  // 页面加载完成之后自动让输入框获取到焦点的小功能
  }
})

// 注册一个局部自定义指令 `v-focus`

directives: {
    
    
  focus: {
    
    
    // 指令的定义
    inserted: function (el) {
    
    
      el.focus() // 页面加载完成之后自动让输入框获取到焦点的小功能
    }
  }
}
  1. 在vue3中:(以通过权限控制按钮为例)
    • 一般新建一个directives.js文件。用于自定义指令
    • 在main.js中引入该文件并挂载

七大钩子函数:

  1. created:在绑定元素的 attribute 或事件监听器被应用之前调用。在指令需要附加在普通的 v-on 事件监听器调用前的事件监听器中时,这很有用。
  2. beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用。
  3. mounted:在绑定元素的父组件被挂载后调用,大部分自定义指令都写在这里。
  4. beforeUpdate:在更新包含组件的 VNode 之前调用。
  5. updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用。
  6. beforeUnmount:在卸载绑定元素的父组件之前调用
  7. unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次。

四个参数:

  1. el:指令所绑定的元素,可以用来直接操作 DOM。
  2. binding:我们通过自定义指令传递的各种参数,主要存在于这个对象中,该对象属性较多,如下属性是我们日常开发使用较多的几个:例如:v-buttonCheck:some="['delete', 'create']"
    • value:指令绑定的值,在这里就是['delete', 'create']
    • arg:传给指令的参数,在这里就是some
  3. vnode:Vue 编译生成的虚拟节点。
  4. oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

注意:除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

<el-button v-buttonCheck:some="['delete', 'create']" type="primary">点击</el-button> // 指令的使用,some是传递的参数。['delete', 'create']是指令绑定的值。这里的意思就是,button按钮只有在具备delete或者create权限时才会显示。

// usersPermissions:表示当前用户所具备的权限,正常该数据应该是从服务端加载而来,但是我这里简单起见,就直接定义好了,这里表示当前用户具备delete和edit权限。
const usersPermissions = ['create', 'edit'] 
const buttonCheck = {
    
    
	mounted(el,binding) {
    
    
		const {
    
     value } = binding
		// 看value提供的权限是否在usersPermissions中具备。如果有,说明当前按钮具备权限,此时应该正常显示,如果没有,说明当前按钮不具备权限,此时不应该显示。
		let f = value.some(item => {
    
    
			return usersPermissions.includes(item)
		})
		if (!f) {
    
    
			// 从父节点删除按钮
			el.parentNode && el.parentNode.removeChild(el)
		}
	}
}
export default app => {
    
    
	app.directive('buttonCheck', buttonCheck)
}

在main.js中引用并挂载
import App from './App.vue'
import directives from 'utils/directives.js'
let app =createApp(App)
directives(app)

注:自定义vue指令灵活多变,本文只是提供一种常见流程。具体逻辑可以根据具体业务需求自行定义指令。

猜你喜欢

转载自blog.csdn.net/du_aitiantian/article/details/131303117