vue自定义指令_按钮权限设计(从0创建项目开始设计)

vue自定义指令设计

背景

阅读若依前端低代码看见v-permission时去了解vue的directive自定义指令时发现,可注入属性,有点像v-bind的用法。

官方参考文档:cn.vuejs.org/guide/reusa...

新建一个vue项目(webpack 模板)

使用vue的webpack模板创建一个项目

bash 复制代码
# vue init webpack yma16-study

进入目录运行项目

bash 复制代码
# cd yma16-study
# npm run dev

安装elementui方便使用ui样式验证自定义指令

bash 复制代码
# npm i element-ui -S

写一个自定义的指令(v-yma16)

用法介绍

一个自定义指令由一个包含类似组件生命周期钩子的对象来定义

vue2的安装方式

javascript 复制代码
import Vue from 'vue'
// 使 v-focus 在所有组件中都可用
Vue.directive('focus', {
  /* ... */
})

指令的钩子会传递以下几种参数:

  • el:指令绑定到的元素。这可以用于直接操作 DOM。
  • binding:一个对象,包含以下属性。
  • value:传递给指令的值。例如在 v-my-directive="1 + 1" 中,值是 2。
  • oldValue:之前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否更改,它都可用。
  • arg:传递给指令的参数 (如果有的话)。例如在 v-my-directive:foo 中,参数是 "foo"。
  • modifiers:一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }。
  • instance:使用该指令的组件实例。
  • dir:指令的定义对象。
  • vnode:代表绑定元素的底层 VNode。
  • prevNode:之前的渲染中代表指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。
自定义显示和不显示的自定义指令

设计v-yma16Auth显示,v-yma16UnAuth不显示

在插入inserted的生命周期触发

javascript 复制代码
const authConfig = {
  isAuthor: true
}
const unAuthConfig = {
  isAuthor: false
}
const yma16Auth = {
  inserted (el, binding, vnode) {
    const { value } = binding
    console.log('value', value)
    console.log('binding', binding)
    // 未授权 移除节点
    if (!authConfig.isAuthor) {
      el.parentNode && el.parentNode.removeChild(el)
    }
  }
}
const yma16UnAuth = {
  inserted (el, binding, vnode) {
    const { value } = binding
    console.log('value', value)
    console.log('binding', binding)
    // 未授权 移除节点
    if (!unAuthConfig.isAuthor) {
      el.parentNode && el.parentNode.removeChild(el)
    }
  }
}

export {authConfig, yma16Auth, yma16UnAuth, unAuthConfig}

main.js入口

javascript 复制代码
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import {authConfig, yma16Auth, yma16UnAuth, unAuthConfig} from './desing-directive'

// 自定义 yma16指令
Vue.directive('yma16Auth', yma16Auth)
Vue.directive('yma16UnAuth', yma16UnAuth)
Vue.prototype.authConfig = authConfig
Vue.prototype.unAuthConfig = unAuthConfig

Vue.config.productionTip = false
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
效果

v-yma16Auth显示,v-yma16UnAuth不显示

使用bind配合自定义directive指令控制按钮的显示隐藏

binding的值调整显示隐藏

javascript 复制代码
const yma16Auth = {
  inserted (el, binding, vnode) {
    const { value } = binding
    console.log(binding)
    console.log(el)
    const {visible} = value
    // visible false 移除节点
    if (!visible) {
      console.log('remove', el)
      el.parentNode && el.parentNode.removeChild(el)
    }
  }
}

视图层

javascript 复制代码
<template>
  <div class="container">
    <h1>{{ msg }}</h1>
    <el-switch
      v-model="yma16Auth.visible"
      active-text="显示"
      inactive-text="隐藏"
    >
    </el-switch>
      <div>

        <el-button type="primary" @click="reRenderBtn" style="margin:10px 0">
          重新强制渲染
        </el-button>
      </div>
    <div>
       <span style="margin:10px 0">
        授权显示的按钮 v-yma16Auth
      </span>
    </div>
      <div v-if="refreshBtn">
        <el-button v-yma16Auth="yma16Auth" type="primary" :visiable="yma16Auth.visible">
          v-yma16Auth
        </el-button>
      </div>
  </div>
</template>

<script>
export default {
  name: 'Index',
  data () {
    return {
      msg: '自定义指令 directive',
      yma16Auth: {
        visible: true,
        value: false
      },
      refreshBtn: true
    }
  },
  methods: {
    reRenderBtn () {
      // this.$forceUpdate()
      console.log('yma16Auth', this.yma16Auth)
      this.refreshBtn = false
      setTimeout(() => { this.refreshBtn = true }, 500)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
效果

隐藏

显示

结尾

结束,感谢阅读,如有不足欢迎指出问题!

相关推荐
森叶7 分钟前
Electron 安装包 asar 解压定位问题实战
前端·javascript·electron
深情废杨杨23 分钟前
前端vue-插值表达式和v-html的区别
前端·javascript·vue.js
GHUIJS24 分钟前
【vue3】vue3.3新特性真香
前端·javascript·vue.js
众生回避30 分钟前
鸿蒙ms参考
前端·javascript·vue.js
笃励1 小时前
Angular面试题五
javascript·ecmascript·angular.js
GHUIJS1 小时前
【vue3】vue3.5
前端·javascript·vue.js
-seventy-1 小时前
对 JavaScript 原型的理解
javascript·原型
秋沐2 小时前
vue中的slot插槽,彻底搞懂及使用
前端·javascript·vue.js
QGC二次开发3 小时前
Vue3 : Pinia的性质与作用
前端·javascript·vue.js·typescript·前端框架·vue
子非鱼9214 小时前
【前端】ES6:Set与Map
前端·javascript·es6