code

vue 拖拽

<template>
  <transition-group tag="div" class="container">
    <div
      class="item"
      v-for="(item) in items"
      :key="item.key"
      :style="{background:item.color,width:'80px',height:'80px',}"
      draggable="true"
      @dragstart="handleDragStart($event, item)"
      @dragover.prevent="handleDragOver($event, item)"
      @dragenter="handleDragEnter($event, item)"
      @dragend="handleDragEnd($event, item)"
    ></div>
  </transition-group>
</template>

<script>
export default {
  name: "Toolbar",
  data() {
    return {
      items: JSON.parse(localStorage.getItem('list')) || [
        { key: 1, color: "red" },
        { key: 2, color: "yellow" },
        { key: 3, color: "green" }
      ],
      dragging: null
    };
  },
  methods: {
    handleDragStart(e, item) {
      this.dragging = item;
    },
    handleDragEnd(e, item) {
      this.dragging = null;
    },
    //首先把div变成可以放置的元素,即重写dragenter/dragover
    handleDragOver(e) {
      e.dataTransfer.dropEffect = "move"; // e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
    },
    handleDragEnter(e, item) {
      e.dataTransfer.effectAllowed = "move"; //为需要移动的元素设置dragstart事件
      if (item === this.dragging) {
        return;
      }
      const newItems = [...this.items];
      console.log(newItems);
      const src = newItems.indexOf(this.dragging);
      const dst = newItems.indexOf(item);
      newItems.splice(dst, 0, ...newItems.splice(src, 1));
      this.items = newItems;
      localStorage.setItem('list', JSON.stringify(newItems))
    }
  },
  created() {
    console.log(localStorage.getItem('list'))
  }
};
</script>

<style scoped>
.container {
  width: 80px;
  height: 300px;
  position: absolute;
  left: 0;
  display: flex;
  flex-direction: column;
  padding: 0;
}
.item {
  margin-top: 10px;
  transition: all linear 0.3s;
}
</style>

vue el-dialog 拖拽 directives 指令

<template>
  <div>
    <el-button type="primary" @click="dialogVisible = true">主要按钮</el-button>
    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
      v-dialogDrag
      width="30%"
      :close-on-click-modal="false">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        dialogVisible: false
      };
    }
  };
</script>

// 在 utils 中新建 directives.js 文件
import Vue from 'vue'

// v-dialogDrag: 弹窗拖拽
Vue.directive('dialogDrag', {
  bind(el, binding, vnode, oldVnode) {
    const dialogHeaderEl = el.querySelector('.el-dialog__header')
    const dragDom = el.querySelector('.el-dialog')
    dialogHeaderEl.style.cursor = 'move'

    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)

    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft
      const disY = e.clientY - dialogHeaderEl.offsetTop

      // 获取到的值带px 正则匹配替换
      let styL, styT

      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if (sty.left.includes('%')) {
        styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
        styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
      } else {
        styL = +sty.left.replace(/\px/g, '')
        styT = +sty.top.replace(/\px/g, '')
      }

      document.onmousemove = function(e) {
        // 通过事件委托,计算移动的距离
        const l = e.clientX - disX
        const t = e.clientY - disY

        // 移动当前元素
        dragDom.style.left = `${l + styL}px`
        dragDom.style.top = `${t + styT}px`

        // 将此时的位置传出去
        // binding.value({x:e.pageX,y:e.pageY})
      }

      document.onmouseup = function(e) {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
})

// v-dialogDragWidth: 弹窗宽度拖大 拖小
Vue.directive('dialogDragWidth', {
  bind(el, binding, vnode, oldVnode) {
    const dragDom = binding.value.$el.querySelector('.el-dialog')

    el.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - el.offsetLeft

      document.onmousemove = function(e) {
        e.preventDefault() // 移动时禁用默认事件

        // 通过事件委托,计算移动的距离
        const l = e.clientX - disX
        dragDom.style.width = `${l}px`
      }

      document.onmouseup = function(e) {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
})

// main.js中导入:import './utils/directives.js'

// 使用 el-dialog 的地方加入 v-dialogDrag

vue中实现超过两行显示展开,点击隐藏

<template>
  <div class="view">
    <div class="text more" ref="more">
      占位
    </div>
    <div class="content" v-for="(item, index) in curData" :key="index">
      <div class="text">
        <div :class="{'retract': item.status}" :style="{'max-height':item.status ? textHeight: ''}" ref="textContainer">
          {{item.desc}}
        </div>
        <div class="btn">
          <p v-if="item.status" @click="item.status = false">展开</p>
          <p v-if="item.status == false" @click="item.status = true">收起</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        curData: [
          { desc: '人物、情节、环境是小说的三要素。情节一般包括开端、发展、高潮、结局四部分,有的包括序幕、尾声。环境包括自然环境和社会环境。 小说按照篇幅及容量可分为长篇、中篇、短篇和微型小说(小小说)。按照表现的内容可分为神话、仙侠、武侠、科幻、悬疑、古传、当代、浪漫青春、游戏竞技等。按照体制可分为章回体小说、日记体小说、书信体小说、自传体小说。按照语言形式可分为文言小说和白话小说。' },
          { desc: '小说刻画人物的方法:心理描写、动作描写、语言描写、外貌描写、神态描写。' },
        ],
        textHeight: null
      }
    },
    methods: {
      // 计算文字 显示展开 收起
      calculateText() {
        // 获取一行文字的height 计算当前文字比较列表文字
        let oneHeight = this.$refs.more.scrollHeight
        let twoHeight = oneHeight * 2 || 40
        this.textHeight = `${twoHeight}px`
        let txtDom = this.$refs.textContainer
        for (let i = 0; i < txtDom.length; i++) {
          let curHeight = txtDom[i].offsetHeight
          if (curHeight > twoHeight) {
            this.$set(this.curData, i, Object.assign({}, this.curData[i], { status: true }))
          } else {
            this.$set(this.curData, i, Object.assign({}, this.curData[i], { status: null }))
          }
        }
      }
    },
    mounted() {
      this.curData.forEach((ele, index) => {
        this.$set(this.curData, index, Object.assign({}, ele, { status: null }))
      })
      // DOM 加载完执行
      this.$nextTick(() => {
        this.calculateText()
      })

      window.onresize = () => {
        this.curData.forEach((ele, index) => {
          this.$set(this.curData, index, Object.assign({}, ele, { status: null }))
        })
        setTimeout(() => {
          this.calculateText()
        }, 0)
      }
    },
    destroyed(){
      window.onresize = null;
    }
  };
</script>

<style>
  .content {
    display: flex;
    margin-bottom: 30px;
  }

  .text {
    position: relative;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 2px;
    color: #666666;
    text-align: justify;
  }

  .retract {
    position: relative;
    overflow: hidden;
    background: #fff;
  }

  .retract:after {
    content: '...';
    position: absolute;
    bottom: 0;
    right: 2px;
    width: 25px;
    padding-left: 5px;
    padding-right: 30px;
    background: linear-gradient(to right, transparent, #fff 0);
  }

  .btn {
    position: absolute;
    right: 0;
    bottom: 0;
    font-size: 14px;
    line-height: 19px;
    letter-spacing: 2px;
    color: #FFAD41;
    cursor: pointer;
  }
  p {
    margin: 0;
  }
  .more {
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 2px;
    color: #666666;
    visibility: hidden;
  }
</style>

基于vue实现头部上划显示下滑消失功能

<template>
  <div class="about">
    <div class="a-header" :class="['header--'+(isTopbarBlock ? 'show' : 'hidden')]">
      <div class="header-top"></div>
      <div class="header-bottom"></div>
    </div>
    <div class="a-main"></div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        isTopbarBlock: true
      }
    },
    mounted() {
      let scrollingElement = document.scrollingElement
      let scrollTop = 0
      let that = this
      window.addEventListener('scroll', () => {
        if (scrollingElement.scrollTop < 300) {
          that.isTopbarBlock = true
          return
        }
        if (scrollingElement.scrollTop > scrollTop) {
          that.isTopbarBlock = false
        } else if (scrollingElement.scrollTop < scrollTop) {
          that.isTopbarBlock = true
        }
        scrollTop = scrollingElement.scrollTop
      })
    },
  }
</script>

<style lang="scss" scoped>
.about {
  .a-header {
    width: 100%;
    height: 160px;
    position: fixed;
    top: 0;
    left: 0;
    transition: all .2s;
    .header-top {
      width: 100%;
      height: 100px;
      background: yellow;
    }
    .header-bottom {
      width: 100%;
      height: 60px;
      background: green;
    }
  }
  .header--show{
    transform: translateY(0);
    transition: all 1.2s;
  }
  .header--hidden{
    transform: translateY(-100px);
    transition: all 1.2s;
  }
  .a-main {
    height: 5000px;
    background: rgba(0,0,0,.5);
  }
}
</style>


console.log

// log.js
const log = {};

/**
 * @description 返回这个样式的颜色值
 * @param {String} type 样式名称 [ primary | success | warning | danger | text ]
 */
function typeColor(type = "default") {
  let color = "";
  switch (type) {
    case "default":
      color = "#303133";
      break;
    case "primary":
      color = "#409EFF";
      break;
    case "success":
      color = "#67C23A";
      break;
    case "warning":
      color = "#E6A23C";
      break;
    case "danger":
      color = "#F56C6C";
      break;
    default:
      break;
  }
  return color;
}

/**
 * @description 打印一个 [ title | text ] 样式的信息
 * @param {String} title title text
 * @param {String} info info text
 * @param {String} type style
 */
log.capsule = function(title, info, type = "primary") {
  console.log(
    `%c ${title} %c ${info} %c`,
    "background:#35495E; padding: 1px; border-radius: 3px 0 0 3px; color: #fff;",
    `background:${typeColor(
      type
    )}; padding: 1px; border-radius: 0 3px 3px 0;  color: #fff;`,
    "background:transparent"
  );
};

/**
 * @description 打印彩色文字
 */
log.colorful = function(textArr) {
  console.log(
    `%c${textArr.map((t) => t.text || "").join("%c")}`,
    ...textArr.map((t) => `color: ${typeColor(t.type)};`)
  );
};

log.default = function(text) {
  log.colorful([{ text }]);
};

log.primary = function(text) {
  log.colorful([{ text, type: "primary" }]);
};

log.success = function(text) {
  log.colorful([{ text, type: "success" }]);
};

log.warning = function(text) {
  log.colorful([{ text, type: "warning" }]);
};

log.danger = function(text) {
  log.colorful([{ text, type: "danger" }]);
};

export default log;

// home.js
log.default(">>> 我是一些默认提示");
log.primary(">>> 我是一些标记提示");
log.success(">>> 我是一些成功提示");
log.warning(">>> 我是一些警告提示");
log.danger(">>> 我是一些错误提示");

瀑布流

<template>
  <div class="waterfall">
    <div class="waterfall-left">
      <div
        class="waterfall-left-item"
        v-for="(item, index) in waterLeft"
        :key="index"
      >
        {{ item.content }}
      </div>
    </div>
    <div class="waterfall-right">
      <div
        class="waterfall-right-item"
        v-for="(ele, index) in waterRight"
        :key="index"
      >
        {{ ele.content }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      waterInfo: [
        {
          content:
            "世间有千万种相遇,而有种遇见叫做一见倾心,红尘中惊鸿的一瞥,你便凝眸在我内心深处,而我为这一眼就开始为你步步沦陷,只想有你温暖的陪伴别无它求,弱水三千取一瓢饮,只想独享你的世界,安静品读。守一份承诺细诉着爱恋,步入你温暖的城池,人的一生有诸多的美好,而我情有独钟的是与你相濡以沫。",
        },
        {
          content:
            "如果你的征途上有暴风雨,我愿把思念化作细丝,织成一把密密的友谊伞,让我们在暴风雨中走向胜境!",
        },
        {
          content:
            "只是因为在人群中多看了你一眼,使我忘不了你容颜,你可知弦断的哀鸣?为你种情盅爱毒,受尽辗转轮回。你若如知弦鸣的悲凉,那手指余温可否换一世相守,且不问前世转身,且不诉前世别离,任它人间花如雨,平生至爱你一人。默然,相爱。寂静,欢喜。",
        },
        { content: "就让我们一直走下去,直到世界一片纯白。" },
        { content: "我醒了,想看看天上飘着的是,云做的雨还是雪做的云。" },
        {
          content:
            "是谁,卷起秋风那无奈的萧瑟?是谁,在落花的泥土里浸染了无限的深情?是谁,点亮秋雨如针如丝的光芒?在秋雨深处,嗅到了寒凉的味道,让感觉缠绕丝丝缕缕秋的絮语。",
        },
        { content: "时光的洪流中,我们总会长大。" },
        {
          content:
            "飞机场的骚乱一会儿就停止了,这里的人都是有着自己的方向的,匆匆地起飞,匆匆地下降,带走别人的故事,留下自己的回忆。",
        },
        {
          content:
            "和善良对峙的,不一定只是邪恶。可能也是残酷。和理想对峙的,不一定只是世俗。可能也是天真。",
        },
        {
          content:
            "世间有千万种相遇,而有种遇见叫做一见倾心,红尘中惊鸿的一瞥,你便凝眸在我内心深处,而我为这一眼就开始为你步步沦陷,只想有你温暖的陪伴别无它求,弱水三千取一瓢饮,只想独享你的世界,安静品读。守一份承诺细诉着爱恋,步入你温暖的城池,人的一生有诸多的美好,而我情有独钟的是与你相濡以沫。",
        },
        {
          content:
            "如果你的征途上有暴风雨,我愿把思念化作细丝,织成一把密密的友谊伞,让我们在暴风雨中走向胜境!",
        },
        {
          content:
            "只是因为在人群中多看了你一眼,使我忘不了你容颜,你可知弦断的哀鸣?为你种情盅爱毒,受尽辗转轮回。你若如知弦鸣的悲凉,那手指余温可否换一世相守,且不问前世转身,且不诉前世别离,任它人间花如雨,平生至爱你一人。默然,相爱。寂静,欢喜。",
        },
        { content: "就让我们一直走下去,直到世界一片纯白。" },
        { content: "我醒了,想看看天上飘着的是,云做的雨还是雪做的云。" },
        {
          content:
            "是谁,卷起秋风那无奈的萧瑟?是谁,在落花的泥土里浸染了无限的深情?是谁,点亮秋雨如针如丝的光芒?在秋雨深处,嗅到了寒凉的味道,让感觉缠绕丝丝缕缕秋的絮语。",
        },
        { content: "时光的洪流中,我们总会长大。" },
        {
          content:
            "飞机场的骚乱一会儿就停止了,这里的人都是有着自己的方向的,匆匆地起飞,匆匆地下降,带走别人的故事,留下自己的回忆。",
        },
        {
          content:
            "和善良对峙的,不一定只是邪恶。可能也是残酷。和理想对峙的,不一定只是世俗。可能也是天真。",
        },
      ],
      waterLeft: [],
      waterRight: [],
    };
  },
  mounted() {
    this.getData();
  },
  methods: {
    getData() {
      this.waterInfo.forEach((item, index) => {
        if (index % 2 == 0) {
          this.waterLeft.push(item);
        } else {
          this.waterRight.push(item);
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.waterfall {
  width: 100%;
  height: 100%;
  overflow: auto;
  display: flex;
  flex-wrap: nowrap;
}

.waterfall-left,
.waterfall-right {
  width: 50%;
  height: 100%;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}

.waterfall-left-item,
.waterfall-right-item {
  width: 100%;
  height: auto;
  padding: 20px;
  font-size: 14px;
  margin-bottom: 20px;
}
</style>

点击

<script>
  !(function (e, t, a) {
    function n() {
      c(
        ".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"
      ),
        o(),
        r();
    }
    function r() {
      for (var e = 0; e < d.length; e++)
        d[e].alpha <= 0
          ? (t.body.removeChild(d[e].el), d.splice(e, 1))
          : (d[e].y--,
            (d[e].scale += 0.004),
            (d[e].alpha -= 0.013),
            (d[e].el.style.cssText =
              "left:" +
              d[e].x +
              "px;top:" +
              d[e].y +
              "px;opacity:" +
              d[e].alpha +
              ";transform:scale(" +
              d[e].scale +
              "," +
              d[e].scale +
              ") rotate(45deg);background:" +
              d[e].color +
              ";z-index:99999"));
      requestAnimationFrame(r);
    }
    function o() {
      var t = "function" == typeof e.onclick && e.onclick;
      e.onclick = function (e) {
        t && t(), i(e);
      };
    }
    function i(e) {
      var a = t.createElement("div");
      (a.className = "heart"),
        d.push({
          el: a,
          x: e.clientX - 5,
          y: e.clientY - 5,
          scale: 1,
          alpha: 1,
          color: s(),
        }),
        t.body.appendChild(a);
    }
    function c(e) {
      var a = t.createElement("style");
      a.type = "text/css";
      try {
        a.appendChild(t.createTextNode(e));
      } catch (t) {
        a.styleSheet.cssText = e;
      }
      t.getElementsByTagName("head")[0].appendChild(a);
    }
    function s() {
      return (
        "rgb(" +
        ~~(255 * Math.random()) +
        "," +
        ~~(255 * Math.random()) +
        "," +
        ~~(255 * Math.random()) +
        ")"
      );
    }
    var d = [];
    (e.requestAnimationFrame = (function () {
      return (
        e.requestAnimationFrame ||
        e.webkitRequestAnimationFrame ||
        e.mozRequestAnimationFrame ||
        e.oRequestAnimationFrame ||
        e.msRequestAnimationFrame ||
        function (e) {
          setTimeout(e, 1e3 / 60);
        }
      );
    })()),
      n();
  })(window, document);
</script>

posted @   7c89  阅读(69)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示