vue开发的点赞,评论页面

效果:

 源码:

<template>
  <div>
    <!--赞/踩-->
    <el-row>
      <el-col :span="12" style="text-align: right; padding-right: 30px">
        <el-button type="primary" @click="like">赞({{ likeVal }})</el-button>
      </el-col>
      <el-col :span="12">
        <el-button type="warning" @click="unlike"
          >踩({{ unlikeVal }})</el-button
        >
      </el-col>
    </el-row>
    <div class="conmment_box">
      <div class="my-reply">
        <div class="reply-info">
          <el-input
            @focus="focusInput"
            type="textarea"
            placeholder="请输入内容"
            v-model="textarea"
            maxlength="1000"
            :autosize="{ minRows: 3, maxRows: 3 }"
            autofocus
            class="reply_input"
          >
          </el-input>
        </div>
        <div class="reply-btn-box">
          <div class="limit">
            还能输入
            <span class="num">{{ 1000 - inputLength }}</span>
            个字符
          </div>
          <el-button size="mini" type="primary" round @click="sendComment">
            发表评论
          </el-button>
        </div>
      </div>
      <div
        v-for="(item, i) in comments"
        :key="i"
        class="author-title reply-father"
      >
        <div class="author-info">
          <span class="author-name">{{ item.name }}</span>
          <span class="author-time">{{ item.time }}</span>
        </div>
        <div class="icon-btn">
          <span
            v-if="!item.inputShow"
            @click="showReplyInput(i, item.name, item.id)"
          >
            <i class="iconfont el-icon-s-comment"></i>
            回复
          </span>
          <span v-else @click="closeReplyInput(i, item.name, item.id)">
            <i class="iconfont el-icon-s-comment"></i>
            收起回复
          </span>
        </div>
        <div class="talk-box">
          <p>
            <span class="reply">{{ item.comment }}</span>
          </p>
        </div>
        <!-- 一级回复弹窗 -->
        <div v-show="_inputShow(i)" class="my-reply">
          <div class="reply-info">
            <el-input
              type="textarea"
              placeholder="请输入内容"
              v-model="replytextarea"
              maxlength="1000"
              :autosize="{ minRows: 3, maxRows: 3 }"
              autofocus
              class="reply_input"
            >
            </el-input>
          </div>
          <div class="reply-btn-box">
            <div class="limit">
              还能输入
              <span class="num">{{ 1000 - inputLength2 }}</span>
              个字符
            </div>
            <el-button
              size="mini"
              type="primary"
              round
              @click="sendCommentReply(i)"
            >
              发表评论
            </el-button>
          </div>
        </div>
        <div class="reply-box">
          <div v-for="(reply, j) in item.reply" :key="j" class="author-title">
            <div class="author-info">
              <span class="author-name">{{ reply.from }}</span>
              <span class="author-time">{{ reply.time }}</span>
            </div>
            <div class="icon-btn">
              <span
                v-if="!reply.inputShow"
                @click="showReplyInput2(i, reply.from, reply.id, j)"
              >
                <i class="iconfont el-icon-s-comment"></i>
                回复
              </span>
              <span
                v-else
                @click="closeReplyInput2(i, reply.from, reply.id, j)"
              >
                <i class="iconfont el-icon-s-comment"></i>
                收起回复
              </span>
            </div>
            <div class="talk-box">
              <p>
                <span>回复 {{ reply.to }}:</span>
                <span class="reply">{{ reply.comment }}</span>
              </p>
            </div>
            <!-- 二级回复弹窗 -->
            <div v-show="_inputShow2(i, j)" class="my-comment-reply">
              <div class="reply-info">
                <el-input
                  type="textarea"
                  placeholder="请输入内容"
                  v-model="replytextarea"
                  maxlength="1000"
                  :autosize="{ minRows: 3, maxRows: 3 }"
                  autofocus
                  class="reply_input"
                >
                </el-input>
              </div>
              <div class="reply-btn-box">
                <div class="limit">
                  还能输入
                  <span class="num">{{ 1000 - inputLength2 }}</span>
                  个字符
                </div>
                <el-button
                  size="mini"
                  type="primary"
                  round
                  @click="sendCommentReply(i)"
                >
                  发表评论
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import request from "@/utils/request";
export default {
  computed: {
    inputLength() {
      return this.textarea.length;
    },
    inputLength2() {
      return this.replytextarea.length;
    },
  },
  props: {
    direction: {
      type: String,
      default: "rtl",
    },
  },
  data() {
    return {
      textarea: "",
      replytextarea: "",
      drawer: true,
      closeInput: true,
      index: "0",
      index1: "0",
      index2: "0",
      replyComment: "",
      myName: "Lana Del Rey",
      myId: 19870621,
      to: "",
      toId: -1,
      comments: [
        {
          name: "风居住的街道",
          id: 19870621,
          comment: "我发布一张新电影我不是小三,大家快来看啊",
          time: "2024年9月16日 18:43",
          commentNum: 2,
          like: 15,
          inputShow: false,
          reply: [
            {
              from: "暖阳冬天",
              fromId: 19891221,
              to: "风居住的街道",
              toId: 19870621,
              comment: "我很喜欢你的新电影!!",
              time: "2024年9月16日 18:43",
              commentNum: 1,
              like: 15,
              inputShow: false,
            },
            {
              from: "风居住的街道",
              fromId: 1123,
              to: "风居住的街道",
              toId: 19870621,
              comment: "别忘记宣传我们的新电影啊",
              time: "2024年9月16日 18:43",
              commentNum: 0,
              like: 5,
              inputShow: false,
            },
          ],
        },
        {
          name: "爱跑的鹿",
          id: 19891221,
          comment: "我发行了我的新电影Lover",
          time: "2024年9月16日 18:43",
          commentNum: 1,
          like: 5,
          inputShow: false,
          reply: [
            {
              from: "风居住的街道",
              fromId: 19870621,
              to: "小张",
              toId: 19891221,
              comment: "新电影和speak now 一样棒!",
              time: "2024年9月16日 18:43",
              commentNum: 25,
              like: 5,
              inputShow: false,
            },
          ],
        },
        {
          name: "洽洽库",
          id: 20240830,
          comment: "ckwell on everywhere",
          time: "2024年9月16日 18:43",
          commentNum: 0,
          like: 5,
          inputShow: false,
          reply: [],
        },
      ],
      likeVal: 5,
      unlikeVal: 1,
      likeOperate: false,
      unlikeOperate: false,
    };
  },
  mounted() {
    this.getList();
  },
  methods: {
    /**
     * 获取列表
     */
    getList() {
      // let id = "334551";
      // let _query = {};
      // request({
      //   url: `/api/plan/Comment/getListById/${id}`,
      //   method: "post",
      //   data: _query,
      // }).then((res) => {
      //   console.log(res);
      // });
    },
    handleClose() {},
    focusInput() {
      this.closeInput = false;
    },
    hideReplyBtn() {
      replyInput.style.padding = "10px";
      replyInput.style.border = "none";
    },
    showReplyInput(i, name, id) {
      this.closeInput = true;
      this.comments[this.index1].reply[this.index2].inputShow = false;
      this.comments[this.index].inputShow = false;
      this.index = i;
      this.comments[i].inputShow = true;
      this.to = name;
      this.toId = id;
    },
    closeReplyInput(i, name, id) {
      this.closeInput = false;
      this.comments[this.index].inputShow = false;
    },
    showReplyInput2(i, name, id, j) {
      this.closeInput = true;
      this.comments[this.index].inputShow = false;
      this.comments[this.index1].reply[this.index2].inputShow = false;
      this.index1 = i;
      this.index2 = j;
      this.comments[i].reply[j].inputShow = true;
      this.to = name;
      this.toId = id;
    },
    closeReplyInput2(i, name, id, j) {
      this.closeInput = false;
      this.comments[i].reply[j].inputShow = false;
    },
    _inputShow(i) {
      return this.comments[i].inputShow && this.closeInput;
    },
    _inputShow2(i, j) {
      return this.comments[i].reply[j].inputShow && this.closeInput;
    },
    sendComment() {
      if (!this.textarea) {
        this.$message({
          showClose: true,
          type: "warning",
          message: "评论不能为空",
        });
      } else {
        let a = {};
        let timeNow = new Date().getTime();
        let time = this.dateStr(timeNow);
        a.name = this.myName;
        a.comment = this.textarea;
        a.time = time;
        a.commentNum = 0;
        a.like = 0;
        this.comments.push(a);
        this.replyComment = "";
        this.textarea = "";
      }
    },
    sendCommentReply(i) {
      if (!this.replytextarea) {
        this.$message({
          showClose: true,
          type: "warning",
          message: "评论不能为空",
        });
      } else {
        let a = {};
        let timeNow = new Date().getTime();
        let time = this.dateStr(timeNow);
        a.from = this.myName;
        a.to = this.to;
        a.comment = this.replytextarea;
        a.time = time;
        a.commentNum = 0;
        a.like = 0;
        this.comments[i].reply.push(a);
        this.replytextarea = "";
      }
    },
    dateStr(date) {
      //获取js 时间戳
      var time = new Date().getTime();
      //去掉 js 时间戳后三位,与php 时间戳保持一致
      time = parseInt((time - date) / 1000);
      //存储转换值
      var s;
      if (time < 60 * 10) {
        //十分钟内
        return "刚刚";
      } else if (time < 60 * 60 && time >= 60 * 10) {
        //超过十分钟少于1小时
        s = Math.floor(time / 60);
        return s + "分钟前";
      } else if (time < 60 * 60 * 24 && time >= 60 * 60) {
        //超过1小时少于24小时
        s = Math.floor(time / 60 / 60);
        return s + "小时前";
      } else if (time < 60 * 60 * 24 * 30 && time >= 60 * 60 * 24) {
        //超过1天少于30天内
        s = Math.floor(time / 60 / 60 / 24);
        return s + "天前";
      } else {
        //超过30天ddd
        var date = new Date(parseInt(date));
        return (
          date.getFullYear() +
          "/" +
          (date.getMonth() + 1) +
          "/" +
          date.getDate()
        );
      }
    },
    like() {
      if (this.likeOperate) {
        this.likeVal--;
        this.likeOperate = false;
      } else {
        this.likeVal++;
        this.likeOperate = true;
      }
    },
    unlike() {
      if (this.unlikeOperate) {
        this.unlikeVal--;
        this.unlikeOperate = false;
      } else {
        this.unlikeVal++;
        this.unlikeOperate = true;
      }
    },
  },
};
</script>

<style lang="scss" scoped>
>>> .conmment_drawer {
  .el-drawer__header {
    margin-bottom: 0px;
    padding: 10px 16px;
    border-bottom: 1px solid rgba(178, 186, 194, 0.3);
  }
}
.conmment_box {
  .my-reply {
    padding: 10px;
    background-color: rgba(245, 246, 247, 0.8);
    margin: 10px 16px;
    border-radius: 8px;
    .reply-info {
      display: inline-block;
      width: 100%;
      >>> .reply_input {
        .el-textarea__inner {
          background: rgba(245, 246, 247, 0.8);
          border: none;
          padding: 0px 6px;
        }
      }
    }
    .reply-btn-box {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0px 6px;
      margin-top: 10px;
      .limit {
        font-size: 12px;
        color: #999aaa;
        .num {
          color: #222226;
        }
      }
    }
  }
  .my-comment-reply {
    padding: 10px;
    background-color: #ffff;
    margin-top: 8px;
    border-radius: 8px;
    .reply-info {
      display: inline-block;
      width: 100%;
      >>> .reply_input {
        .el-textarea__inner {
          background: #ffff;
          border: none;
          padding: 0px 6px;
        }
      }
    }
    .reply-btn-box {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0px 6px;
      margin-top: 10px;
      .limit {
        font-size: 12px;
        color: #999aaa;
        .num {
          color: #222226;
        }
      }
    }
  }
  .author-title:not(:last-child) {
    border-bottom: 1px solid rgba(178, 186, 194, 0.3);
  }
  .author-title {
    padding: 10px 16px;
    .author-info {
      display: inline-block;
      width: 60%;
      line-height: 20px;
      > span {
        cursor: pointer;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .author-name {
        color: #000;
        font-size: 16px;
        font-weight: bold;
      }
      .author-time {
        margin-left: 6px;
        font-size: 12px;
        color: #aaa4a4;
      }
    }
    .icon-btn {
      width: 30%;
      padding: 0 !important ;
      float: right;
      text-align: right;
      font-size: 12px;
      color: #999aaa;

      > span {
        cursor: pointer;
      }
      .iconfont {
        font-size: 14px;
      }
    }
    .talk-box {
      margin-top: 8px;
      font-size: 14px;
      > p {
        margin: 0;
        color: #222226;
      }
      .reply {
        font-size: 14px;
        color: #000;
      }
    }
    .reply-box {
      margin: 10px 0 0 30px;
      background-color: #efefef;
      border-radius: 4px;
    }
  }
}
</style>

 

<think>好的,我现在需要帮助用户解决关于Dify循环实现的问题。首先,我需要明确用户的具体需求。他们提到“dify 循环实现”或“dify 如何处理循环”,但Dify本身可能没有直接称为“循环”的功能,所以需要结合现有文档中的信息来推断可能的解决方案。 根据用户提供的引用内容,Dify工作流中有迭代节点[^1]。这可能类似于编程中的循环结构,用于重复执行某个任务。例如,在处理列表数据或需要多次执行同一操作时,迭代节点可以派上用场。我需要详细解释迭代节点的配置和使用步骤,确保用户能够理解如何设置循环次数或遍历数据集。 另外,用户可能对如何处理循环中的错误或性能问题感兴趣。引用[2]提到在Dify中处理PEM文件的问题,这可能涉及在循环中正确处理数据格式,避免错误积累。需要提醒用户在循环中注意错误处理和资源管理,确保每次迭代的稳定性。 引用[3]中的例子展示了如何结合FastAPI和Selenium进行实时监控并生成GIF,这可能涉及循环截取浏览器内容。虽然Dify本身可能不直接控制这类循环,但可以通过外部脚本或定时任务触发工作流,模拟循环执行。这部分需要说明如何将外部循环机制与Dify结合使用。 接下来,我需要组织回答结构。首先介绍迭代节点的基本概念和配置步骤,然后讨论循环中的数据处理和错误处理,最后补充外部触发循环的方法。同时,生成相关问题以帮助用户进一步探索,比如优化循环性能或处理复杂数据结构。 需要确保回答符合格式要求,使用正确的中文表达,行内公式用$...$,独立公式用$$...$$,但当前问题不涉及数学公式,所以可能不需要使用。同时,引用标识要自然地添加到相关段落末尾,如、[^2]、[^3]。 最后,检查是否有遗漏点,比如Dify的其他循环相关功能或用户可能遇到的常见问题,确保回答全面且易于理解。</think>在Dify中处理循环逻辑主要通过**迭代节点**实现,以下是具体实现方式和应用场景的解析: ### 一、Dify循环实现机制 Dify通过**工作流设计器**中的迭代节点处理循环需求,其核心原理类似编程中的`for循环`。迭代节点可遍历以下数据类型: - 数组列表:`["A","B","C"]` - 字典集合:`{"key1":"value1", "key2":"value2"}` - 数值范围:通过`range()`函数生成序列 配置示例: ```python # 模拟迭代节点的数据输入 input_data = { "dataset": [1,2,3,4,5], "process_logic": "item * 2" # 对每个元素执行乘以2的操作 } ``` ### 二、迭代节点的关键配置步骤 1. **数据源绑定**:将数组/字典类型变量连接到迭代节点的输入端口 2. **循环变量命名**:设定当前元素的变量名(默认为`item`) 3. **子流程设计**:在迭代节点内部构建需要重复执行的逻辑模块 4. **结果聚合**:通过`outputs`收集所有迭代结果,支持数组或对象格式 $$ \text{总耗时} = \sum_{i=1}^{n}(单次迭代时间_i) + 系统开销 $$ ### 三、循环中的特殊处理 1. **错误中断控制**: - 启用`continueOnError`参数可跳过失败迭代 - 通过`try-catch`模块包裹敏感操作 2. **并行优化**: ```python # 伪代码示例 Parallel.forEach(dataset, lambda item: process(item)) ``` 3. **结果过滤**: ```python filtered = filter(lambda x: x%2==0, processed_results) ``` ### 四、应用场景案例 1. **批量文件处理**:遍历存储桶中的文件列表进行格式转换 2. **数据清洗**:对数据库查询结果集进行逐条校验 3. **API轮询**:定时循环调用第三方接口直到满足特定条件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值