首页 > 其他分享 >vue指令封装(按钮权限、loading加载、slideIn窗口进入动画)

vue指令封装(按钮权限、loading加载、slideIn窗口进入动画)

时间:2023-11-27 17:23:09浏览次数:26  
标签:el loading vue app 绑定 binding slideIn vm 指令

vue 指令

vue 本身具有一些指令,但是有些指令是 vue 作者自己写的,有些是第三方插件写的。

v-if

v-if 指令是用来控制元素是否显示的,如果值为 true,则显示,如果值为 false,则隐藏。

<div id="app">
  <p v-if="isShow">我是显示的内容</p>
  <p v-else>我是隐藏的内容</p>
</div>
<script>
  var vm = new Vue({
    el: "#app",
    data: {
      isShow: true,
    },
  });
</script>

v-for

v-for 指令是用来遍历数组或者对象,遍历的结果会被渲染到页面上。

<div id="app">
  <ul>
    <li v-for="item in list">{{item.name}}</li>
  </ul>
</div>
<script>
  var vm = new Vue();
  vm.list = [{ name: "张三" }, { name: "李四" }, { name: "王五" }];
  vm.$mount("#app");
  // vm.$mount('#app')  // 也可以写成 vm.$mount('#app'),因为vm.$mount('#app')内部也是调用了vm.$mount('#app'),所以可以写成vm.$mount('#app'),因为vm.$mount('#app')内部也是调用了vm.$mount('#app'),所以可以写成vm.$mount('#app')
</script>

v-show

v-show 指令是用来控制元素是否显示的,如果值为 true,则显示,如果值为 false,则隐藏。

<div id="app">
  <p v-show="isShow">我是显示的内容</p>
</div>
<script>
  var vm = new Vue({
    el: "#app",
    data: {
      isShow: true,
    },
  });
  // 等价于
  var vm = new Vue({
    el: "#app",
    data: {
      isShow: true,
    },
    directives: {
      show: {
        update: function (value) {
          this.el.style.display = value ? "" : "none";
        },
      },
    },
  });
</script>

v-text

v-text 指令是用来显示文本的,如果值为字符串,则显示,如果值为变量,则显示变量的值。

<div id="app">
  <p v-text="msg"></p>
</div>
<script>
  var vm = new Vue(
      {
          el: '#app',
      }
      msg: '我是文本'
  )
</script>

v-html

v-html 指令是用来显示 html 的,如果值为字符串,则显示,如果值为变量,则显示变量的值。

<div id="app">
  <p v-html="msg"></p>
</div>
<script>
  var vm = new Vue(
      {
          el: '#app',
      }
      msg: '<span style="color: red">我是文本</span>'
  )
</script>

v-bind

v-bind 指令是用来绑定元素属性的,如果值为字符串,则绑定元素的属性,如果值为变量,则绑定变量的值。

<div id="app">
  <input type="text" v-bind:value="msg" />
</div>
<script>
  var vm = new Vue(
      {
          el: '#app',
      }
      msg: '我是文本'
  )
  // 等价于
  var vm = new Vue(
      {
          el: '#app',
      }
      msg: '我是文本'
  )
</script>

v-on

v-on 指令是用来绑定元素事件的,如果值为字符串,则绑定元素的事件,如果值为变量,则绑定变量的值。

<div id="app">
  <button v-on:click="showMsg">点我</button>
</div>
<script>
  var vm = new Vue({
    el: "#app",
    methods: {
      showMsg: function () {
        alert("我是按钮");
      },
    },
  });
</script>

v-bind:class

v-bind:class 指令是用来绑定元素的 class 属性的,如果值为字符串,则绑定元素的 class 属性,如果值为变量,则绑定变量的值。

<div id="app">
  <div v-bind:class="isShow?'show' : 'hide'">
    我是显示的内容
    <span v-bind:class="isShow?'show' : 'hide'">我是隐藏的内容</span>
  </div>
</div>
<script>
  var vm = new Vue({
    el: "#app",
    data: {
      isShow: true,
    },
  });
</script>

v-model

v-model 指令是用来双向绑定表单元素的,如果值为字符串,则绑定元素的 value 属性,如果值为变量,则绑定变量的值。

<div id="app">
  <input type="text" v-model="msg" />
</div>
<script>
  var vm = new Vue();
  vm.msg = "我是文本";
  vm.$mount("#app");
</script>

v-pre

v-pre 指令是用来跳过这个元素和它的子元素的编译过程。

<div id="app">
  <p v-pre>我是文本</p>
</div>
<script>
  var vm = new Vue();
  vm.$mount("#app");
</script>

v-cloak

v-cloak 指令是用来隐藏元素直到编译完成。

<div id="app" v-cloak>
  <p>我是文本</p>
</div>
<script>
  var vm = new Vue();
  vm.$mount("#app");
</script>

v-once

v-once 指令是用来只渲染元素和它的子元素一次。

<div id="app">
  <p v-once>我是文本</p>
</div>
<script>
  var vm = new Vue();
  vm.$mount("#app");
</script>

v-pre

v-pre 指令是用来跳过这个元素和它的子元素的编译过程。

<div id="app">
  <p v-pre>我是文本</p>
</div>
<script>
  var vm = new Vue();
  vm.$mount("#app");
</script>

v-cloak

v-cloak 指令是用来隐藏元素直到编译完成。

<div id="app" v-cloak>
  <p>我是文本</p>
</div>
<script>
  var vm = new Vue();
  vm.$mount("#app");
</script>

打住,本来就是准备一个简单的介绍,不准备详细介绍这些指令,但是奈何 GPT 功能强大。@@!

自定义指令

自定义指令是一种代码重游的方式,可以将一些行为抽取出来,封装成一个指令,在元素上使用这个指令,就可以让页面上相应的行为发生变化。自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。
以下是一个简单的官方案例

选项式格式:

<template>
  <input v-focus />
</template>

<script setup>
  const focus = {
    mounted: (el) => el.focus(),
  };

  export default {
    directives: {
      // 在模板中启用 v-focus
      focus,
    },
  };
</script>

组合式格式:

<script setup>
  // 在模板中启用 v-focus
  const vFocus = {
    mounted: (el) => el.focus(),
  };
</script>

<template>
  <input v-focus />
</template>

<script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令。在上面的例子中,vFocus 即可以在模板中以 v-focus 的形式使用。在没有使用 <script setup> 的情况下,自定义指令需要通过 directives 选项注册

指令钩子

一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。

const myDirective = {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode, prevVnode) {
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件更新前调用
  beforeUpdate(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都更新后调用
  updated(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载后调用
  unmounted(el, binding, vnode, prevVnode) {},
};

这里需要注意的式指令的钩子函数,在调用时,会将当前元素、指令对象、虚拟节点、上一个虚拟节点作为参数传递给钩子函数。

指令参数

指令的参数可以是以下几种类型:

  • 字符串:如果指令的值是一个字符串,则会被当作 CSS 类名来绑定到元素上。
  • 对象:如果指令的值是一个对象,则会基于对象的值来设置元素的属性。
  • 表达式:如果指令的值是一个表达式,则会基于表达式的值来设置元素的属性。
  • 函数:如果指令的值是一个函数,则会调用该函数,并将函数的返回值作为指令的绑定值。

指令的绑定值

指令的绑定值是由指令的定义函数接收到的参数,在指令的钩子函数中,可以通过 binding.value 访问到。

const myDirective = {
  //...
  // 指令的绑定值
  bind(el, binding, vnode, prevVnode) {
    // 绑定值
    console.log(binding.value);
  },
};

指令的更新值

指令的更新值是由指令的更新函数接收到的参数,在指令的钩子函数中,可以通过 binding.value 访问到。

const myDirective = {
  //...
  // 指令的更新值
  update(el, binding, vnode, prevVnode) {
    // 更新值
    console.log(binding.value);
  },
};

指令的 oldValue

指令的 oldValue 是一个只读的属性,它的值就是指令的绑定值在上一次更新时的值。仅在beforeUpdateupdated 中可用。无论值是否更改,它都可用。

const myDirective = {
  //...
  // 指令的 oldValue
  update(el, binding, vnode, prevVnode) {
    // 更新值
    console.log(binding.value);
    if (binding.value) {
      // 指令的 oldValue
      console.log(binding.oldValue);
    }
  },
};

指令的 arg

指令的 arg 是一个只读的属性,它的值就是指令名之后的第一个冒号后面的值。
例如在 v-my-directive:foo 中,参数是 "foo"。

指令的 modifiers

指令的 modifiers 是一个只读的对象,它包含了指令名之后的所有的冒号后面的修饰符。
例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }。

const myDirective = {
  // 指令的 modifiers
  update(el, binding, vnode, prevVnode) {
    // modifiers
    console.log(binding.modifiers);
  },
};

指令的 vnode

指令的 vnode 是一个只读的对象,它包含了当前指令所绑定的虚拟节点。

const myDirective = {
  // 指令的 vnode
  update(el, binding, vnode, prevVnode) {
    // vnode
    console.log(binding.vnode);
  },
};

指令的 prevNode

指令的 prevNode 是一个只读的对象,它包含了上一个虚拟节点。代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。

const myDirective = {
  // 指令的 prevNode
  update(el, binding, vnode, prevVnode) {
    // prevNode
    console.log(binding.prevNode);
  },
};

举例来说,像下面这样使用指令:

<div v-example:foo.bar="baz"></div>

binding 参数会是一个这样的对象:

{
  arg: 'foo',
  modifiers: { bar: true },
  value: /* `baz` 的值 */,
  oldValue: /* 上一次更新时 `baz` 的值 */
}

除了 el 外,其他参数都是只读的,不要更改它们。若你需要在不同的钩子间共享信息,推荐通过元素的 dataset attribute 实现。
在指令钩子中,可以通过 el.dataset 访问到元素的 dataset attribute。

简化指令

对于自定义指令来说,一个很常见的情况是仅仅需要在 mounted 和 updated 上实现相同的行为,这样可以使得指令更加简洁。

app.directive("color", (el, binding) => {
  // 这会在 `mounted` 和 `updated` 时都调用
  el.style.color = binding.value;
});

在组件上使用指令

当在组件上使用自定义指令时,它会始终应用于组件的根节点,和透传 attributes 类似。

<div id="app">
  <my-component v-color="red"></my-component>
</div>
<!-- MyComponent 的模板 -->

<div>
  <!-- 指令会被应用在此处 -->
  <span>My component content</span>
</div>

vue 插件语法

一般我们会将指令做成 vue 插件,这样可以方便我们复用,并且可以避免一些全局变量污染。
vue 暴露出来一个扩展方法,install 方法里面可以直接添加插件。

export default {
  install(app) {
    //...
  },
};

封装按钮权限指令

app.directive("permisson", {
  mounted(el, binding) {
    if (!binding.value) return false;
    const userStore = useUserStore();
    if (!userStore.buttons.includes(binding.value)) {
      el.parentNode.removeChild(el);
    }
  },
});

封装加载动画指令

app.directive("preload", (el, binding) => {
  el.style.position = "relative";
  const vnode = h(FxLoading, {
    isShow: binding.value,
    sec: binding.arg && parseInt(binding.arg),
  });
  render(vnode, el);
});

封装窗口元素进入动画

//动画距离
const DISTANCE = 100;  、
//动画时间
const DURATION = 500;

// 动画对应关系映射
const animationMap = new WeakMap();
// 窗口监视器
const ob = new IntersectionObserver((entires) => {
  for (const entry of entires) {
    if (entry.isIntersecting) {
      animationMap.get(entry.target).play();
      ob.unobserve(entry.target);
    }
  }
});

/**
 * 判断给定的元素是否在视图范围之外
 * @param {HTMLElement} el - 要判断的元素
 * @returns {boolean} - 如果元素在视图范围之外则返回true,否则返回false
 */
function isBelowViewPort(el) {
  const rect = el.getBoundingClientRect();
  return rect.top > window.innerHeight;
}
app.directive("slideIn", {
  mounted(el) {
    setTimeout(() => {
      if (!isBelowViewPort(el)) {
        // 只有当元素在视口top值下面的时候才会触发animate
        return;
      }
      const animation = el.animate(
        [
          {
            transform: `translateY(${DISTANCE}px)`,
            opacity: 0.5,
          },
          {
            transform: `translateY(0px)`,
            opacity: 1,
          },
        ],
        {
          duration: DURATION,
          easing: "ease",
        }
      );
      animation.pause();
      animationMap.set(el, animation);
      ob.observe(el);
    }, 0);
  },
  unmounted(el) {
    ob.unobserve(el);
  },
});

标签:el,loading,vue,app,绑定,binding,slideIn,vm,指令
From: https://www.cnblogs.com/Cxymds/p/17859840.html

相关文章

  • 记录一下vue如果全局引入scss变量
    开始首先一些普通的css,可以在App.vue中引入然后项目中会经常用到一些功能型的scss,比如mixin,和函数等,这个时候在main.js和app.vue是无效的。首先查看自己的sass和sass-loader版本,注意sass-loader的安装版本,如果是v8的版本使用prependDatea,以上的版本使用additionalData(翻......
  • vue前端截图
    <template><divclass="bigbox"> <divclass="box"ref="imageTest"> <divclass="boxTop"> 13653197159邀请您注册 <spanstyle="color:#5FFFB7;">金猫矿池</span> </div>......
  • vue3使用kindeditor富文本编辑器组件,支持上传图片(接口或base64)
    参考文章:https://blog.csdn.net/qq_27936291/article/details/1247689891.安装插件npmi@zhj-target/vue3-kind-editor--save或者yarnadd@zhj-target/vue3-kind-editor2.在vue项目中使用importVue3KindEditorfrom'@zhj-target/vue3-kind-editor'conststate=re......
  • vue中的watch监听器
    方法一:当监听某一属性的变化时,建议直接使用函数写法constvm=newVue({el:'#app',data:{username:''},watch:{username(newVal,oldVal){console.log(newVal,oldVal)}}}) 方法二:当页面初始化需要监听一......
  • vue导入excel表格
    1.vue导入模版信息。进行数据操作首先要安装 npminstallfile-saver  npminstallxlsx  npminstallscript-loader,在src下面创建一个excel文件夹,查创建2个js(Blob.js,Export2Excel.js)utils/vendor/Export2Excel.js文件/*eslint-disable*/require('script-loader!f......
  • Vue-加入购物车-判断token添加登录提示
    Vue-加入购物车-判断token添加登录提示目标:给未登录的用户,添加登录提示说明:加入购物车,是一个登录后的用户才能进行的操作,所以需要进行鉴权判断,判断用户token是否存在若存在:继续加入购物车操作不存在:提示用户未登录,引导到登录页,登录完回跳addCart(){//判断token......
  • Vue中自定义组件监听事件传参
    自定义数字框组件如下<template><divclass="count-box"><button@click="handleSub"class="minus">-</button><input:value="value"@change="handleChange"class="inp"typ......
  • vue实现页面全屏、局部全屏等多方式全屏
    1、vuex创建全局变量在store/index中:importVuexfrom'vuex'Vue.use(Vuex)constuser={state:{//全屏fullscreen:false,},mutations:{//全屏SET_FULLSCREEN:(state,fullscreen)=>{state.fullscreen=fullscreen},},act......
  • 安装 Vue 开发者工具:装插件调试 Vue 应用
    (1)通过谷歌应用商店安装(国外网站)(2)极简插件:下载→ 开发者模式→ 拖拽安装 → 插件详情允许访问文件         https://chrome.zzzmh.cn/index下载的文件,解压。chrome浏览器,右上角点击-》更多工具=》扩展程序。打开开发者模式将解压的文件拖到空白区......
  • vue2跨级组件传值
    //祖先组件importSonfrom'./Son'exportdefault{components:{Son},provide(){return{money:1000000000}}}子孙组件<template> <div>  孙子组件  <p>这个是爷爷传给我的钱:{{money}}</p> </div&......