vue实现标签云,让你的标签动起来

一起探讨学习

欢迎大家进群,一起讨论学习

每天给大家提供技术干货

在这里插入图片描述

博主技术笔记 https://notes.xiyankt.com


博主开源微服架构前后端分离技术博客项目源码地址,欢迎各位star https://gitee.com/bright-boy/xiyan-blog


vue实现标签云,让你的标签动起来

npm包地址 https://www.npmjs.com/package/bright-tag

项目介绍

Vue标签云UI组件

安装教程
  1. npm i bright-tag
  2. 在main.js中
import tagCloud from 'bright-tag'
Vue.use(tagCloud)
使用说明

props

  1. data

Object数组。name属性是显示的标签名,其他自行扩展。

  1. config

Object对象,配置项。有下面几个参数:

参数默认值说明
radius120滚动半径,Number,单位px
maxFont24最大字体大小
colornull字体颜色。为null时随机
rotateAngleXbase600X方向旋转速度基数,数越小速度越快
rotateAngleYbase600Y方向旋转速度基数,数越小速度越快

方法

方法名参数说明
clickTagtag点击标签的方法。返回整个标签

调用用例

<!-- template -->
<tag-cloud :data="hotTag" @clickTag="clickTagItem"></tag-cloud>
// Vue实例
export default {
  data () {
    return {
      hotTag: [{"id":"05023f8da31c4b4187cc6899e2a3aec2","name":"镇远县"},{"id":"0ef028e5278f4f5ca31f99f1bd22b1cc","name":"剑河县"},{"id":"1a32ef04d3c548eaa6777abb46da32f2","name":"台江县"},{"id":"2c26488325bd493687d16315fe0e5fdd","name":"岑巩县"},{"id":"3a786111828a4b9f89ae9da25753eedd","name":"黎平"},{"id":"4ed593eed91b4244969995237f5c96c5","name":"丹寨县"},{"id":"615d2c178f1a47cb8d473823e74f5386","name":"凯里市"},{"id":"76f652df03db43349272a9aff492b065","name":"榕江县"},{"id":"8ff29d0d35e548feb945063b34ed9c9b","name":"黄平县"},{"id":"a8ac2170008746fdadc05ea461bc5e37","name":"雷山县"}]
    }
  },
  methods: {
    clickTagItem (tag) {
      // TODO
    }
  }
}

在这里插入图片描述

以下是源码解析

<template>
  <div class="tag-wall"        <div class="tag-cloud" ref="wrapper">
          <p
            v-for="(item, index) in data"
            :key="index"
            ref="tag"
            @click="clickTag(item)"
            @dblclick="dbclickTag(item)"
          >
            {{ item.name }}
          </p>
      </div>
  </div>
</template>

<script>

export default {
  data() {
    return {
      data: [
        { id: "05023f8da31c4b4187cc6899e2a3aec2", name: "镇远县" },
        { id: "0ef028e5278f4f5ca31f99f1bd22b1cc", name: "剑河县" },
        { id: "1a32ef04d3c548eaa6777abb46da32f2", name: "台江县" },
        { id: "2c26488325bd493687d16315fe0e5fdd", name: "岑巩县" },
        { id: "3a786111828a4b9f89ae9da25753eedd", name: "黎平" },
        { id: "4ed593eed91b4244969995237f5c96c5", name: "丹寨县" },
        { id: "615d2c178f1a47cb8d473823e74f5386", name: "凯里市" },
        { id: "76f652df03db43349272a9aff492b065", name: "榕江县" },
        { id: "8ff29d0d35e548feb945063b34ed9c9b", name: "黄平县" },
        { id: "a8ac2170008746fdadc05ea461bc5e37", name: "雷山县" },
      ],
      option: {
        radius: 140, // 滚动半径,单位px
        maxFont: 24, // 最大字体大小
        color: null, // 字体颜色。为空时随机
        rotateAngleXbase: 600, // 默认旋转速度基数,数越小速度越快
        rotateAngleYbase: 600,
      },
      tagList: [],
    };
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null;
    }
  },
  watch: {
    data() {
      this.$nextTick(() => {
        this._initTags();
      });
    },
  },
  mounted() {
    this._initTags();
  },
  created() {
    this.listTag();
    if (this.config != null) {
      this.option = Object.assign({}, this.option, this.config);
    }
  },
  methods: {
    _initTags() {
      this.rotateAngleX = Math.PI / this.option.rotateAngleXbase;
      this.rotateAngleY = Math.PI / this.option.rotateAngleYbase;

      for (var i = 0, length = this.data.length; i < length; i++) {
        // 获取球面上均匀的点的经纬度 θ = arccos( ((2*num)-1)/all - 1); Φ = θ*sqrt(all * π);
        let angleX = Math.acos((2 * (i + 1) - 1) / length - 1);
        let angleY = angleX * Math.sqrt(length * Math.PI);
        // 根据经纬度获取点的坐标,球中心的点坐标是 (0,0,0) x=r*sinθ*cosΦ   y=r*sinθ*sinΦ   z=r*cosθ;
        const x = this.option.radius * Math.sin(angleX) * Math.cos(angleY);
        const y = this.option.radius * Math.sin(angleX) * Math.sin(angleY);
        const z = this.option.radius * Math.cos(angleX);
        if (this.option.color) {
          this.$refs.tag[i].style.color = this.option.color;
        } else {
          // 随机颜色
          this.$refs.tag[i].style.color =
            "rgb(" +
            Math.round(255 * Math.random()) +
            "," +
            Math.round(255 * Math.random()) +
            "," +
            Math.round(255 * Math.random()) +
            ")";
        }
        // 每个标签对象都有四对值
        var tag = {
          x: x,
          y: y,
          z: z,
          ele: this.$refs.tag[i],
        };
        this.tagList.push(tag);
      }
      const _self = this;
      const datas = _self.tagList;
      this.timer = setInterval(function () {
        for (var i = 0; i < datas.length; i++) {
          _self.rotateX(datas[i]);
          _self.rotateY(datas[i]);
          _self.setPosition(
            datas[i],
            _self.option.radius,
            _self.option.maxFont
          );
        }
      }, 20);
    },
    setPosition(tag, r, maxFont) {
      // 设置每个标签的坐标位置和字体大小以及透明度
      if (this.$refs.wrapper) {
        tag.ele.style.transform =
          "translate(" +
          (tag.x +
            this.$refs.wrapper.offsetWidth / 2 -
            tag.ele.offsetWidth / 2) +
          "px," +
          (tag.y +
            this.$refs.wrapper.offsetHeight / 2 -
            tag.ele.offsetHeight / 2) +
          "px)";
        tag.ele.style.opacity = tag.z / r / 2 + 0.7;
        tag.ele.style.fontSize = (tag.z / r / 2 + 0.5) * maxFont + "px";
      }
    },
    rotateX(tag) {
      var cos = Math.cos(this.rotateAngleX);
      var sin = Math.sin(this.rotateAngleX);
      var y1 = tag.y * cos - tag.z * sin;
      var z1 = tag.y * sin + tag.z * cos;
      tag.y = y1;
      tag.z = z1;
    },
    rotateY(tag) {
      var cos = Math.cos(this.rotateAngleY);
      var sin = Math.sin(this.rotateAngleY);
      var x1 = tag.z * sin + tag.x * cos;
      var z1 = tag.z * cos - tag.x * sin;
      tag.x = x1;
      tag.z = z1;
    },
    dbclickTag() {
      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      } else {
        const _self = this;
        this.timer = setInterval(function () {
          for (var i = 0; i < _self.tagList.length; i++) {
            _self.rotateX(_self.tagList[i]);
            _self.rotateY(_self.tagList[i]);
            _self.setPosition(
              _self.tagList[i],
              _self.option.radius,
              _self.option.maxFont
            );
          }
        }, 20);
      }
    },
    clickTag(item) {
      this.$emit("clickTag", item);
    },
  },
};
</script>

<style scoped>
.tag-cloud {
  width: 300px;
  height: 300px;
  position: relative;
  color: #333;
  margin: 0 auto;
  text-align: center;
}

.tag-cloud p {
  position: absolute;
  top: 0px;
  left: 0px;
  color: #333;
  font-family: Arial;
  text-decoration: none;
  margin: 0 10px 15px 0;
  line-height: 18px;
  text-align: center;
  font-size: 16px;
  padding: 4px 9px;
  display: inline-block;
  border-radius: 3px;
}
.tag-cloud p:hover {
  cursor: pointer;
}
</style>

各位老板关注下

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Vue态给 iframe 元素的 src 属性赋值可以通过以下几种方式实现: 1. 使用 Vue 的数据绑定 在 Vue 组件的 template 中使用数据绑定的方式,将 iframe 的 src 属性与组件中的某个变量绑定起来,当变量的值发生变化时,iframe 的 src 属性也会相应地更新。 例如: ``` <template> <div> <iframe :src="url"></iframe> </div> </template> <script> export default { data() { return { url: 'http://www.example.com' } }, methods: { changeUrl() { this.url = 'http://www.google.com' } } } </script> ``` 2. 使用 ref 获取 iframe 元素 在 Vue 组件中使用 ref 获取 iframe 元素,然后通过 JavaScript 态修改 iframe 的 src 属性。 例如: ``` <template> <div> <iframe ref="myiframe"></iframe> </div> </template> <script> export default { mounted() { this.$refs.myiframe.src = 'http://www.example.com' }, methods: { changeUrl() { this.$refs.myiframe.src = 'http://www.google.com' } } } </script> ``` 注意:使用 ref 获取元素需要在 mounted 钩子函数中,因为只有在挂载后才能获取到元素。 3. 使用 v-if 和 v-bind:key 态创建和销毁 iframe 元素 在 Vue 组件中使用 v-if 和 v-bind:key 态创建和销毁 iframe 元素,并根据数据来态设置 iframe 的 src 属性。 例如: ``` <template> <div> <iframe v-if="show" :src="url" :key="url"></iframe> </div> </template> <script> export default { data() { return { show: true, url: 'http://www.example.com' } }, methods: { changeUrl() { this.url = 'http://www.google.com' } } } </script> ``` 当 show 值为 true 时,会态创建一个带有指定 src 属性的 iframe 元素;当 show 值为 false 时,会销毁 iframe 元素。当 url 值发生变化时,根据 v-bind:key 的值重新创建 iframe 元素并更新 src 属性。 以上就是在 Vue态给 iframe 元素赋值的几种方法,可以根据具体的需求选择适合的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘明同学呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值