vue3评论组件,🔥基于vue3的UI组件,主要功能有评论,聊天,搜索,锚点。

入门

请遵循https://undraw.gitee.io/undraw-ui/上的文档!

安装

使用npm安装

npm i undraw-ui

使用

  1. main.ts 中引入组件
import { createApp } from 'vue'
import App from './App.vue'

import UndrawUi from 'undraw-ui'
import 'undraw-ui/dist/style.css'

const app = createApp(App)
app.use(UndrawUi)
app.mount('#app')

1. 折叠

<template>
  <u-fold unfold line="1">
    <p>
      时间不是某种从我们身上流过的东西,而就是我的生命。弃我而去的不是日历上的一个个日子,而是我生命中的岁月;甚至也不仅仅是我的岁月,而就是我自己。我不但找不回逝去的岁月,而且也找不回从前的我了。
    </p>
  </u-fold>
</template>


2. 评论

<template>
  <div class="comment-view" style="padding: 0px">
    <u-comment :config="config" @submit="submit" @like="like">
      <!-- <template #list-title>全部评论</template> -->
    </u-comment>
  </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'
import { UToast, CommentApi, CommentSubmitParam, ConfigApi } from 'undraw-ui'
// 下载表情包资源emoji.zip https://gitee.com/undraw/undraw-ui/releases
// static文件放在public下,引入emoji.ts文件可以移动到自定义位置
import emoji from './emoji'

const config = reactive<ConfigApi>({
  user: {
    id: 1,
    username: 'user',
    avatar: 'https://static.juzicon.com/avatars/avatar-200602130320-HMR2.jpeg?x-oss-process=image/resize,w_100',
    // 评论id数组 建议:存储方式用户id和文章id和评论id组成关系,根据用户id和文章id来获取对应点赞评论id,然后加入到数组中返回
    likes: [1, 2, 11]
  },
  emoji: emoji,
  comments: []
})

// 提交评论事件
const submit = ({ clear, content, parentId }: CommentSubmitParam) => {
  console.log(content, parentId)
  UToast({ message: '评论成功!', type: 'info' })
  // 提交评论 --后端接口处理
  editSubmit(content, parentId as number)
  clear()
}

// 点赞按钮事件
const like = (id: number) => {
  const likes = config.user.likes
  if (likes.indexOf(id) == -1) {
    // 点赞 --后端接口处理
    likes.push(id)
    editLike(id, 1)
  } else {
    // 取消点赞 --后端接口
    likes.splice(
      likes.findIndex(item => item == id),
      1
    )
    editLike(id, -1)
  }
}

// 模拟后端处理
const editLike = (id: number, count: number) => {
  let tar = null
  config.comments.forEach(v => {
    if (v.id != id) {
      tar = v.reply?.list.find(v => v.id == id)
    } else {
      tar = v
    }
    if (tar) {
      tar.like += count
    }
  })
}

let temp_id = 100
// 模拟后端处理
const editSubmit = (content: string, parentId: number) => {
  let comment: CommentApi = {
    id: (temp_id += 1),
    parentId: parentId,
    avatar: config.user.avatar,
    username: config.user.username,
    level: 6,
    link: `/${(temp_id += 1)}`,
    address: '来自江苏',
    content: content,
    like: 0,
    createTime: '1分钟前',
    reply: null
  }
  if (parentId == undefined) {
    config.comments.push(comment)
  } else {
    let raw_comment = config.comments.find(v => v.id == parentId)
    let reply = raw_comment?.reply
    if (reply) {
      reply.list.push(comment)
    } else if (raw_comment) {
      raw_comment.reply = { total: 1, list: [comment] }
    } else {
      config.comments.push(comment)
    }
  }
}

config.comments = [
  {
    id: 1,
    parentId: null,
    avatar: 'https://static.juzicon.com/avatars/avatar-200602130320-HMR2.jpeg?x-oss-process=image/resize,w_100',
    username: '落🤍尘',
    level: 6,
    link: '/1',
    address: '来自上海',
    content:
      '缘生缘灭,缘起缘落,我在看别人的故事,别人何尝不是在看我的故事?别人在演绎人生,我又何尝不是在这场戏里?谁的眼神沧桑了谁?我的眼神,只是沧桑了自己[喝酒]',
    like: 2,
    createTime: '1分钟前',
    reply: null
  },
  {
    id: 3,
    parentId: null,
    username: '悟二空',
    avatar: 'https://static.juzicon.com/user/avatar-bf22291e-ea5c-4280-850d-88bc288fcf5d-220408002256-ZBQQ.jpeg',
    level: 1,
    link: '/3',
    address: '来自苏州',
    content: '知道在学校为什么感觉这么困吗?因为学校,是梦开始的地方。[脱单doge]',
    like: 11,
    createTime: '1天前',
    reply: {
      total: 2,
      list: [
        {
          id: 14,
          parentId: 3,
          avatar:
            'https://static.juzicon.com/user/avatar-8b6206c1-b28f-4636-8952-d8d9edec975d-191001105631-MDTM.jpg?x-oss-process=image/resize,m_fill,w_100,h_100',
          username: '别扰我清梦*ぁ',
          level: 5,
          link: '/14',
          address: '来自重庆',
          content: '说的对,所以,综上所述,上课睡觉不怪我呀💤',
          like: 3,
          createTime: '1分钟前'
        },
        {
          id: 15,
          avatar:
            'https://static.juzicon.com/user/avatar-3cb86a0c-08e7-4305-9ac6-34e0cf4937cc-180320123405-BCV6.jpg?x-oss-process=image/resize,m_fill,w_100,h_100',
          parentId: 3,
          username: 'Blizzard',
          level: 4,
          link: '/15',
          content: '回复 <span style="color: blue;"">@别扰我清梦*ぁ:</span> 看完打了一个哈切。。。会传染。。。[委屈]',
          address: '来自广州',
          like: 9,
          createTime: '7天前'
        }
      ]
    }
  }
]
</script>

3. 搜索(input关键词动态滚动)

<template>
  <u-search :config="config" style="margin-left: 20px" @submit="submit"></u-search>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { SearchConfig } from 'undraw-ui'

const config = ref<SearchConfig>({
  keywords: ['斗罗大陆', '斗破苍穹', '吞噬星空', '凡人修仙传', '一念永恒'], // 搜索框关键字滚动
  hotSearchList: [
    '斗罗大陆',
    '斗破苍穹',
    '吞噬星空',
    '凡人修仙传',
    '一念永恒',
    '完美世界',
    '鬼灭之刃',
    '间谍过家家',
    '武动乾坤',
    '神印王座'
  ] // top10 热门搜索 最多显示10条数据
})

const submit = (val: string) => {
  console.log(val)
  window.open('/all?keyword=' + val)
}
</script>

<style lang="scss" scoped></style>

4. 锚点

<template>
  <div class="view">
    <el-scrollbar height="500px">
      <div id="article2" class="article">
        <h2>人的大地</h2>
        <p>
          我们对自身的了解,来自大地的,比来自书本的多。因为大地桀骜不驯。人在跟障碍较量时,才会发现自己的价值。但是,为了克服障碍,人需要一个工具——一个木刨,或一把铁犁。农民在劳动中,逐渐窥探到自然界的一些奥秘,他们挖掘到的真理是无处不在的。同样地,飞机这个航空运输工具,也使人接触到这些古老的问题。
        </p>
        <p>
          在茫茫夜海上,每一盏灯火都显示了一个心灵的奇迹。在这户人家,有人在阅读,有人在思索,有人在娓娓谈心。在另一户人家,有人在探索宇宙,有人在殚精竭虑地计算仙女座的星云。那里,有人在恋爱。原野上绵延不断地闪烁着这些暗淡欲灭的灯火。还有最隐秘的,那是诗人的灯火、教师的灯火、木工师傅的灯火。但是,在这些有生命的灯火之间,又有多少扇关闭的窗户,多少个沉睡的人……我应该努力返航,设法跟其中幾盏灯火产生联系——这些灯火,绵延向远方,星星点点,散落在原野上。
        </p>
        <h2>人和植物一样</h2>
        <p>对我来说,在地里种下一粒种子本身就是美好的。我总是带着喜悦和极大的敬畏去做这件事。</p>
        <p>种子种下去以后,我会看着我的花圃,想象生命是如何在眼睛看不见的黑暗地下工作的。</p>
        <p>
          我一直惦记着自己种下的种子。我常常在夜里醒来,陷入思索:雨水和露珠如何接触干燥的种壳,使它变得柔软。生命的精灵如何在种子里活跃起来,植物的个性如何呈现出来,种子如何挣脱囚禁自己的种壳,从中伸出两只手——一只手是根,负责抓住泥土,让自己挺立并吸收养料;另一只手伸出去寻找光,向上攀爬,痛饮微风和阳光,实现它完整的生命之美。
        </p>
        <h2>文明与野蛮</h2>
        <p>
          我们相信,人类社会会不断摒除野蛮,走向文明,因为绝大多数人向往文明,文明意味着尊重生命、维护人的尊严和自由、建立一种理性且科学的生活方式,让绝大多数人有安全感。人类历史正是因为人类对文明的追求与保护而顽强延续到今天,文明战胜野蛮,是必然的。
        </p>
        <h2>等待中的期许</h2>
        <div class="content">
          <h3>开头</h3>
          <p>
            &emsp;曾听图书出版界的朋友讲过一个令人心动的故事。前些年,他在一个饭局上,遇到一个初次见面的人。中国人聊天,总会问籍贯,就像英国人爱聊天气。听那人说到自己的故乡,朋友心弦微动。他忽然想起一个名字。30多年前,他还是一个少年,从杂志上找了一个笔友。两个人通信很久,聊聊日常琐事、青春悸动。直到后来,毕业,上班,搬家,逐渐失联。
          </p>
          <p>
            这是许多人都有的经历,成长,始于告别。这位朋友一直记得笔友所在的城市——就是在饭局上初见的那个人的故乡。朋友随意问起,是否认识某某某(他笔友的名字)。那人当即回道:“我们是邻居。”
          </p>
          <p>
            中国地大物博、人口众多,他们却通过这种巧合,再次相遇了。如今,两个人都结了婚,有了孩子,换了城市过着平淡的生活。这样的巧合,算是生活里的小奇迹。朋友还找机会去了笔友所在的城市,与她和她的家人见面,从此建立联系。只是交流方式不再是车马慢的信件,而是微信,两个人升级为网友。
          </p>
          <p>
            近日和年轻的同事聊起这个故事,让我惊讶的是,这群“90后”竟然也有笔友。一名同事还提到一个网站,注册后,会收到一个随机地址,可以给对方寄送明信片。他也收到过来自英国、日本、马来西亚等地的明信片。日本笔友,很体贴地用中文写着地址;法国笔友,歪歪扭扭地写了“你好”两个字。
          </p>
          <p>
            据这家网站统计,已经有80多万名会员收到来自207个国家的6293万张明信片。这种跨越千万里的期待,总是令人怦然心动。
          </p>
          <h3>中间</h3>
          <p>
            多年前,我出差去外地,还时不时给同事寄上一两张明信片,总算生活中,能有一些小小的惊喜。这些惊喜所蕴含的正是“等待”的迷人之处。像《等待戈多》里所说的:“我在等待我的戈多,我却真的不知道他什么时候来。”沈从文写《边城》,也说翠翠等着心上人,“那个人也许永远不回来了,也许明天回来”。
          </p>
          <p>
            日本人伊藤秀夫从来没想过,自己的孩子能够“回来”。10年前,他的儿子就因落水而丧生了。但是不久前,他收到一张明信片,是儿子寄出的。原来,在孩子遭遇意外之前,当地政府搞了一个防止全球变暖的宣传和启蒙活动。他们邀请小学生给10年后的自己寄一张明信片。伊藤的儿子参加了。10多年后,政府才把这些明信片寄出。伊藤这才知道,儿子当时最关心的一件事是,“我弟弟在干什么?”看着明信片,伊藤一下子记起了那个冬天,那个孩子的样子。我也忽然想起“刻舟求剑”这个词来。那张明信片,就是伊藤儿子刻下的记号,伊藤永远找不回儿子了,记号却一直存在。
          </p>
          <p>
            如今,邮筒正在慢慢消失,说起来总令人深感惋惜。可是,如果让我们回到那个车马慢的时代,估计大部分人会拒绝。
          </p>
          <p>在这个时代,人们不断往前跑,总会甩下一些东西,有得有失。</p>
          <p>
            前两天看新闻,一家外卖平台要增加社交功能了。我于是掰着手指头数了数,我们有了电商社交、短视频社交,现在又有外卖社交——真是一个社交途径极丰富的时代。
          </p>
          <h3>结尾</h3>
          <p>
            只是,曾经那种社交的丰富感——期待、温馨、畅快、痛苦……已很难感受到了。一个点赞图标,几乎表达了我们作为人类的一切感情。
          </p>
          <p>(徐 行摘自《看天下》,IC photo供图)</p>
        </div>
        <h2>村庄的时间</h2>
        <div class="content">
          <p>
            当我十岁的时候站在我家后面的皂荚树下,我突然感到时间的停滞。我的视野里只有寂静的午后村庄,没有风,没有人,空气均匀地铺展在池塘的深绿色水面上。我在这种突如其来的空寂中不敢妄动,与此同时,心中涌起永恒的瞻望。我想我永远不会长大,鸭蹼状的宽大树叶也永遠不会扇动,而放眼望去,青砖平房、柴垛、洗衣石板都永远在这里,不会变动一分一毫。
          </p>
          <p>
            片刻后,一声狗吠从巷口穿透时间凝滞形成的雾状薄膜,小孩子在天台上望着奔跑而去的伙伴放声大哭,我从一种清亮的空寂时间一下子坠入纷杂的轰隆隆的时间洪流,一直到现在。
          </p>
          <p>
            我在城市的时间里看到时间是属于摇滚乐的,一年前还是土堆成山的地方,呼啦啦拔地而起一片楼群;又见拆迁的工地,昔日的楼房破腔露肚,灰白的墙壁上满是雨痕。重建与摧毁,搬入与流离,过去与现在宛如时间的两排利齿,一切都被咬得粉碎。
          </p>
          <p>
            而当我回到村庄,在我生命的二十多年间,它几乎没有什么变动,老屋拆去,新屋盖起,住的依然是原来的人家。时间在村庄宛如丝绸,平滑完整,几乎不留痕迹。
          </p>
          <p>
            我从一个城市迁徙到另一个城市,舍弃旧的人事,建立新的人事,流动的、变化的,没有一个坚硬的空间能顽强留存。
          </p>
          <p>
            时间在村庄没有痕迹吗?试想我与相差二十岁的侄子,我跟他在同样的村庄长大,看到的同样是田地、池塘、泥路,同样可以攀在江边的桑树上吃桑葚,然而这二十年的时间是虚无的吗?我看着他跟小时候的我一样用瓦片和泥土玩过家家,一样看到黄昏时太阳在田野尽头的树林间隐没。然而,他再也听不到每天早上一直喊到我起床的米糕小贩的叫卖声了,再也听不到敲着清脆响亮铁板卖姜糖的叮叮当声了,再也不会跟我一样挤坐在垸礼堂听戏了。手工艺人在农村已经消失,无论是篾匠、木匠,还是弹棉花的匠人,都已经无处寻觅。手工艺人展现技艺的时间感是缓慢的、耐心的。我记得,随着拨浪鼓的咚咚声,婶娘们拥出门围着小贩买针头线脑,而满身棉絮的匠人在堂屋用巨大的弓弹着棉花,宛如翻搅起漫天雪花。
          </p>
          <p>
            而我的侄子只能看到事物的最终状态,时间在“需求—供应”模式下被挤压成薄片。他睡在从家居市场买来的床上,吃着从菜市场买来的菜,玩着从超市买来的玩具。虽在农村,却与在城市几无差异,还好他能看到跑动的鸡和狗,认识生长在田地里的棉花和小麦。
          </p>
          <p>
            他跟随他的父母离开村庄,进入不同的城市,不断变更就读的学校,不断认识新同学又忘记老同学。这样一种流动不居的空间变动,给他带来的是怎样的时间体验呢?我想在我之前,祖辈都在这个村庄日出而作、日落而息,耕种同一片土地,喝同一脉井水,我想时间于他们是绵长的、悠远的。而到了我这一代,空间开始变动,时间慢慢加快,村庄中的人不断外涌。由此我看到在我父亲与他的父亲之间,时间是没有肌理的;而在我跟我侄子之间,时间裹挟的人事变化远超从前。
          </p>
          <p>(朱 颜摘自人民文学出版社《纸上王国》一书,黄思思图)</p>
        </div>
      </div>
    </el-scrollbar>
    <!-- container指定监听的容器 target滚动轴 target-offset距离窗口顶部达到指定偏移量 -->
    <div class="article-catalog">
      <u-anchor container="#article2" style="width: 120px" target=".el-scrollbar__wrap"></u-anchor>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ElScrollbar } from 'undraw-ui'
</script>

<style lang="scss" scoped>
.article-catalog {
  width: 300px;
  margin-left: 10px;
}
.view {
  display: flex;
}
.article {
  width: 400px;
  p {
    margin: 20px 0;
    font-size: 16px;
    line-height: 32px;
    word-break: break-all;
    text-indent: 2em;
  }
}
</style>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐