算宽度一行等

该段代码展示了如何在 Vue 组件中实现动态列表渲染,根据屏幕空间动态显示企业信息。当企业数量过多时,会显示“等”字以指示还有未展示的公司。点击公司名称可跳转到详细页面,同时组件处理了新闻动态的链接跳转。代码中还包含了一个定时器,用于实时计算并调整公司列表的显示状态。
摘要由CSDN通过智能技术生成
<template>
  <div>
    <div v-if="showData" class="dynamic_item_wrap">
      <div @click.stop.prevent="goToNewsDetail(showData)" class="dynamic_item_box">
        <div class="title double-line-ellipsis">{{ showData.title }}</div>
        <div class="sourceAndTime">
          <div class="source">{{ showData.source_name }}</div>
          <div class="line"></div>
          <div class="timer">{{ showData.infopubl_date }}</div>
        </div>
        <div class="company_box" ref="box2">
          <div
            @click.stop.prevent="goToCompanyDetail(item)"
            v-for="(item, index) in showData.enterprise_info"
            :key="index"
            :class="`company_item company_item${itemIndex}`"
          >
            <!-- <v-icon class="icon_left" id="icon-qy-biaoqianicon-qiye"></v-icon> -->
            <img src="@/assets/image/mine/companyTag.svg" alt="" class="tag" />

            <span :class="`companyName ${showMore ? 'maxWidth1' : 'maxWidth2'}`">{{ item.name }}</span>
            <v-icon class="icon_right" id="icon-xiala-hei1x" :style="{ transform: 'rotateZ(-90deg)' }"></v-icon>
          </div>
          <span v-if="showMore" class="moreText">等</span>
        </div>
        <!-- <div class="company_box2" ref="box2">
          <div
            @click.stop.prevent="goToCompanyDetail(item)"
            v-for="(item, index) in dynamics.enterprise_info"
            :key="index"
            :class="`company_item company_item${itemIndex}`"
          >
           
            <img src="@/assets/image/mine/companyTag.svg" alt="" class="tag" />

            <span :class="`companyName ${showMore ? 'maxWidth1' : 'maxWidth2'}`">{{ item.name }}</span>
            <v-icon class="icon_right" id="icon-xiala-hei1x" :style="{ transform: 'rotateZ(-90deg)' }"></v-icon>
          </div>
          <span v-if="showMore" class="moreText">等</span>
        </div> -->
        <div class="fix_circle_max">
          <div class="fix_circle_min"></div>
        </div>
        <div class="one-line" :class="{ half: itemIndex + 1 == newListLength }"></div>
      </div>
    </div>
    <div v-else class="empty_box">近期暂无动态</div>
  </div>
</template>

<script>
  import { parseTime } from '~/assets/js/tools'
  // 公司item右margin,用于计算
  const MARGIN_RIGHT = 8
  export default {
    name: 'DynamicItem',
    data() {
      return {
        showMore: false,
        showData: [],
        time: ''
      }
    },
    props: {
      dynamics: {
        type: Object,
        default: () => {
          return {}
        }
      },
      itemIndex: [Array, Number],
      newListLength: {}
    },
    methods: {
      // 跳转新闻舆情
      goToNewsDetail(data) {
        // let url = `${data.link_address}`
        // // console.log(data.source,'source');
        // // console.log(url,'url');
        // url && window.open(url)
        let url = `${
          data.source === '新闻'
            ? `${process.env.qiyeDomain}/website-transfer/?target=${encodeURIComponent(data.link_address)}`
            : data.link_address
        }`
        url && window.open(url)
      },
      // 处理时间
      parseTime(timestamp) {
        return parseTime(timestamp, '{y}-{m}-{d}')
      },
      // 点击跳转企业详情
      goToCompanyDetail(item) {
        let pageUrl = `${process.env.qiyeDomain}/company/${item.id}.html`
        window.open(pageUrl, '_blank')
      }
    },
    mounted() {
      // this.$nextTick(() => {
      //   setTimeout(() => {
      //     console.log(this.$refs.box2.clientHeight)
      //   }, 5000)
      // })
      // window.onload=()=>{
      //   this.$$nextTick(()=>{
      //          console.log(this.$refs.box2.clientHeight)
      //   })
      // }
      // setInterval(() => {
      //   console.log(this.$refs.box2.clientHeight)
      // }, 200)
      this.time = setInterval(() => {
        // console.log(this.$refs.box2.clientHeight)
        if (this.itemIndex <= 10) {
          if (this.$refs.box2.clientHeight) {
            this.$nextTick(() => {
              // 获取最大宽度
              let parentElem = document.getElementsByClassName('company_box')?.[0]
              let maxWidth = parentElem?.offsetWidth
              // 获取item
              let companyElemList = document.getElementsByClassName(`company_item${this.itemIndex}`) || []

              let totalWidth = 0
              let resultArr = []
              this.showMore = false
              // 显隐逻辑
              if (this.showData.enterprise_info?.length > 0) {
                this.showData.enterprise_info?.forEach((item, index) => {
                  if (this.itemIndex === 6) {
                    console.log(companyElemList[index].clientWidth, '1111')
                  }

                  totalWidth += companyElemList[index]?.clientWidth + MARGIN_RIGHT
                  // console.log(maxWidth, totalWidth, index)
                  if (totalWidth < maxWidth || (totalWidth > maxWidth && index === 0)) {
                    resultArr.push(item)
                  } else {
                    this.showMore = true
                  }
                })
              }
              if (this.showMore && resultArr.length > 1) {
                // 重置total,重新计算下
                totalWidth = 0
                //   防止特殊情况,极限卡边,在加一层兜底
                resultArr.forEach((item, index) => {
                  totalWidth += companyElemList[index]?.clientWidth + MARGIN_RIGHT
                })
                if (totalWidth + MARGIN_RIGHT > maxWidth) {
                  resultArr.pop()
                }
              }
              // 更新视图
              this.$set(this.showData, 'enterprise_info', resultArr)
              clearInterval(this.time)
            })
          }
        }
      }, 200)
    },
    watch: {
      dynamics: {
        handler(val) {
          if (val) {
            if (this.$isServer) return
            // 拷贝一份做处理
            this.showData = JSON.parse(JSON.stringify(val))
            // this.showData.enterprise_info = [
            //   { name: '华为技请玩问术问有限' },
            //   { name: '华为技热恩术有限儿玩' },
            //   { name: '华为技术玩有限公问问司' },
            //   { name: '华为技问术请问有限公司' },
            //   // { name: '华为技术有限公司' },
            //   // { name: '华为技术有限公司' },
            //   // { name: '华为技术wadawd有限公司' },
            //   // { name: '格力电请问器' },
            //   // { name: '深圳市腾讯计算机系统有限公司' }
            // ]
            if (this.itemIndex <= 10) {
              return
            }
            this.$forceUpdate()
            this.$nextTick(() => {
              // 获取最大宽度
              let parentElem = document.getElementsByClassName('company_box')?.[0]
              let maxWidth = parentElem?.offsetWidth
              // 获取item
              let companyElemList = document.getElementsByClassName(`company_item${this.itemIndex}`) || []

              let totalWidth = 0
              let resultArr = []
              this.showMore = false
              // 显隐逻辑
              if (this.showData.enterprise_info?.length > 0) {
                this.showData.enterprise_info?.forEach((item, index) => {
                  if (this.itemIndex === 6) {
                    console.log(companyElemList[index].clientWidth, '1111')
                  }

                  totalWidth += companyElemList[index]?.clientWidth + MARGIN_RIGHT
                  // console.log(maxWidth, totalWidth, index)
                  if (totalWidth < maxWidth || (totalWidth > maxWidth && index === 0)) {
                    resultArr.push(item)
                  } else {
                    this.showMore = true
                  }
                })
              }
              if (this.showMore && resultArr.length > 1) {
                // 重置total,重新计算下
                totalWidth = 0
                //   防止特殊情况,极限卡边,在加一层兜底
                resultArr.forEach((item, index) => {
                  totalWidth += companyElemList[index]?.clientWidth + MARGIN_RIGHT
                })
                if (totalWidth + MARGIN_RIGHT > maxWidth) {
                  resultArr.pop()
                }
              }
              // 更新视图
              this.$set(this.showData, 'enterprise_info', resultArr)
            })
          }
        },
        immediate: true,
        deep: true
      }
    }
  }
</script>

<style lang="scss" scoped>
  .dynamic_item_warp {
    position: relative;
    overflow: hidden;
  }
  .fix_circle_max {
    position: absolute;
    top: 15px;
    left: -3px;
    width: 12px;
    height: 12px;
    background-color: #0067ff;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 2;
    .fix_circle_min {
      position: absolute;
      // top: 50%;
      // left: 50%;
      // transform: translateX(-50%);
      width: 4px;
      margin: auto;
      height: 4px;
      background-color: #fff;
      border-radius: 50%;
    }
  }
  .one-line {
    top: 15px;
    left: -2px;
    z-index: 1;
    position: absolute;
    height: 100%;
    width: 1px;
    left: 2px;
    background: #0067ff;
    &.half {
      height: 70%;
    }
  }
  .dynamic_item_box {
    position: relative;
    cursor: pointer;
    padding: 12px 0px 0px 20px;
    // background: #f6f7fb;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    &:hover {
      //   background: #ebf4ff;
    }
    .title {
      line-height: 20px;
      font-family: PingFangSC-Medium;
      font-size: 16px;
      color: #292a2d;
      letter-spacing: 0;
      font-weight: 500;
      cursor: pointer;
      margin-bottom: 10px;
      &:hover {
        color: #0067ff;
      }
    }
    .sourceAndTime {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      margin-bottom: 14px;
      font-family: PingFangSC-Medium;
      font-size: 12px;
      color: #a7a7a7;
      letter-spacing: 0;
      line-height: 16px;
      font-weight: 500;
      .source {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        letter-spacing: 0;
      }
      .line {
        width: 1px;
        height: 10px;
        background: #5e667d;
        margin: 0 10px;
      }
      .timer {
        white-space: nowrap;
        letter-spacing: 0;
      }
    }
  }
  .company_box,
  .company_box2 {
    display: flex;
    align-items: center;
    .company_item {
      background: #eff2f6;
      border-radius: 2px;
      padding: 4px 6px;
      margin-right: 8px;
      display: flex;
      justify-content: flex-start;
      align-items: center;
      &:hover {
        box-shadow: 0px 2px 4px 0px rgba(193, 220, 253, 1);
        .icon_left,
        .icon_right {
          color: rgb(57, 129, 244);
        }
        .companyName {
          color: #3981f4;
        }
      }
      .icon_right {
        font-size: 14px;
      }
      .icon_left {
        font-size: 14px;
      }
      .companyName {
        &.maxWidth1 {
          max-width: 655px;
        }
        &.maxWidth2 {
          max-width: 663px;
        }
        margin-left: 4px;
        white-space: nowrap;
        overflow: hidden;
        font-family: PingFangSC-Regular;
        font-size: 12px;
        color: #768aa5;
        letter-spacing: 0;
        line-height: 12px;
        font-weight: 400;
        text-overflow: ellipsis;
      }
    }
    .moreText {
      font-family: PingFangSC-Regular;
      font-size: 12px;
      color: #768aa5;
      letter-spacing: 0;
      font-weight: 400;
    }
  }
  .empty_box {
    // margin-left: 72px;
    padding-left: 12px;
    // transform: translateY(-20px);
    // width: 760px;
    height: 44px;
    line-height: 44px;
    background: #f1f3fb;
    border-radius: 4px;
    font-size: 14px;
    color: #5e667d;
    font-weight: 400;
  }
  .tag {
    width: 12px;
  }
</style>

up-b20b816e0015f2bfbad95e3819b91083f93.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值