vue3评论和回复代码

没有写后端,但是这也是一种思路,只不过有些复杂,我也晕晕的,但是写代码主要是看别人写代码的思路,所以没有后端应该也不影响(vue3+tailwindcss),用到了组件交互

这里样式是仿着b站动态写的

五个组件:

1、第一个:就是帖子区

2、第二个:评论区:发一级评论

3、第三个:一级评论:一级评论的展示和发二级评论,把二级和三级都镶嵌到了这里,对二级的判断就是有没有children,对三级的判断类似

4、第四个:二级评论:二级评论的展示和发三级评论

5、第五个:三级评论(三级及以上统称三级):三级评论的展示(递归,也是类似判断)

这有个例子解释一二三级评论

<script setup lang="ts">
import { ref } from 'vue';
import CommentParent from '@/components/form/CommentParent.vue';
function updateIsExpanded(item){
  item.isExpanded = !item.isExpanded;
}
const selectedCategory = ref('全部');
const list = ref([
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '小伙伴们,我们这也是好起来了,和奥运冠军一起吃上饭了',
    content: '小伙伴们,我们这也是好起来了,和奥运冠军一起吃上饭了',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '【欧气宝箱新品】\n' +
      '软软糯糯的miku玉桂狗团子٩(๑˃̵ᴗ˂̵๑)۶\n' +
      '\n' +
      '⭐MAX LIMI TED VOCALOID 初音未来 X 三丽鸥 圆滚滚毛绒玩偶2\n' +
      '⭐MAX LIMI TED VOCALOID 初音未来 X 三丽鸥 毛绒夹子2\n' +
      '⭐MAX LIMI TED VOCALOID 初音未来 X 三丽鸥 趴趴毛绒玩偶2 ',
    like: 0,
    comment: 0,
    category: '诗歌',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '绳匠久等啦,《绝区零》bilibili个性装扮将于8月8日20:00上线![星星眼]\n' +
      '同时个性装扮领取页面现已开放,在活动中获得【个性装扮】的绳匠可以通过站内信前往查看~',
    like: 0,
    comment: 0,
    category: '对联',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '#战双帕弥什# \n' +
      '【空中花园 | 情报中心】第二十六期\n' +
      '新版本测试服优化内容来啦~\n' +
      '\n' +
      '本期新增[数据演习]BOSS及难度等级、[幻痛囚笼]奖励领取优化、主界面字幕优化等内容。\n' +
      '\n' +
      '更多优化详情点击图片即可查看↓↓↓',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  }
]);

const originalList = ref([
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '小伙伴们,我们这也是好起来了,和奥运冠军一起吃上饭了',
    content: '小伙伴们,我们这也是好起来了,和奥运冠军一起吃上饭了',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '【欧气宝箱新品】\n' +
      '软软糯糯的miku玉桂狗团子٩(๑˃̵ᴗ˂̵๑)۶\n' +
      '\n' +
      '⭐MAX LIMI TED VOCALOID 初音未来 X 三丽鸥 圆滚滚毛绒玩偶2\n' +
      '⭐MAX LIMI TED VOCALOID 初音未来 X 三丽鸥 毛绒夹子2\n' +
      '⭐MAX LIMI TED VOCALOID 初音未来 X 三丽鸥 趴趴毛绒玩偶2 ',
    like: 0,
    comment: 0,
    category: '诗歌',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '绳匠久等啦,《绝区零》bilibili个性装扮将于8月8日20:00上线![星星眼]\n' +
      '同时个性装扮领取页面现已开放,在活动中获得【个性装扮】的绳匠可以通过站内信前往查看~',
    like: 0,
    comment: 0,
    category: '对联',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '#战双帕弥什# \n' +
      '【空中花园 | 情报中心】第二十六期\n' +
      '新版本测试服优化内容来啦~\n' +
      '\n' +
      '本期新增[数据演习]BOSS及难度等级、[幻痛囚笼]奖励领取优化、主界面字幕优化等内容。\n' +
      '\n' +
      '更多优化详情点击图片即可查看↓↓↓',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  }
]);

function handleCategoryClick(category) {
  selectedCategory.value = category;
  // 根据选中的分类过滤列表数据
  const arrList = originalList.value;
  if (category !== '全部') {
    list.value = arrList.filter(item => item.category === category);
  } else {
    list.value = originalList.value;
  }
}

const addArr = [
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  },
  {
    user: '星与花灰色的雨',
    time: '6',
    title: '11111111111111111111111111',
    content: '22222222222222222222222',
    like: 0,
    comment: 0,
    category: '古诗',
    isExpanded: false
  }
];

function scrollHandle() {
  const scrollHeight = document.body.scrollHeight;
  const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
  const clientHeight = document.documentElement.clientHeight;
  const distance = scrollHeight - scrollTop - clientHeight;
  if (distance <= 200) {
    load();
  }
}

onMounted(() => {
  window.addEventListener('scroll', scrollHandle, false);
});
onUnmounted(() => {
  window.removeEventListener('scroll', scrollHandle, false);
});

let loading = false;
load();

function load() {
  if (loading) {
    return;
  }
  loading = true;
  add();
}

function add() {
  const arrList = list.value;
  list.value = arrList.concat(addArr);
  loading = false;
}
</script>

<template>
  <n-space vertical>
    <n-input
      type="textarea"
      placeholder="有什么想发的吗?"
      :autosize="{
        minRows: 3,
      }"
    />
  </n-space>

  <div class="items w-84 w-full">
    <div class="rounded-lg h-12 w-full">
      <div class="flex h-full pl-2">
        <div @click="handleCategoryClick('全部')"
             :class="{'text-blue-400 font-bold': selectedCategory === '全部', 'text-pink-300': selectedCategory!== '全部'}"
             class="text-base leading-loose active flex items-center justify-center cursor-pointer relative h-full mr-8"
        >
          全部
        </div>
        <div @click="handleCategoryClick('古诗')"
             :class="{'text-blue-400 font-bold': selectedCategory === '古诗', 'text-pink-300': selectedCategory!== '古诗'}"
             class="text-base leading-loose flex items-center justify-center relative h-full font-normal mr-8 cursor-pointer"
        >
          古诗
        </div>
        <div @click="handleCategoryClick('诗歌')"
             :class="{'text-blue-400 font-bold': selectedCategory === '诗歌', 'text-pink-300': selectedCategory!== '诗歌'}"
             class="text-base leading-loose flex items-center justify-center relative h-full font-normal mr-8 cursor-pointer"
        >
          诗歌
        </div>
        <div @click="handleCategoryClick('对联')"
             :class="{'text-blue-400 font-bold': selectedCategory === '对联', 'text-pink-300': selectedCategory!== '对联'}"
             class="text-base leading-loose flex items-center justify-center relative h-full font-normal mr-8 cursor-pointer"
        >
          对联
        </div>
      </div>
    </div>

    <div class="item box-border w-full p-4 border border-gray-300 rounded-lg mb-4"
         v-for="(item, index) in list" :key="index">
      <div class="relative min-w-[556px]">
        <div class="item__main  pl-88 pr-20 relative">
          <div class="absolute top-0 left-0 h-86 w-86 flex justify-center items-center">
            <div class="h-48 w-48">
              <div class="h-66 w-66">
                <div class="center rounded-full w-37 h-37 opacity-100">
                  <picture class="flex w-20 h-20">
                    <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像" />
                  </picture>
                  <div>
                    <div class="local-undefined local-4">⭐</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="items-center h-16 pt-4">
            <div>
              <span
                class="font-bold text-pink-300 cursor-pointer transition-all duration-200">
                {{ item.user }}
              </span>
            </div>
            <div class="items-center pt-1">
              <div data-module="time" class="text-[#9499a0] cursor-pointer">
                {{ item.time }}分钟前
              </div>
            </div>
          </div>
          <div class="mt-8">
            <div class="font-sans text-[15px]">
              <div class="truncate">
                <span class="line--6"></span><span class="line--6">{{ item.content }}</span>
              </div>
            </div>
          </div>
          <div class="flex justify-between h-12 pr-5">
            <div>
              <div class="flex items-center cursor-pointer relative h-full text-[#9499a0] text-sm w-28">
                <svg
                  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"
                  width="18" height="18" style="width: 18px; height: 18px;">
                  <path
                    d="M9.789075 2.2956175C8.97235 1.6308450000000003 7.74999 2.212005 7.74999 3.26506L7.74999 5.3915500000000005C6.642015000000001 5.5780325 5.3073725 6.040405 4.141735000000001 7.11143C2.809155 8.335825 1.751515 10.3041 1.45716 13.404099999999998C1.409905 13.9018 1.7595399999999999 14.22505 2.105415 14.317499999999999C2.442215 14.40755 2.8807175 14.314625 3.127745 13.92915C3.9664525 12.620249999999999 4.89282 11.894575 5.765827499999999 11.50585C6.4628049999999995 11.19545 7.14528 11.093125 7.74999 11.0959L7.74999 13.235025C7.74999 14.2881 8.97235 14.869250000000001 9.789075 14.2045L15.556199999999999 9.510425000000001C16.355075 8.860149999999999 16.355075 7.640124999999999 15.556199999999999 6.989840000000001L9.789075 2.2956175zM9.165099999999999 3.0768275000000003L14.895025 7.739050000000001C15.227975 7.980475 15.235775 8.468875 14.943874999999998 8.7142L9.17615 13.416800000000002C8.979474999999999 13.562024999999998 8.75 13.4269 8.75 13.227375000000002L8.75 10.638175C8.75 10.326975000000001 8.542125 10.134725 8.2544 10.1118C7.186765 10.02955 6.1563175 10.2037 5.150895 10.69295C4.14982 11.186925 3.2102250000000003 12.096525 2.573625 13.00995C2.54981 13.046975 2.52013 13.046025 2.5211725 12.986C2.8971525 10.0573 3.9373475 8.652125 4.807025 7.85305C5.87747 6.8694775 7.213197500000001 6.444867500000001 8.2272 6.33056C8.606525 6.287802500000001 8.74805 6.0849325 8.74805 5.7032275L8.74805 3.2615475C8.74805 3.0764875000000007 8.993175 2.9321925 9.165099999999999 3.0768275000000003z"
                    fill="currentColor"></path>
                </svg>
                转发
              </div>
            </div>
            <div >
              <div class="flex items-center cursor-pointer relative h-full text-[#9499a0] text-sm w-28">
                <svg @click="updateIsExpanded(item)"
                  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"
                  width="18" height="18" style="width: 18px; height: 18px;">
                  <path
                    d="M1.5625 7.875C1.5625 4.595807499999999 4.220807499999999 1.9375 7.5 1.9375L10.5 1.9375C13.779175 1.9375 16.4375 4.595807499999999 16.4375 7.875C16.4375 11.0504 13.944675 13.6435 10.809275 13.80405C10.097025 14.722974999999998 8.920875 15.880675 7.267095 16.331325C6.9735075 16.4113 6.704762499999999 16.286224999999998 6.55411 16.092325C6.40789 15.904149999999998 6.3561 15.634350000000001 6.4652449999999995 15.383025C6.72879 14.776249999999997 6.776465 14.221025000000001 6.7340175 13.761800000000001C3.8167675 13.387125 1.5625 10.894475 1.5625 7.875zM7.5 2.9375C4.773095 2.9375 2.5625 5.148095 2.5625 7.875C2.5625 10.502575 4.61524 12.651075000000002 7.2041924999999996 12.8038C7.4305875 12.817174999999999 7.619625000000001 12.981200000000001 7.664724999999999 13.203475C7.772575 13.734575000000001 7.8012 14.405425000000001 7.5884275 15.148399999999999C8.748325 14.6682 9.606 13.759825 10.151275 13.016475C10.24445 12.889475 10.392050000000001 12.8138 10.54955 12.812275C13.253575 12.785725 15.4375 10.58535 15.4375 7.875C15.4375 5.148095 13.226899999999999 2.9375 10.5 2.9375L7.5 2.9375z"
                    fill="currentColor"></path>
                </svg>
                {{ item.comment }}
              </div>
            </div>
            <div>
              <div class="flex items-center cursor-pointer relative h-full text-[#9499a0] text-sm w-28">
                <svg
                  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"
                  width="18" height="18" style="width: 18px; height: 18px;">
                  <path
                    d="M10.4511 2.2220125C10.218425 2.194885 10.002175 2.2953725 9.884175 2.433395C9.4264 2.9688525 9.321875 3.7501399999999996 8.978575 4.3581725C8.533574999999999 5.146395 8.1198 5.6213375 7.609775000000001 6.068507499999999C7.1751375 6.449565 6.738407499999999 6.697442499999999 6.3125 6.8050575L6.3125 14.854575C6.9198900000000005 14.868174999999999 7.572900000000001 14.876875 8.25 14.876875C9.936425 14.876875 11.367025 14.823325 12.33115 14.773699999999998C13.03235 14.737575 13.646025000000002 14.390075 13.966750000000001 13.81945C14.401900000000001 13.04535 14.9387 11.909650000000001 15.264174999999998 10.571200000000001C15.56665 9.327275 15.704699999999999 8.304325 15.766675 7.582224999999999C15.7988 7.208262500000001 15.50165 6.875019999999999 15.059999999999999 6.875019999999999L11.323274999999999 6.875019999999999C11.156575 6.875019999999999 11.000800000000002 6.791952499999999 10.907975 6.653499999999999C10.783725 6.468192500000001 10.82855 6.2670175 10.9037 6.07485C11.059 5.675084999999999 11.29355 4.9974475 11.382425000000001 4.4018275C11.470875000000001 3.80917 11.450999999999999 3.32219 11.212050000000001 2.86913C10.9571 2.3857825 10.66065 2.2464475 10.4511 2.2220125zM12.034300000000002 5.87502L15.059999999999999 5.87502C16.02035 5.87502 16.850875 6.64489 16.763 7.667825C16.697100000000002 8.435525 16.55155 9.5092 16.235825000000002 10.807500000000001C15.882625 12.259950000000002 15.3035 13.482225 14.838450000000002 14.309474999999999C14.32695 15.2194 13.377475 15.721150000000002 12.38255 15.772375C11.405125 15.822725 9.956949999999999 15.876875000000002 8.25 15.876875000000002C6.5961925 15.876875000000002 5.0846825 15.826025000000001 4.0136674999999995 15.77715C2.8370825 15.723474999999999 1.8519999999999999 14.850000000000001 1.725645 13.654824999999999C1.6404649999999998 12.849274999999999 1.5625 11.80725 1.5625 10.689375C1.5625 9.665175000000001 1.6279400000000002 8.736175 1.7045524999999997 7.998975C1.8351224999999998 6.7427075 2.9137075 5.87502 4.130655 5.87502L5.8125 5.87502C6.072015 5.87502 6.457235 5.7490675 6.9505175 5.316582499999999C7.377705000000001 4.942045 7.7193000000000005 4.5546075 8.107775 3.8665374999999997C8.492075 3.18585 8.605825 2.389785 9.124075 1.783595C9.452975 1.3988800000000001 9.99475 1.162025 10.5669 1.228745C11.16225 1.29816 11.717425 1.683875 12.09655 2.4025825000000003C12.478275 3.1262375000000002 12.474075 3.8618225 12.371500000000001 4.54938C12.302149999999997 5.0139949999999995 12.155425000000001 5.510059999999999 12.034300000000002 5.87502zM5.3125 14.82705L5.3125 6.875019999999999L4.130655 6.875019999999999C3.3792199999999997 6.875019999999999 2.77211 7.400795 2.6991975000000004 8.10235C2.6253525 8.812875 2.5625 9.70665 2.5625 10.689375C2.5625 11.762875 2.6374975 12.768475 2.7200975 13.549700000000001C2.7919925 14.229675 3.3521950000000005 14.74595 4.05924 14.778224999999999C4.4278775 14.795 4.849985 14.812050000000001 5.3125 14.82705z"
                    fill="currentColor"></path>
                </svg>
                {{ item.like }}
              </div>
            </div>
          </div>
        </div>

        <CommentParent :isExpanded="item.isExpanded"></CommentParent>

      </div>
    </div>
  </div>


</template>



<style scoped>

.item__main {
  padding: 0 20px 0 88px;
}

</style>

<script setup lang="ts">
import { reactive, ref,watch } from 'vue';
import CommentOne from '@/components/form/CommentOne.vue';
import type { Comment } from '@/interface/Comment';
import { addCommentApi, getCommentInfoApi } from '@/api/forum/comment';


let isExpanded = defineProps({
  isExpanded: {
    type: Boolean,
    default: false
  }
});
let showSendBtn = ref(false);

// let info = [
//   {
//     id: 1,
//     rootId: 1,
//     parentId: 0,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   },
//   {
//     id: 2,
//     rootId: 2,
//     parentId: 0,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   },
//   {
//     id: 3,
//     rootId: 3,
//     parentId: 0,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   },
//   {
//     id: 4,
//     rootId: 1,
//     parentId: 1,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   },
//   {
//     id: 5,
//     rootId: 2,
//     parentId: 2,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   },
//   {
//     id: 6,
//     rootId: 3,
//     parentId: 3,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   },
//   {
//     id: 7,
//     rootId: 1,
//     parentId: 4,
//     username: 'tao',
//     comment: '7897',
//     showReply: false,
//     children: []
//   }
// ];

//树形结构
// function transformData(info) {
//   const groupedData = {};
//
//   // 首先按照 rootId 对数据进行分组
//   info.forEach(item => {
//     if (!groupedData[item.rootId]) {
//       groupedData[item.rootId] = {
//         ...item,
//         children: []
//       };
//     } else {
//       if (item.parentId === groupedData[item.rootId].id) {
//         groupedData[item.rootId].children.push(item);
//       }
//     }
//   });
//
//   return reactive({
//     data: ref<Comment[]>(Object.values(groupedData))
//   });
// }
// let props = transformData(info);

let props = reactive({
  data: reactive<Comment[]>([
    {
      id: 1,
      rootId: 1,
      parentId: 0,
      username: 'tao',
      comment: '7897',
      showReply: false,
      children: [
        {
          id: 4,
          rootId: 1,
          parentId: 1,
          username: 'tao',
          comment: '7897',
          showReply: false,
          children: [
            {
              id: 7,
              rootId: 1,
              parentId: 4,
              username: 'tao',
              comment: '7897',
              showReply: false,
              children: []
            }
          ]
        }
      ]
    },
    {
      id: 2,
      rootId: 2,
      parentId: 0,
      username: 'tao',
      comment: '7897',
      showReply: false,
      children: [
        {
          id: 5,
          rootId: 2,
          parentId: 2,
          username: 'tao',
          comment: '7897',
          showReply: false,
          children: []
        }
      ]
    },
    {
      id: 3,
      rootId: 3,
      parentId: 0,
      username: 'tao',
      comment: '7897',
      showReply: false,
      children: [
        {
          id: 6,
          rootId: 3,
          parentId: 3,
          username: 'tao',
          comment: '7897',
          showReply: false,
          children: []
        }
      ]
    }
  ])
});

let totalCount = ref(0);

let commentInfo = reactive({
  id: 8,
  rootId: 1,
  parentId: 0,
  comment: ref(''),
  username: ref('涛涛6号'),
  showReply: false
});



// const getCommentList = async () => {
//   try {
//     const res = await getCommentInfoApi(0);
//     totalCount.value = res.data.total;
//     props.data = res.data.items;
//   } catch (error) { /* empty */ }
// };
// onMounted(() => {
//   getCommentList();
// });


function addComment(commentInfo){
  const newCommentInfo = {...commentInfo };
  props.data.unshift(newCommentInfo);
  commentInfo.comment = '';
  showSendBtn.value = false;

  // try {
  //   const res = await addCommentApi(newCommentInfo);
  //   getCommentList();
  // } catch (error) {
  //   console.log(error);
  // }
}
</script>

<template>
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" v-show="isExpanded.isExpanded">
    <div class="flex items-center mb-4">
      <ul class="flex items-center list-none m-0 p-0">
        <li>评论 {{totalCount}}</li>
        <li class="pl-2">最新</li>
        <li class="pl-1">最热</li>
      </ul>
    </div>
    <div class="flex w-200">
      <div class="flex justify-center w-20 h-12">
        <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
      </div>
      <div class="flex-1 transition-duration-200 border border-1 rounded-lg bg-gray-200 overflow-x-hidden">
        <div class="p-2 flex flex-col w-full rounded-lg cursor-text overflow-hidden">
          <textarea v-model="commentInfo.comment" @click="showSendBtn = !showSendBtn" class="p-1 w-full h-8 rounded-md bg-transparent font-normal text-base text-gray-700 resize-none outline-none" placeholder="有什么想说的" ></textarea>
        </div>
      </div>

    </div>
    <div class="flex justify-between items-center ml-4 mt-2 z-1 h-8 transition-all duration-200 ease-in-out" v-show="showSendBtn">
      <div class="w-full">
        <div @click="addComment(commentInfo)" class="z-1 text-base float-right flex justify-center items-center w-17.5 h-8 rounded-md cursor-pointer">发布</div>
      </div>
    </div>
    <div>

    </div>
    <div class="mt-4">
      <CommentOne :commentInfo="props.data"></CommentOne>
    </div>

  </div>
</template>

<style scoped>

</style>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import CommentTwo from '@/components/form/CommentTwo.vue';
import { Comment } from '@/interface/Comment';
import CommentThree from '@/components/form/CommentThree.vue';

const props = defineProps({
  commentInfo: {
    type: Array<Comment>,
    default: () =>[]
  }
});


let commentNew = ref('');
function getInfo(item,comment){
  return reactive({
    id: item.id,
    rootId: item.rootId,
    parentId: item.id,
    comment: comment,
    username: ref('涛涛号'),
    showReply: false
  });
}

function addCommentTwo(item,comment) {
  let commentInfoTwo = getInfo(item,comment);
  console.log(commentInfoTwo.comment);
  const newCommentInfo = {...commentInfoTwo };
  // 找到新评论的父级评论
  const parentComment = props.commentInfo.find(item => item.id === newCommentInfo.parentId);
  if (parentComment) {
    if (!parentComment.children) {
      parentComment.children = [];
    }
    parentComment.children.unshift(newCommentInfo);
  }
  commentNew.value = '';
  item.showReply = false;
}


function showReply(currentItem) {
  props.commentInfo.forEach(item => {
    if (item !== currentItem && item.showReply) {
      item.showReply = false;
    }
  });
  currentItem.showReply = !currentItem.showReply;
}


</script>

<template>

  <div class="flex flex-col" v-for="(item,index) in props.commentInfo" :key="index">
    <hr class="my-2 border-gray-300" />
    <div>
      <div class="flex justify-center absolute left-0 w-20 h-12 cursor-pointer">
        <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
      </div>
      <div class="flex-1 pl-10 w-full">
        <div class="flex items-center mb-1">
          <div>{{item.username}}</div>
        </div>
        <div class="text-base leading-loose">
          <span>{{item.comment}}</span>
          <div class="flex items-center mt-0.5 text-sm">
            <span class="reply-time">59 分钟前</span>
            <span class="flex items-center mr-4 cursor-pointer">
                      <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
                        <path d="M594.176 151.168a34.048 34.048 0 0 0-29.184 10.816c-11.264 13.184-15.872 24.064-21.504 40.064l-1.92 5.632c-5.632 16.128-12.8 36.864-27.648 63.232-25.408 44.928-50.304 74.432-86.208 97.024-23.04 14.528-43.648 26.368-65.024 32.576v419.648a4569.408 4569.408 0 0 0 339.072-4.672c38.72-2.048 72-21.12 88.96-52.032 21.504-39.36 47.168-95.744 63.552-163.008a782.72 782.72 0 0 0 22.528-163.008c0.448-16.832-13.44-32.256-35.328-32.256h-197.312a32 32 0 0 1-28.608-46.336l0.192-0.32 0.64-1.344 2.56-5.504c2.112-4.8 5.12-11.776 8.32-20.16 6.592-17.088 13.568-39.04 16.768-60.416 4.992-33.344 3.776-60.16-9.344-84.992-14.08-26.688-30.016-33.728-40.512-34.944zM691.84 341.12h149.568c52.736 0 100.864 40.192 99.328 98.048a845.888 845.888 0 0 1-24.32 176.384 742.336 742.336 0 0 1-69.632 178.56c-29.184 53.44-84.48 82.304-141.76 85.248-55.68 2.88-138.304 5.952-235.712 5.952-96 0-183.552-3.008-244.672-5.76-66.432-3.136-123.392-51.392-131.008-119.872a1380.672 1380.672 0 0 1-0.768-296.704c7.68-72.768 70.4-121.792 140.032-121.792h97.728c13.76 0 28.16-5.504 62.976-27.456 24.064-15.104 42.432-35.2 64.512-74.24 11.904-21.184 17.408-36.928 22.912-52.8l2.048-5.888c6.656-18.88 14.4-38.4 33.28-60.416a97.984 97.984 0 0 1 85.12-32.768c35.264 4.096 67.776 26.88 89.792 68.608 22.208 42.176 21.888 84.864 16 124.352a342.464 342.464 0 0 1-15.424 60.544z m-393.216 477.248V405.184H232.96c-40.448 0-72.448 27.712-76.352 64.512a1318.912 1318.912 0 0 0 0.64 282.88c3.904 34.752 32.96 61.248 70.4 62.976 20.8 0.96 44.8 1.92 71.04 2.816z" fill="#9499a0"></path>
                      </svg>
                      <span>2</span>
                    </span>
            <span class="flex items-center mr-4 cursor-pointer">
                      <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
                        <path d="M594.112 872.768a34.048 34.048 0 0 1-29.12-10.816c-11.264-13.248-15.872-24.064-21.504-40.064l-1.92-5.632c-5.632-16.128-12.8-36.864-27.712-63.232-25.344-44.928-50.24-74.432-86.144-97.024-23.104-14.528-43.648-26.432-65.024-32.64V203.84a4570.24 4570.24 0 0 1 339.072 4.672c38.656 2.048 72 21.12 88.896 52.032 21.504 39.36 47.232 95.744 63.552 163.008 16.448 67.52 21.568 123.776 22.592 163.008 0.448 16.832-13.44 32.256-35.392 32.256h-197.248a32 32 0 0 0-28.608 46.336l0.128 0.32 0.64 1.28 2.56 5.568c2.176 4.8 5.12 11.776 8.384 20.16 6.528 17.088 13.568 39.04 16.768 60.416 4.928 33.344 3.712 60.16-9.344 84.992-14.08 26.688-30.016 33.728-40.576 34.944z m97.728-190.016h149.568c52.8 0 100.864-40.128 99.392-97.92a846.336 846.336 0 0 0-24.32-176.448 742.016 742.016 0 0 0-69.632-178.56c-29.248-53.44-84.48-82.304-141.824-85.248-55.68-2.88-138.24-5.952-235.712-5.952-96 0-183.488 3.008-244.672 5.76-66.368 3.136-123.328 51.392-130.944 119.872a1380.608 1380.608 0 0 0-0.768 296.704c7.68 72.768 70.4 121.792 140.032 121.792h97.728c13.76 0 28.16 5.504 62.976 27.392 24.064 15.168 42.432 35.264 64.448 74.368 11.968 21.12 17.472 36.864 22.976 52.736l2.048 5.888c6.656 18.88 14.336 38.4 33.216 60.416 19.456 22.72 51.456 36.736 85.184 32.768 35.2-4.096 67.776-26.88 89.792-68.672 22.208-42.112 21.888-84.8 16-124.288a343.04 343.04 0 0 0-15.488-60.608zM298.688 205.568v413.184H232.96c-40.512 0-72.448-27.712-76.352-64.512a1318.912 1318.912 0 0 1 0.64-282.88c3.904-34.816 32.896-61.248 70.4-62.976 20.8-0.96 44.736-1.92 71.04-2.816z" fill="#9499a0"></path>
                      </svg>
                      <span>2</span>
                    </span>
            <span @click="showReply(item)" class="cursor-pointer">回复</span>
          </div>
        </div>
      </div>
    </div>

    <div class="flex w-200" v-show="item.showReply">
      <div class="flex justify-center w-20 h-12">
        <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
      </div>
      <div class="flex-1 transition-duration-200 border border-1 rounded-lg bg-gray-200 overflow-x-hidden">
        <div class="p-2 flex flex-col w-full rounded-lg cursor-text overflow-hidden">
          <textarea v-model="commentNew" class="p-1 w-full h-8 rounded-md bg-transparent font-normal text-base text-gray-700 resize-none outline-none" placeholder="有什么想说的" ></textarea>
        </div>
      </div>
      <div class="flex justify-between items-center ml-4 mt-2 z-1 h-8 transition-all duration-200 ease-in-out">
        <div class="w-full">
          <div @click="addCommentTwo(item,commentNew)" class="z-1 text-base float-right flex justify-center items-center w-17.5 h-8 rounded-md cursor-pointer">发布</div>
        </div>
      </div>
    </div>


    <div class="pt-5 pl-10" v-if="item.children && item.children.length">
      <CommentTwo :commentInfo="item.children" :addCommentTwo="addCommentTwo" :showReply="showReply"></CommentTwo>
    </div>

    <div class="pt-5 pl-10" v-for="(child,childIndex) in item.children" :key="childIndex">
      <div v-if="child.children && child.children.length">
        <CommentThree :commentInfo="child.children" :addCommentThree="addCommentTwo" :showReply="showReply"></CommentThree>
      </div>
    </div>
  </div>

</template>

<style scoped>

</style>
<script setup lang="ts">
import { Comment } from '@/interface/Comment';
import { ref } from 'vue';

const props = defineProps({
  commentInfo: {
    type: Array<Comment>,
    default: () =>[]
  }
  // addCommentTwo: {
  //   type: Function
  // },
  // showReply: {
  //   type: Function
  // }
});



let commentNew = ref('');
function getInfo(item,comment){
  return reactive({
    id: item.id,
    rootId: item.rootId,
    parentId: item.id,
    comment: comment,
    username: ref('涛涛'),
    showReply: false
  });
}

// function addCommentTwo(item,comment) {
//   let commentInfoTwo = getInfo(item,comment);
//
//   const newCommentInfo = {...commentInfoTwo };
//   // 找到新评论的父级评论
//   const parentComment = props.commentInfo.find(item => item.id === newCommentInfo.parentId);
//   if (parentComment) {
//     if (!parentComment.children) {
//       parentComment.children = [];
//     }
//     parentComment.children.unshift(newCommentInfo);
//   }
//   commentNew.value = '';
//   item.showReply = false;
// }

function findCorrectPosition(rootId, parentId, commentInfo) {
  for (let item of commentInfo) {
    if (item.id === rootId) {
      if (parentId === 0) {
        return item;
      } else {
        for (let child of item.children) {
          if (child.id === parentId) {
            return child;
          }
        }
      }
    }
  }
  return null;
}

function addCommentTwo(item, comment) {
  let commentInfoTwo = getInfo(item, comment);

  const newCommentInfo = {...commentInfoTwo };

  // 使用新方法找到正确的位置
  const target = findCorrectPosition(newCommentInfo.rootId, newCommentInfo.parentId, props.commentInfo);

  if (target) {
    if (!target.children) {
      target.children = [];
    }
    target.children.unshift(newCommentInfo);
  }

  commentNew.value = '';
  item.showReply = false;
}


function showReply(currentItem) {
  props.commentInfo.forEach(item => {
    if (item !== currentItem && item.showReply) {
      item.showReply = false;
    }
  });
  currentItem.showReply = !currentItem.showReply;
}
</script>

<template>
  <div v-if="props.commentInfo && props.commentInfo.length" >
    <div class="flex flex-col" v-for="(item,index) in props.commentInfo" :key="index">
      <div class="flex">
          <div class="flex w-15 h-12 cursor-pointer">
            <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
          </div>
          <div class="flex-1 pl-5">
            <div class="flex items-center mb-1">
              <div>{{item.username}}</div>
            </div>
            <div class="text-base leading-loose">
              <span>{{item.comment}}</span>
              <div class="flex items-center mt-0.5 text-sm">
                <span class="reply-time">59 分钟前</span>
                <span class="flex items-center mr-4 cursor-pointer">
                      <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
                        <path d="M594.176 151.168a34.048 34.048 0 0 0-29.184 10.816c-11.264 13.184-15.872 24.064-21.504 40.064l-1.92 5.632c-5.632 16.128-12.8 36.864-27.648 63.232-25.408 44.928-50.304 74.432-86.208 97.024-23.04 14.528-43.648 26.368-65.024 32.576v419.648a4569.408 4569.408 0 0 0 339.072-4.672c38.72-2.048 72-21.12 88.96-52.032 21.504-39.36 47.168-95.744 63.552-163.008a782.72 782.72 0 0 0 22.528-163.008c0.448-16.832-13.44-32.256-35.328-32.256h-197.312a32 32 0 0 1-28.608-46.336l0.192-0.32 0.64-1.344 2.56-5.504c2.112-4.8 5.12-11.776 8.32-20.16 6.592-17.088 13.568-39.04 16.768-60.416 4.992-33.344 3.776-60.16-9.344-84.992-14.08-26.688-30.016-33.728-40.512-34.944zM691.84 341.12h149.568c52.736 0 100.864 40.192 99.328 98.048a845.888 845.888 0 0 1-24.32 176.384 742.336 742.336 0 0 1-69.632 178.56c-29.184 53.44-84.48 82.304-141.76 85.248-55.68 2.88-138.304 5.952-235.712 5.952-96 0-183.552-3.008-244.672-5.76-66.432-3.136-123.392-51.392-131.008-119.872a1380.672 1380.672 0 0 1-0.768-296.704c7.68-72.768 70.4-121.792 140.032-121.792h97.728c13.76 0 28.16-5.504 62.976-27.456 24.064-15.104 42.432-35.2 64.512-74.24 11.904-21.184 17.408-36.928 22.912-52.8l2.048-5.888c6.656-18.88 14.4-38.4 33.28-60.416a97.984 97.984 0 0 1 85.12-32.768c35.264 4.096 67.776 26.88 89.792 68.608 22.208 42.176 21.888 84.864 16 124.352a342.464 342.464 0 0 1-15.424 60.544z m-393.216 477.248V405.184H232.96c-40.448 0-72.448 27.712-76.352 64.512a1318.912 1318.912 0 0 0 0.64 282.88c3.904 34.752 32.96 61.248 70.4 62.976 20.8 0.96 44.8 1.92 71.04 2.816z" fill="#9499a0"></path>
                      </svg>
                      <span>2</span>
                    </span>
                <span class="flex items-center mr-4 cursor-pointer">
                      <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
                        <path d="M594.112 872.768a34.048 34.048 0 0 1-29.12-10.816c-11.264-13.248-15.872-24.064-21.504-40.064l-1.92-5.632c-5.632-16.128-12.8-36.864-27.712-63.232-25.344-44.928-50.24-74.432-86.144-97.024-23.104-14.528-43.648-26.432-65.024-32.64V203.84a4570.24 4570.24 0 0 1 339.072 4.672c38.656 2.048 72 21.12 88.896 52.032 21.504 39.36 47.232 95.744 63.552 163.008 16.448 67.52 21.568 123.776 22.592 163.008 0.448 16.832-13.44 32.256-35.392 32.256h-197.248a32 32 0 0 0-28.608 46.336l0.128 0.32 0.64 1.28 2.56 5.568c2.176 4.8 5.12 11.776 8.384 20.16 6.528 17.088 13.568 39.04 16.768 60.416 4.928 33.344 3.712 60.16-9.344 84.992-14.08 26.688-30.016 33.728-40.576 34.944z m97.728-190.016h149.568c52.8 0 100.864-40.128 99.392-97.92a846.336 846.336 0 0 0-24.32-176.448 742.016 742.016 0 0 0-69.632-178.56c-29.248-53.44-84.48-82.304-141.824-85.248-55.68-2.88-138.24-5.952-235.712-5.952-96 0-183.488 3.008-244.672 5.76-66.368 3.136-123.328 51.392-130.944 119.872a1380.608 1380.608 0 0 0-0.768 296.704c7.68 72.768 70.4 121.792 140.032 121.792h97.728c13.76 0 28.16 5.504 62.976 27.392 24.064 15.168 42.432 35.264 64.448 74.368 11.968 21.12 17.472 36.864 22.976 52.736l2.048 5.888c6.656 18.88 14.336 38.4 33.216 60.416 19.456 22.72 51.456 36.736 85.184 32.768 35.2-4.096 67.776-26.88 89.792-68.672 22.208-42.112 21.888-84.8 16-124.288a343.04 343.04 0 0 0-15.488-60.608zM298.688 205.568v413.184H232.96c-40.512 0-72.448-27.712-76.352-64.512a1318.912 1318.912 0 0 1 0.64-282.88c3.904-34.816 32.896-61.248 70.4-62.976 20.8-0.96 44.736-1.92 71.04-2.816z" fill="#9499a0"></path>
                      </svg>
                      <span>2</span>
                    </span>
                <span @click="showReply(item)" class="cursor-pointer">回复</span>
              </div>
            </div>
          </div>
      </div>

      <div class="flex w-200" v-show="item.showReply">
        <div class="flex justify-center w-20 h-12">
          <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
        </div>
        <div class="flex-1 transition-duration-200 border border-1 rounded-lg bg-gray-200 overflow-x-hidden">
          <div class="p-2 flex flex-col w-full rounded-lg cursor-text overflow-hidden">
            <textarea v-model="commentNew" class="p-1 w-full h-8 rounded-md bg-transparent font-normal text-base text-gray-700 resize-none outline-none" placeholder="有什么想说的" ></textarea>
          </div>
        </div>
        <div class="flex justify-between items-center ml-4 mt-2 z-1 h-8 transition-all duration-200 ease-in-out">
          <div class="w-full">
            <div @click="addCommentTwo(item,commentNew)" class="z-1 text-base float-right flex justify-center items-center w-17.5 h-8 rounded-md cursor-pointer">发布</div>
          </div>
        </div>
      </div>

    </div>

  </div>

</template>

<style scoped>

</style>
<script setup lang="ts">
import { Comment } from '@/interface/Comment';
import { reactive, ref } from 'vue';

const props = defineProps({
  commentInfo: {
    type: Array<Comment>,
    default: () =>[]
  }
  // addCommentThree: {
  //   type: Function
  // },
  // showReply: {
  //   type: Function
  // }
});

//假数据
const user = reactive({
  userName: '测试数据'
});

let commentNew = ref('');
function getInfo(item,comment){
  return reactive({
    id: item.id,
    rootId: item.rootId,
    parentId: item.id,
    comment: comment,
    username: ref('涛涛6号'),
    showReply: false
  });
}

// function addCommentThree(item,comment) {
//   let commentInfoTwo = getInfo(item,comment);
//
//   const newCommentInfo = {...commentInfoTwo };
//   // 找到新评论的父级评论
//   const parentComment = props.commentInfo.find(item => item.id === newCommentInfo.parentId);
//   if (parentComment) {
//     if (!parentComment.children) {
//       parentComment.children = [];
//     }
//     parentComment.children.unshift(newCommentInfo);
//   }
//   commentNew.value = '';
//   item.showReply = false;
// }


function showReply(currentItem) {
  props.commentInfo.forEach(item => {
    if (item !== currentItem && item.showReply) {
      item.showReply = false;
    }
  });
  currentItem.showReply = !currentItem.showReply;
}


function findCorrectPosition(rootId, parentId, commentInfo) {
  for (let item of commentInfo) {
    if (item.id === rootId) {
      if (parentId === 0) {
        return item;
      } else {
        for (let child of item.children) {
          if (child.id === parentId) {
            return child;
          }
        }
      }
    }
  }
  return null;
}

function addCommentThree(item, comment) {
  let commentInfoTwo = getInfo(item, comment);

  const newCommentInfo = {...commentInfoTwo };

  // 使用新方法找到正确的位置
  const target = findCorrectPosition(newCommentInfo.rootId, newCommentInfo.parentId, props.commentInfo);

  if (target) {
    if (!target.children) {
      target.children = [];
    }
    target.children.unshift(newCommentInfo);
  }

  commentNew.value = '';
  item.showReply = false;
}
</script>

<template>
  <div v-if="props.commentInfo && props.commentInfo.length">
    <div class="flex flex-col" v-for="(item,index) in props.commentInfo" :key="index">
      <div class="flex">
        <div class="flex w-15 h-12 cursor-pointer">
          <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
        </div>
        <div class="flex-1 pl-5">
          <div class="flex items-center mb-1">
            <div>{{user.userName}}  回复 {{item.username}}</div>
          </div>
          <div class="text-base leading-loose">
            <span>{{item.comment}}</span>
            <div class="flex items-center mt-0.5 text-sm">
              <span class="reply-time">59 分钟前</span>
              <span class="flex items-center mr-4 cursor-pointer">
                      <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
                        <path d="M594.176 151.168a34.048 34.048 0 0 0-29.184 10.816c-11.264 13.184-15.872 24.064-21.504 40.064l-1.92 5.632c-5.632 16.128-12.8 36.864-27.648 63.232-25.408 44.928-50.304 74.432-86.208 97.024-23.04 14.528-43.648 26.368-65.024 32.576v419.648a4569.408 4569.408 0 0 0 339.072-4.672c38.72-2.048 72-21.12 88.96-52.032 21.504-39.36 47.168-95.744 63.552-163.008a782.72 782.72 0 0 0 22.528-163.008c0.448-16.832-13.44-32.256-35.328-32.256h-197.312a32 32 0 0 1-28.608-46.336l0.192-0.32 0.64-1.344 2.56-5.504c2.112-4.8 5.12-11.776 8.32-20.16 6.592-17.088 13.568-39.04 16.768-60.416 4.992-33.344 3.776-60.16-9.344-84.992-14.08-26.688-30.016-33.728-40.512-34.944zM691.84 341.12h149.568c52.736 0 100.864 40.192 99.328 98.048a845.888 845.888 0 0 1-24.32 176.384 742.336 742.336 0 0 1-69.632 178.56c-29.184 53.44-84.48 82.304-141.76 85.248-55.68 2.88-138.304 5.952-235.712 5.952-96 0-183.552-3.008-244.672-5.76-66.432-3.136-123.392-51.392-131.008-119.872a1380.672 1380.672 0 0 1-0.768-296.704c7.68-72.768 70.4-121.792 140.032-121.792h97.728c13.76 0 28.16-5.504 62.976-27.456 24.064-15.104 42.432-35.2 64.512-74.24 11.904-21.184 17.408-36.928 22.912-52.8l2.048-5.888c6.656-18.88 14.4-38.4 33.28-60.416a97.984 97.984 0 0 1 85.12-32.768c35.264 4.096 67.776 26.88 89.792 68.608 22.208 42.176 21.888 84.864 16 124.352a342.464 342.464 0 0 1-15.424 60.544z m-393.216 477.248V405.184H232.96c-40.448 0-72.448 27.712-76.352 64.512a1318.912 1318.912 0 0 0 0.64 282.88c3.904 34.752 32.96 61.248 70.4 62.976 20.8 0.96 44.8 1.92 71.04 2.816z" fill="#9499a0"></path>
                      </svg>
                      <span>2</span>
                    </span>
              <span class="flex items-center mr-4 cursor-pointer">
                      <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
                        <path d="M594.112 872.768a34.048 34.048 0 0 1-29.12-10.816c-11.264-13.248-15.872-24.064-21.504-40.064l-1.92-5.632c-5.632-16.128-12.8-36.864-27.712-63.232-25.344-44.928-50.24-74.432-86.144-97.024-23.104-14.528-43.648-26.432-65.024-32.64V203.84a4570.24 4570.24 0 0 1 339.072 4.672c38.656 2.048 72 21.12 88.896 52.032 21.504 39.36 47.232 95.744 63.552 163.008 16.448 67.52 21.568 123.776 22.592 163.008 0.448 16.832-13.44 32.256-35.392 32.256h-197.248a32 32 0 0 0-28.608 46.336l0.128 0.32 0.64 1.28 2.56 5.568c2.176 4.8 5.12 11.776 8.384 20.16 6.528 17.088 13.568 39.04 16.768 60.416 4.928 33.344 3.712 60.16-9.344 84.992-14.08 26.688-30.016 33.728-40.576 34.944z m97.728-190.016h149.568c52.8 0 100.864-40.128 99.392-97.92a846.336 846.336 0 0 0-24.32-176.448 742.016 742.016 0 0 0-69.632-178.56c-29.248-53.44-84.48-82.304-141.824-85.248-55.68-2.88-138.24-5.952-235.712-5.952-96 0-183.488 3.008-244.672 5.76-66.368 3.136-123.328 51.392-130.944 119.872a1380.608 1380.608 0 0 0-0.768 296.704c7.68 72.768 70.4 121.792 140.032 121.792h97.728c13.76 0 28.16 5.504 62.976 27.392 24.064 15.168 42.432 35.264 64.448 74.368 11.968 21.12 17.472 36.864 22.976 52.736l2.048 5.888c6.656 18.88 14.336 38.4 33.216 60.416 19.456 22.72 51.456 36.736 85.184 32.768 35.2-4.096 67.776-26.88 89.792-68.672 22.208-42.112 21.888-84.8 16-124.288a343.04 343.04 0 0 0-15.488-60.608zM298.688 205.568v413.184H232.96c-40.512 0-72.448-27.712-76.352-64.512a1318.912 1318.912 0 0 1 0.64-282.88c3.904-34.816 32.896-61.248 70.4-62.976 20.8-0.96 44.736-1.92 71.04-2.816z" fill="#9499a0"></path>
                      </svg>
                      <span>2</span>
                    </span>
              <span @click="showReply(item)" class="cursor-pointer">回复</span>
            </div>
          </div>
        </div>
      </div>

      <div class="flex w-200" v-show="item.showReply">
        <div class="flex justify-center w-20 h-12">
          <img class="rounded-full" src="https://p6-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/49c54d48-7310-473f-abad-74430cffbe2c_1723314581958214069~tplv-a9rns2rl98-web-image.jpeg?rk3s=b14c611d&x-expires=1754850582&x-signature=OaYZruDp6aO%2F9brMxQ52DYWd%2Bmk%3D" alt="头像">
        </div>
        <div class="flex-1 transition-duration-200 border border-1 rounded-lg bg-gray-200 overflow-x-hidden">
          <div class="p-2 flex flex-col w-full rounded-lg cursor-text overflow-hidden">
            <textarea v-model="commentNew" class="p-1 w-full h-8 rounded-md bg-transparent font-normal text-base text-gray-700 resize-none outline-none" :placeholder="'回复'+user.userName" ></textarea>
          </div>
        </div>
        <div class="flex justify-between items-center ml-4 mt-2 z-1 h-8 transition-all duration-200 ease-in-out">
          <div class="w-full">
            <div @click="addCommentThree(item,commentInfo)" class="z-1 text-base float-right flex justify-center items-center w-17.5 h-8 rounded-md cursor-pointer">发布</div>
          </div>
        </div>

      </div>
      <div v-if="item.children && item.children.length">
        <CommentThree class="pt-5" :commentInfo="item.children" :addCommentThree="addCommentThree" :showReply="showReply"></CommentThree>
      </div>

    </div>
  </div>
</template>

<style scoped>

</style>

接口

export interface Comment {
  id?: number;
  rootId?: number;
  parentId?:number;
  username?: string;
  comment?: string;
  showReply?: Boolean;
  children?: Comment[];
}

菜鸟一枚,请多指教

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于 Vue3 的评论回复功能的示例代码: ```vue <template> <div> <h2>评论</h2> <textarea v-model="comment" placeholder="请输入评论"></textarea> <button @click="submitComment">提交评论</button> <hr> <h3>评论列表</h3> <ul> <li v-for="(item, index) in comments" :key="index"> {{ item.content }} <button @click="showReplyBox(index)">回复</button> <div v-if="item.showReplyBox"> <textarea v-model="item.replyContent" placeholder="请输入回复"></textarea> <button @click="submitReply(index)">提交回复</button> </div> <ul> <li v-for="(reply, replyIndex) in item.replies" :key="replyIndex"> {{ reply.content }} </li> </ul> </li> </ul> </div> </template> <script> import { reactive } from 'vue' export default { setup() { const state = reactive({ comment: '', comments: [ { content: '这是评论1', showReplyBox: false, replyContent: '', replies: [] }, { content: '这是评论2', showReplyBox: false, replyContent: '', replies: [] }, { content: '这是评论3', showReplyBox: false, replyContent: '', replies: [] }, ], }) // 显示回复框 const showReplyBox = (index) => { state.comments[index].showReplyBox = true } // 提交评论 const submitComment = () => { if (!state.comment.trim()) { alert('请输入评论') return } state.comments.push({ content: state.comment, showReplyBox: false, replyContent: '', replies: [] }) state.comment = '' } // 提交回复 const submitReply = (index) => { if (!state.comments[index].replyContent.trim()) { alert('请输入回复') return } state.comments[index].replies.push({ content: state.comments[index].replyContent }) state.comments[index].replyContent = '' state.comments[index].showReplyBox = false } return { comment: state.comment, comments: state.comments, showReplyBox, submitComment, submitReply, } }, } </script> ``` 在这个示例中,我们使用了 Vue3 提供的 `reactive` 函数来创建响应式数据。评论回复的内容都存储在 `comments` 数组中,每个评论对象中包含一个 `showReplyBox` 属性,用于控制回复框的显示状态,以及一个 `replies` 数组,用于存储回复内容。 用户输入评论回复后,点击提交按钮即可将其添加到相应的评论对象或回复数组中。同时,为了方便用户回复,我们在每个评论对象中添加了一个按钮,点击后会显示回复框。 需要注意的是,为了防止用户输入空内容,我们在提交评论回复前都进行了输入内容的判断。 这只是一个简单的示例代码,实际应用中可能还需要考虑更多的功能和细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值