vue2模拟无限级评论

目录

一、效果展示

二、代码展示

2.1、主页面

2.2、评论父页面组件

2.3、评论多级页面(递归组件)

一、效果展示

二、代码展示

2.1、主页面

<template>
  <div>
    <h1>姓名:{{ $store.state.userInfo1.username }}</h1>
    <button
      :class="{ aactive: $store.state.userInfo1.id === 1 }"
      @click="shiftName({ id: 1, username: 'zhangsan' })"
    >
      张三
    </button>
    <button
      :class="{ aactive: $store.state.userInfo1.id === 2 }"
      @click="shiftName({ id: 2, username: 'lisi' })"
    >
      李四
    </button>
    <button
      :class="{ aactive: $store.state.userInfo1.id === 3 }"
      @click="shiftName({ id: 3, username: 'wangwu' })"
    >
      王五
    </button>
    <hr />
    <CommentOne></CommentOne>
  </div>
</template>
<script>
import CommentOne from "@/components/CommentOne.vue";
export default {
  components: {
    CommentOne,
  },
  methods: {
    shiftName(params) {
      this.$store.commit("UPDATE_NAME", params);
    },
  },
};
</script>
<style lang='less' scoped>
.aactive {
  background-color: black;
  color: white;
}
</style>

vuex切换账号:  主页面进行触发(this.$store.commit("UPDATE_NAME", params);)

  state: {
    userInfo1: {
      id: 1,
      username: 'zhangsan'
    },
  },
  mutations: {
    UPDATE_NAME(store, userInfo) {
      store.userInfo1 = userInfo
    }
  },

2.2、评论父页面组件

CommentOne.vue

<template>
  <div>
    <div>
      <p>
        <textarea v-model="commentText"></textarea>
      </p>
      <p>
        <button @click="addComment">提交评论</button>
      </p>
    </div>
    <!-- 评论列表 -->
    <ul>
      <CommentComp
        :data="formatTree(commentTree)"
        @addReply="addReply"
      ></CommentComp>
    </ul>
  </div>
</template>
<script>
import CommentComp from "./CommentComp.vue";
export default {
  components: {
    CommentComp,
  },
  data() {
    return {
      commentText: "",
      commentTree: JSON.parse(localStorage.getItem("one") || "[]"),
    };
  },
  methods: {
    addComment() {
      const { id, username } = this.$store.state.userInfo1;
      const commentInfo = {
        id: new Date().getTime(),
        pid: 0,
        uid: id,
        username,
        comment: this.commentText,
      };
      this.setComment("one", commentInfo);
      this.commentTree.unshift(commentInfo);
      this.commentTree = "";
    },
    //子传父事件
    addReply(item, replyTxt) {
      console.log(item, replyTxt, "fu");
      const { id, username } = this.$store.state.userInfo1;
      const replyInfo = {
        id: new Date().getTime(),
        pid: item.id,
        uid: id,
        username,
        comment: replyTxt,
      };
      (item.children || (item.children = [])).unshift(replyInfo);
      this.setComment("one", replyInfo);
    },
    setComment(field, comment) {
      //每提交一次,就将数据存起来
      const CommentList = JSON.parse(localStorage.getItem(field) || "[]");
      CommentList.unshift(comment);
      localStorage.setItem(field, JSON.stringify(CommentList));
      this.$nextTick(() => {
        this.commentTree = JSON.parse(localStorage.getItem(field) || "[]");
      });
    },
    // 数据格式化
    formatTree(data) {
      const result = [];
      const map = {};
      data.forEach((item) => {
        map[item.id] = item;
      });
      data.forEach((item) => {
        const parent = map[item.pid];
        if (parent) {
          (parent.children || (parent.children = [])).unshift(item);
        } else {
          result.unshift(item);
        }
      });
      return result;
    },
  },
};
</script>
<style>
</style>

2.3、评论多级页面(递归组件)

CommentComp.vue:  name: "CommentComp",组件递归,给自己加名字

<template>
  <div>
    <li v-for="(item, index) in data" :key="index">
      <p>{{ item.username }}</p>
      <p>{{ item.comment }}</p>
      <a href="javascript:;" @click="setReply(item)">回复</a>
      <div v-if="item.isReply">
        <p>
          <textarea v-model="item.replyTxt"></textarea>
        </p>
        <p>
          <button @click="addReply(item)">提交回复</button>
        </p>
      </div>
      <div v-if="item.children" style='padding-left:50px'>
        <CommentComp :data="item.children" @addReply="addReply"></CommentComp>
      </div>
    </li>
  </div>
</template>
<script>
export default {
  name: "CommentComp", //组件递归,给自己加名字
  props: ["data"],
  methods: {
    setReply(item) {
      this.$set(item, "isReply", !item["item.isReply"]);
      //   item.isReply = !item.isReply;(vue2不可以,vue3可以)
    },
    addReply(item) {
      const replyTxt = item.replyTxt;
      this.$emit("addReply", item, replyTxt);
      item.isReply = false; //关闭自己
      item.replyTxt = "";
      console.log(item, replyTxt, "zi");
    },
  },
};
</script>
<style>
</style>

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值