ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue-自定义属性

2021-04-01 17:04:50  阅读:181  来源: 互联网

标签:el style vue obj 自定义 binding arr let 属性


懒加载

html:

<div v-lazy>
   <div style="width: 100%;height: 99vh;background: red"></div>
   <div style="width: 100%;height: 50vh;background: orange"></div>
   <div style="width: 100%;height: 36vh;background: yellow"></div>
   <div style="width: 100%;height: 102vh;background: green"></div>
   <div style="width: 100%;height: 14vh;background: cyan"></div>
   <div style="width: 100%;height: 50vh;background: blue"></div>
   <div style="width: 100%;height: 100vh;background: purple"></div>
</div>

directive:

import Vue from 'vue'
import {Toast} from "vant";

Vue.directive("lazy", (el) => {
   let showPage = 1;// 当前展示页数
   let maxPage = 1;// 最大页数
   let arr = [];
   let mission = null;// 正在执行的加载任务

   Vue.nextTick(() => {
      let height = 0;// 累计高度
      for (let item of el.children) {
         if (height >= el.clientHeight * maxPage) maxPage++;// 当前页已放满,增加页数
         height += item.clientHeight;// 累计高度

         let obj = {pageNum:maxPage, height};
         arr.push(obj);

         if (maxPage > showPage) item.style.display = "none";// 隐藏不展示内容
      }
   })

   // 加载新内容
   let changeShowDom = () => {
      showPage++;// 增加页数
      for (let i in arr) {
         // 找到页数对应dom下标,展示对应dom
         if (arr[i].pageNum === showPage) el.children[i].style.display = "";
      }
   }

   // 滚动监听
   el.onscroll = () => {
      if (mission) return;// 阻止连续触发

      let scrollTop = el.scrollTop; // 滚动高度
      let clientHeight = el.clientHeight; //可见高度


      for (let i = arr.length - 1; i > 0; i--) {
         if (showPage === arr[i].pageNum && scrollTop + clientHeight >= arr[i].height - 30) {
            // 已滚动至当前页面底部
            Toast.loading({mask: true, duration: 1000});// 加载动画
            changeShowDom();// 加载新内容
            mission = setTimeout(() => { mission = null }, 1000);// 1秒后取消监听限制
            break;
         }
      }

      if (showPage >= maxPage) el.onscroll = null;// 全部加载完毕,关闭滚动监听
   };
})

边框

html:

<div v-border:5.t.r="'red'"></div>

directive:

import Vue from 'vue'

/**	使用方式:border:v-border:width.arr="color"
 *		width--线宽(不传默认1px)
 *		arr--画线的方位(不传默认全部)
 *		color--颜色(不传默认#eaeaea)
 */
Vue.directive("border", (el, binding) => {
   let width = binding.arg ? binding.arg : "1";// 线宽(默认1px)
   let arr = [];// 画线的方位
   let color = binding.value ? binding.value : "#eaeaea";// 颜色(默认#eaeaea)

   if (binding.modifiers.t) arr.push("borderTop");// top画线
   if (binding.modifiers.r) arr.push("borderRight"); // right画线
   if (binding.modifiers.b) arr.push("borderBottom"); // bottom画线
   if (binding.modifiers.l) arr.push("borderLeft"); // left画线
   if (JSON.stringify(binding.modifiers) === "{}") arr.push("border");// 未指定方位,默认全画

   for (let item of arr) {
      el.style[item] = `${width}px solid ${color}`;
   }
})

效果:
在这里插入图片描述

flex布局

html:

<div v-flex.jc.ac class="hp">
   <div v-border:5.t.r="'red'" style="width: 50%;height: 10rem;"></div>
</div>

directive:

import Vue from 'vue'

/** 使用方式:v-flex.xx.xx...
 * w: 换行
 * wr: 反向换行
 * rr: 水平反向布局
 * c: 垂直布局
 * cr: 垂直反向布局
 * js: X轴靠前
 * jc: X轴居中
 * je: X轴靠后
 * jb: X轴两端对齐
 * ja: X轴元素间隔对齐
 * as: Y轴靠前
 * ac: Y轴居中
 * ae: Y轴靠后
 * ab: Y轴文字对齐
 */
Vue.directive("flex", (el, binding) => {
   if (el.className.indexOf("flex") !== -1) return;
   // 添加类名
   el.className += (el.className ? " " : "") + "flex";

   // 添加样式
   if (binding.modifiers) {
      let obj = binding.modifiers;

      // flex-flow
      let wrap = obj.w ? "wrap" : (obj.wr ? "wrap-reverse" : "nowrap");// 默认:不换行/w:换行/wr:反向换行
      if (obj.rr) {
         el.style.flexFlow = `row-reverse ${wrap}`;    // 水平反向布局
      } else if (obj.c) {
         el.style.flexFlow = `column ${wrap}`;         // 垂直布局
      } else if (obj.cr) {
         el.style.flexFlow = `column-reverse ${wrap}`; // 垂直反向布局
      } else if (obj.w || obj.wr) {
         el.style.flexFlow = `row ${wrap}`;            // 水平布局
      }

      // justify-content
      if (obj.js) {
         el.style.justifyContent = "flex-start";       // 垂直布局时上对齐,水平布局时左对齐
      } else if (obj.jc) {
         el.style.justifyContent = "center";           // 居中
      } else if (obj.je) {
         el.style.justifyContent = "flex-end";         // 垂直布局时下对齐,水平布局时右对齐
      } else if (obj.jb) {
         el.style.justifyContent = "space-between";    // 两端对齐,元素之间间隔相等
      } else if (obj.ja) {
         el.style.justifyContent = "space-around";     // 元素两侧间隔相等,故元素之间的间隔比元素到边框的距离大一倍
      }

      // align-item
      if (obj.as) {
         el.style.alignItems = "flex-start";       // 垂直布局时左对齐,水平布局时上对齐
      } else if (obj.ac) {
         el.style.alignItems = "center";           // 居中
      } else if (obj.ae) {
         el.style.alignItems = "flex-end";         // 垂直布局时右对齐,水平布局时下对齐
      } else if (obj.ab) {
         el.style.alignItems = "baseline";         // 元素的第一行文字的基线对齐。
      }
   }
})

效果:
在这里插入图片描述

元素隐藏

html

<div v-hide></div>

directive

import Vue from 'vue'

// 使用方式:v-hide="boolean"(不传默认隐藏)
Vue.directive("hide", (el, binding) => {
   let flag = binding.value === undefined ? true : binding.value;
   el.style.display = flag ? "none" : "";
})

标签:el,style,vue,obj,自定义,binding,arr,let,属性
来源: https://blog.csdn.net/qweqwe2277/article/details/115374726

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有