Vue2+Element 封装评论+表情功能

有需要的小伙伴直接拿代码即可,不需要下载依赖。

评论组件如下:

创建 comment.vue 文件。

表情组件 VueEmoji.vue 在评论组件中使用。

<template>
  <div class="comment">
    <div class="flex_box">
      <h2>评论 {{total}}</h2>
      <p>文明上网理性发言</p>
    </div>
    <div class="comment-header">
      <div class="header_children">
        <i class="el-icon-user-solid img_width"></i>
        <el-input
          :placeholder="placeholderText"
          v-model="context"
          class="input"
          type="textarea"
          resize="none"
          size="mini"
          clearable
          :maxlength="contentLength"
          @focus="isShowSecReply(undefined)"
        ></el-input>
      </div>
      <div class="header_btn">
        <!-- 表情 -->
        <vue-emoji @chooseEmoji="chooseEmoji"></vue-emoji>
        <el-button
          type="primary"
          style="height: 40px"
          @click="addComment()"审核
        >{{ buttonText }}</el-button>
      </div>
    </div>
    <div v-loading="bigLoading">
      <div class="comment-body" v-for="(item, index) in comments" :key="item.id + '' + index">
        <!-- 一级评论 -->
        <div class="first-comment">
          <i class="el-icon-user-solid img_width"></i>
          <div class="content">
            <!-- 一级评论用户昵称 -->
            <div style="display: flex;align-items: center;">
              <h3>{{ item.memberName }}</h3>
              <span v-if="item.auditStatus == '0'" style="color: #ddab16;margin-left: 10px">(待审核)</span>
            </div>
            <!-- 一级评论发布时间 -->
            <span>{{ item.createTime }}</span>
            <!-- 一级评论评论内容 -->
            <p>{{ item.commentContent }}</p>
            <!-- 一级评论评论点赞 -->
            <div class="comment-right">
              <i
                class="el-icon-chat-dot-round"
                @click="isShowSecReply(item)"
              >回复</i>
              <i
                v-if="userInfor.memberName == item.memberName"
                class="el-icon-delete"
                @click="deleteComment(item, undefined)"
              >删除</i>
            </div>
            <!-- 回复一级评论 -->
            <div class="reply-comment" v-show="isShowSec === item.id">
              <el-input
                :placeholder="placeholderText"
                class="input"
                v-model.trim="replyContext"
                :maxlength="contentLength"
                clearable
              ></el-input>
              <div class="flex_one_box">
                <!-- 表情 -->
                <vue-emoji @chooseEmoji="chooseEmoji" :layer="comments"></vue-emoji>
                <el-button
                  type="primary"
                  size="mini"
                  class="reply-button"
                  @click="addComment(item)"
                >回复</el-button>
              </div>
            </div>
            <!-- 次级查看更多 -->
            <div class="li_top" v-if="item.commentReplyInfoList?.length > 0" @click="hanlePublicTotal(item)">
              <span style="color: rgb(21 66 231);">共{{item.commentReplyCount}}条评论</span>
              <i class="el-icon-caret-bottom" v-show="item.publicTotal"></i>
              <i class="el-icon-caret-top" v-show="!item.publicTotal"></i>
            </div>
            <!-- 次级评论 -->
            <ul v-infinite-scroll="load(item.commentReplyInfoList)" infinite-scroll-delay="200" style="overflow:auto" class="infinite_list" v-if="item.publicTotal"> 
              <li v-for="(reply, index) in item.commentReplyInfoList" :key="reply.id + '' + index">
                <!-- 次级评论头像,该用户没有头像则显示默认头像 -->
                <template>
                  <div class="second-comment">
                    <i class="el-icon-user-solid img_width"></i>
                    <div class="content">
                      <!-- 次级评论用户昵称 -->
                      <div style="display: flex;align-items: center;">
                        <h3>{{ reply.memberName }}</h3>
                        <span v-if="reply.auditStatus == '0'" style="color: #ddab16;margin-left: 10px">(待审核)</span>
                      </div>
                      <!-- 次级评论评论时间 -->
                      <span>{{ reply.createTime }}</span>
                      <span class="to_reply">{{ reply.memberName }}</span>
                      回复
                      <span class="to_reply">{{ reply.replyMemberName }}</span>:
                      <p>{{ reply.commentContent }}</p>
                      <!-- 次级评论评论点赞 -->
                      <div class="comment-right">
                        <i
                          class="el-icon-chat-dot-round"
                          @click="isShowSecReply(reply)"
                        >回复</i>
                        <i
                          v-if="userInfor.memberName == reply.memberName"
                          class="el-icon-delete"
                          @click="deleteComment(item, reply)"
                        >删除</i>
                      </div>
                      <div class="reply-comment" v-show="isShowSec === reply.id">
                        <el-input
                          :placeholder="placeholderText"
                          class="input"
                          v-model.trim="replyContext"
                          :maxlength="contentLength"
                          clearable
                        ></el-input>
                        <div class="flex_one_box">
                          <!-- 表情 -->
                          <vue-emoji @chooseEmoji="chooseEmoji" :layer="item.commentReplyInfoList"></vue-emoji>
                          <el-button
                            type="primary"
                            size="mini"
                            class="reply-button"
                            @click="addComment(item,reply)"
                          >回复</el-button>
                          </div>
                      </div>
                    </div>
                  </div>
                </template>
              </li>
              <el-button class="loading_p" type="primary" size="mini" v-if="item.moreValue" :loading="childrenMorelist.loading" @click="changeChildrenMore(item)">加载更多</el-button>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <!-- 一级查看更多 -->
    <el-button type="info" class="moreBtn" :loading="morelist.loading" @click="changeMore" v-if="morelist.value">
      查看更多评论
      <i class="el-icon-caret-bottom"></i> 
    </el-button>
    <!-- <div v-else class="more_div">暂无更多评论</div> -->
    <!-- 暂无评论的空状态 -->
    <el-empty :description="emptyText" v-if="comments.length === 0"></el-empty>
  </div>
</template>
<script>
export default {
  props: {
    sourceType: {
      type: String,
      require: true
    },
    articleId: {
      //评论所属文章 id
      type: String
    },
    emptyText: {
      // 评论为空的时候显示的文字
      type: String,
      default: "期待你的评论!"
    },
    buttonText: {
      // 按钮文字
      type: String,
      default: "评论"
    },
    contentLength: {
      // 评论长度
      type: Number,
      default: 150
    },
    placeholderText: {
      // 默认显示文字
      type: String,
      default: "请输入最多150字的评论..."
    }
  },
  data() {
    return {
      bigLoading: false,
      userInfor: {},
      params: {
        pageNum: "1",
        pageSize: "5",
        orderByColumn: "createTime",
        isAsc: "asc",
        sourceType: this.sourceType,
        mainId: "",
      },
      pantPageNum: "1", // 父级查看更多
      total: 0,
      comments: [
        {
          auditStatus: "1", // 审核状态
          auditTime: "2024-05-27", // 审核时间
          auditUserId: null,
          commentContent: "999", // 内容
          commentReplyCount: 1, // 二级回复条数
          commentReplyInfoList: [], // 二级回复数组
          createBy: "admin", // 
          createTime: "2024-05-27 01:39:18",
          id: 242,
          ids: null,
          mainId: 0,
          memberId: 1, // 哪条详情下评论的详情id
          memberName: "admin", // 用户名
          operationUserName: "自动通过",
          parentId: 0, // 父级id
          remark: null,
          replyMemberName: null, // 回复的用户名
          sourceId: "20",
          sourceType: "1", // 类型
          title: null,
          updateBy: "系统"
        }
      ], // 获取得到的评论
      context: "", // 评论内容
      replyContext: "", //一级评论回复
      isShowSec: "", //是否显示次级回复框
      isClickId: "", //记录点击回复的评论id
      morelist: {
        index: '2',
        value: false,
        loading: false,
      },
      childrenMorelist: {
        index: '2',
        childrenId: "",
        childrenPageNum: "1", // 子级查看更多
        childrenTotal: 0,
        value: false,
        loading: false,
      },
    };
  },
  mounted() {
    this.userInfor = localStorage.getItem("userInfor") ? JSON.parse(localStorage.getItem("userInfor")) : {};
    // 获取评论数据
    this.getCommentList();
  },
  computed: {
    isLogin() {
      return this.$store.getters.isLogin;
    },
  },
  methods: {
    chooseEmoji(layer,val) {
      if(layer) {
        this.replyContext += val;
        return;
      }
      this.context += val;
    },
    // 查看更多评论
    async changeMore() {
      this.morelist.loading = true;
      this.pantPageNum++;
      this.params.pageNum = this.pantPageNum;
      console.log("this.params.pageNum",this.params.pageNum);
      let res = await this.getNewList();
      res.rows.map(item => {
        this.$set(item,'publicTotal',false)
      })
      this.comments.push(...res.rows);
      this.morelist.loading = false;
      this.total = res.total;
      if(res.total > this.params.pageNum * this.params.pageSize) {
        this.morelist.value = true;
      }else {
        this.morelist.value = false;
      }
    },
    // 加载更多
    async changeChildrenMore(item) {
      if(this.childrenMorelist.childrenId && this.childrenMorelist.childrenId != item.id) {
        this.childrenMorelist.childrenPageNum = "1";
      }
      this.childrenMorelist.childrenId = item.id;
      this.childrenMorelist.loading = true;
      this.childrenMorelist.childrenPageNum++;
      this.params.pageNum = this.childrenMorelist.childrenPageNum;
      this.params.mainId = item.id;
      let res = await this.getNewList();
      this.childrenMorelist.childrenTotal = res.total;
      console.log("res",res);
      item.commentReplyInfoList.push(...res.rows);
      this.childrenMorelist.loading = false;
      if(res.total > this.params.pageNum * this.params.pageSize) {
        item.moreValue = true;
      }else {
        item.moreValue = false;
      }
    },
    load(list) {
      list += 2
    },
    // 唤起文件选择
    handleClick() {
      this.$refs.avatar.click();
    },
    // 获取本篇文章所有评论
    async getCommentList() {
      try {
        this.comments = [];
        this.bigLoading = true;
        // 获取某篇文章下的所有评论
        const res = await this.$get(`/api/comment/list?pageNum=${this.params.pageNum}&pageSize=${this.params.pageSize}&orderByColumn=${this.params.orderByColumn} desc,auditStatus&isAsc=${this.params.isAsc}&sourceType=${this.params.sourceType}&mainId=${this.params.mainId}&sourceId=${this.$route.query.id}`)
        this.bigLoading = false;
        this.comments = res.rows; //评论列表
        this.total = res.total; //评论总数
        if(this.total > this.params.pageSize) {
          this.morelist.value = true;
        }else {
          this.morelist.value = false;
        }
        this.comments.map(item => {
          if(item.commentReplyCount > 5) {
            item.moreValue = true;
          }else {
            item.moreValue = false;
          }
          this.$set(item,'publicTotal',false)
        }) 
      } catch (err) {
        this.bigLoading = false;
        this.$message.error(err);
      }
    },
    async getNewList() {
      let res = await this.$get(`/api/comment/list?pageNum=${this.params.pageNum}&pageSize=${this.params.pageSize}&orderByColumn=${this.params.orderByColumn} desc,auditStatus&isAsc=${this.params.isAsc}&sourceType=${this.params.sourceType}&mainId=${this.params.mainId}&sourceId=${this.$route.query.id}`);
      console.log("res1111",res);
      return res;
    },
    // 控制二级条数显示盒子
    hanlePublicTotal(item) {
      item.publicTotal = !item.publicTotal;
      console.log("item",item);
    },
    isShowSecReply(item) {
      console.log("一级input获取焦点",item);
      let id = item?.id;
      if (id) {
        this.isShowSec = id;
        if (this.isClickId === this.isShowSec) {
          this.isShowSec = "";
        } else {
          this.isShowSec = id;
        }
        this.isClickId = this.isShowSec;
      } else {
        this.isShowSec = this.isClickId = "";
      }
    },
    // 删除
    deleteComment(item, reply) {
      if(!this.isLogin) {
        this.$message.warning("请先登录!");
        return;
      }
      let _id = item.id;
      let replyId = reply?.id;
      if (replyId) {
        // 删除二级评论,提交请求到后端
        this.$confirm('确认删除此评论?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$put(`/api/comment/${replyId}`).then(async (res) => {
            if (res.code === 200) {
              this.params.pageNum = '1';
              let data = await this.getNewList();
              console.log("data",data);
              item.commentReplyCount = data.total;
              item.commentReplyInfoList.splice(0);
              item.commentReplyInfoList.push(...data.rows);
              //
              this.$message({
                message: "删除成功",
                type: "success",
              });
            }
          });
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        })
      } else {
        // 删除一级评论,提交请求到后端
        this.$confirm('确认删除此评论?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$put(`/api/comment/${_id}`).then((res) => {
            if (res.code === 200) {
              this.$message({
                message: "删除成功",
                type: "success",
              });
              this.params.pageNum = '1';
              this.getCommentList();
            }
          });
          this.total--;
          if(this.total == this.params.pageSize) {
            this.morelist.value = false;
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        })
      }
    },
    // 评论添加成功,返回的数据
    async addComment(item,reply) {
      console.log(">>>>item",item );
      if(!this.isLogin) {
        this.$message.warning("请先登录!");
        return;
      }
      //本地更新评论列表
      if (item) {
        // 添加二级评论
        if (!this.replyContext) {
          this.$message.warning("评论或留言不能为空哦!");
          return;
        }
        this.addSecond(item,reply);
      } else {
        // 添加一级评论,提交数据到后端
        if (!this.context) {
          this.$message.warning("评论或留言不能为空哦!");
          return;
        }
        this.addFirst();
      }
      this.isShowSec = this.isClickId = "";
    },
    addSecond(item,reply) {
      // 模拟数据提交成功后返回数据
      let data = {
        mainId: item.id,
        parentId: item.id,
        sourceType: item.sourceType,
        sourceId: this.$route.query.id, 
        commentContent: this.replyContext //评论内容
      };
      if(reply) {
        data.parentId = reply.id;
      }
      this.$post("/api/comment",data).then(async(res) => {
        if(res.code == 200) {
          this.params.mainId = item.id;
          let res = await this.getNewList();
          if(!item.commentReplyInfoList) {
            item.commentReplyInfoList = [];
          }
          item.commentReplyInfoList.splice(0);
          item.commentReplyInfoList.push(...res.rows);
          item.commentReplyCount = res.total;
          if(res.total > 5) {
            item.moreValue = true;
          }
          this.replyContext = "";
          console.log("comments",this.comments);
        }
      })
    },
    addFirst() {
      // 模拟数据提交成功后返回数据
      let data = {
        mainId: '',
        parentId: '',
        sourceType: this.sourceType,
        sourceId: this.$route.query.id, 
        commentContent: this.context //评论内容
      };
      this.$post("/api/comment",data).then(async(res) => {
        if(res.code == 200) {
          this.params.mainId = '';
          let res = await this.getNewList();
          res.rows.map(item => {
            this.$set(item,'publicTotal',false)
          })
          this.comments = res.rows;
          this.context = "";
          this.total = res.total;
          if(res.total > 5) {
            this.morelist.value = true;
          }
        }
      })
    },
  }
};
</script>
<style lang="scss" scoped>
.comment {
  min-height: 26vh;
  border-radius: 5px;
  margin-top: 2px;
  overflow: hidden;
  h3 {
    margin: 5px 0;
  }
  p {
    margin: 3px 0;
  }
  ul {
    list-style-type: none;
  }
  .img_width {
    max-width: 50px;
    max-height: 50px;
    border-radius: 50px;
    font-size: 30px;
    color: #3339;
  }
  .flex_box {
    padding: 0 5px;
    display: flex;
    align-items: center;
    margin-bottom: 30px;
    h2 {
      margin: 0;
    }
    p {
      font-size: 16px;
      color: #666;
      margin: 0 0 0 20px;
    }
  }
  .active {
    color: rgb(202, 4, 4);
  }
  .comment-header {
    position: relative;
    // height: 50px;
    padding: 10px 5px;
    // display: flex;
    // align-items: center;
    .header_children {
      display: flex;
      align-items: center;
    }
    .header_btn {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 20px 0 60px;
      margin-top: 10px;
    }

    .input {
      margin-left: 10px;
      margin-right: 20px;
      flex: 1;
      font-size: 14px;
      ::v-deep .el-input__inner:focus {
        border-color: #dcdfe6;
      }
    }
  }

  .comment-body {
    font-size: 14px;
    .first-comment {
      display: flex;
      padding: 10px 20px;
      .input {
        ::v-deep.el-input__inner:focus {
          border-color: #dcdfe6;
        }
      }
      i {
        margin-right: 5px;
        margin-left: 1vw;
        cursor: pointer;

        // &:nth-child(3) {
        //   color: rgb(202, 4, 4);
        // }
      }

      .content {
        margin-left: 10px;
        position: relative;
        flex: 1;

        & > span {
          font-size: 12px;
          color: rgb(130, 129, 129);
        }

        .comment-right {
          position: absolute;
          right: 0;
          top: 0;
        }

        .reply-comment {
          // height: 60px;
          // display: flex;
          // align-items: center;
          .flex_one_box {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 10px;
          }

          .reply-button {
            margin-left: 20px;
            height: 35px;
          }
        }
        .li_top {
          width: 200px;
          cursor: pointer;
          padding-left: 50px;
        }

        .infinite_list {
          max-height: 333px;
        }

        .second-comment {
          display: flex;
          padding: 10px 0 10px 5px;
          border-radius: 20px;
          background: #ffffff;
          .to_reply {
            // color: rgb(126, 127, 128);
            color: #0d74e1;
          }
        }
        .loading_p {
          cursor: pointer;
          margin: 3px auto;
          display: flex;
          justify-content: center;
        }
      }
    }
  }

  .moreBtn {
    width: 100%;
    i {
      font-size: 16px;
    }
  }
  .more_div {
    display: flex;
    display: flex;
    justify-content: center;
    color: #66666694;
    font-size: 14px;
  }
  ::-webkit-scrollbar
  {
    width: 8px;
    height: 5px;
    background-color: #F5F5F5;
  }
  /*定义滚动条轨道 内阴影+圆角*/
  ::-webkit-scrollbar-track
  {
    -webkit-box-shadow: inset 0 0 6px #c0c0c0;
    border-radius: 10px;
    background-color: #f9f9f9;
  }
  /*定义滑块 内阴影+圆角*/
  ::-webkit-scrollbar-thumb
  {
    border-radius: 10px;
    -webkit-box-shadow: inset 0 0 6px #c0c0c0;
    background-color: #c0c0c0;
  }
}
</style>

表情组件如下:

1. 创建 VueEmoji.vue 文件。

<template>
    <div class="emoji">
        <ul class="emoji-default" v-show="isShowEmoji">
            <li v-for="(item, index) in emojiJson" :key="index"
                @click.stop="chooseEmojiDefault(item)">
                {{item}}
            </li>
        </ul>
        <div class="emoji-tabs">
            <div :class="!isShowEmoji ? 'emoji-tab' : 'new_tab'" @click="isShowEmoji = !isShowEmoji">
                {{ isShowEmoji ? '收起' : emojiJson[4]}}
            </div>
        </div>
    </div>
</template>

<script>

const emojiJson = require("../utils/emoji.json");

export default {
  props: {
    keyId: {
      type: String,
      required: false
    },
    layer: {
      type: Array || Object,
      required: false
    }
  },
  data() {
    return {
      emojiJson: emojiJson.data.split(','),
      isShowEmoji: false,
    }
  },
  methods: {
    chooseEmojiDefault(item) {
      console.log("item",item);
      this.$emit("chooseEmoji",this.keyId,this.layer,item);
      this.isShowEmoji = false;
    }
  }
}

</script>

<style lang="scss" scoped>
// 纵向滚动条
@mixin scroll-bar($width: 10px) {
    &::-webkit-scrollbar-track {
        border-radius: 10px;
        background-color: #ffffff;
    }
    &::-webkit-scrollbar {
        width: $width;
        height: 10px;
        background-color: #ffffff;
    }
    &::-webkit-scrollbar-thumb {
        border-radius: 10px;
        background-color: rgba(0, 0, 0, 0.2);
    }
}

.emoji {
    text-align: left;
    // width: 100%;
    // height: 100%;
    background: #fff;
    // border: 1px solid #dcdfe6;
    box-shadow: 0 2px 4px 0 rgb(0 0 0 / 12%), 0 0 6px 0 rgb(0 0 0 / 4%);

    .emoji-tabs {
        // border-top: 1px solid #DCDFE6;
        background: #f8f8f8;

        .emoji-tab {
          cursor: pointer;
          background: #ffffff;
          /* height: 100%; */
          /* padding: 5px 5px; */
          /* overflow: hidden; */
          text-align: center;
          /* line-height: 15px; */
          font-size: 25px
        }
        .new_tab {
          cursor: pointer;
          font-size: 14px;
          color: #1c33e5;
          text-align: center;
          padding: 5px 0;
        }
    }


    .emoji-default {
        width: calc(100% - 40px);
        height: 202px;
        overflow-y: auto;
        @include scroll-bar();
        padding: 0px 20px;

        li {
            display: inline-block;
            padding: 5px;
            font-size: 24px;
            width: 29px;
            height: 29px;
            overflow: hidden;
            cursor: pointer;
        }

        li:hover {
            background-color: #d5d5d5;
        }
    }
}

</style>

2. 在写公共方法的地方创建 emoji.json 文件,里面是表情的数据,内容如下:

{
  "data": "😀,😁,😂,😃,😄,😅,😆,😉,😊,😋,😎,😍,😘,😗,😙,😚,😇,😐,😑,😶,😏,😣,😥,😮,😯,😪,😫,😴,😌,😛,😜,😝,😒,😓,😔,😕,😲,😷,😖,😞,😟,😤,😢,😭,😦,😧,😨,😬,😰,😱,😳,😵,😡,😠,💘,❤,💓,💔,💕,💖,💗,💙,💚,💛,💜,💝,💞,💟,❣,💪,👈,👉,☝,👆,👇,✌,✋,👌,👍,👎,✊,👊,👋,👏,👐,✍,🍇,🍈,🍉,🍊,🍋,🍌,🍍,🍎,🍏,🍐,🍑,🍒,🍓,🍅,🍆,🌽,🍄,🌰,🍞,🍖,🍗,🍔,🍟,🍕,🍳,🍲,🍱,🍘,🍙,🍚,🍛,🍜,🍝,🍠,🍢,🍣,🍤,🍥,🍡,🍦,🍧,🍨,🍩,🍪,🎂,🍰,🍫,🍬,🍭,🍮,🍯,🍼,☕,🍵,🍶,🍷,🍸,🍹,🍺,🍻,🍴,🌹,🍀,🍎,💰,📱,🌙,🍁,🍂,🍃,🌷,💎,🔪,🔫,🏀,⚽,⚡,👄,👍,🔥,🙈,🙉,🙊,🐵,🐒,🐶,🐕,🐩,🐺,🐱,😺,😸,😹,😻,😼,😽,🙀,😿,😾,🐈,🐯,🐅,🐆,🐴,🐎,🐮,🐂,🐃,🐄,🐷,🐖,🐗,🐽,🐏,🐑,🐐,🐪,🐫,🐘,🐭,🐁,🐀,🐹,🐰,🐇,🐻,🐨,🐼,🐾,🐔,🐓,🐣,🐤,🐥,🐦,🐧,🐸,🐊,🐢,🐍,🐲,🐉,🐳,🐋,🐬,🐟,🐠,🐡,🐙,🐚,🐌,🐛,🐜,🐝,🐞,🦋,😈,👿,👹,👺,💀,☠,👻,👽,👾,💣"
}

在 Vue 文件中使用,如下:

<template>
    <div>
       <comment :buttonText="'发表评论'"/>
    </div>
</template>

效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654042.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Amazon云计算AWS(一)

目录 一、基础存储架构Dynamo&#xff08;一&#xff09;Dynamo概况&#xff08;二&#xff09;Dynamo架构的主要技术 二、弹性计算云EC2&#xff08;一&#xff09;EC2的基本架构&#xff08;二&#xff09;EC2的关键技术&#xff08;三&#xff09;EC2的安全及容错机制 提供的…

【C++】vector的基本使用

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. vector初始化 2. vector iterator 的使用 2.1 常规遍历 2.2 rbegin rend 反向遍历 3. vector 常见函数使用 3.1 …

N1912A P 系列双通道功率计

N1912A 双通道功率计 产品综述 <<<P 系列双通道功率计>>> Keysight N1912A P 系列双通道功率计可以提供峰值功率、峰均比、平均功率、上升时间、下降时间 NS 脉冲宽度测量。 “ 功能特点 30 MHz 视频带宽 能够以高达 100 MSa/s 的采样率执行单次实时捕…

全新交友盲盒+付费进群二合一源码 包含全套源码+教程

盲盒交友脱单系统源码&#xff0c;带教程&#xff0c;免授权这套源码已经替你们搭建测试过了 附带进群系统&#xff0c;定位是正常的 申明需要无限回调&#xff0c;没有回调的搭建出来不能用不要说源码不能用 全新系统方便大家使用&#xff0c;已经录制好详细的教程&#xf…

AIGC 007-E4T基于编码器的域调优用于文本到图像模型的快速个性化!

AIGC 007-E4T基于编码器的域调优用于文本到图像模型的快速个性化&#xff01; 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 这篇论文提出了一种使用领域特定编码器来快速将文本到图像模型适配到新领域的方案。这种被称为基于编码器的领域微调 (E4T) 的方法&#xff0c;专…

不怕YOLOv10高歌猛进,我有YOLOv8稳扎稳打

YOLOv10 出来有几天时间了&#xff0c;这次我没有选择第一时间出文章解析&#xff0c;如此频繁的发布数字版本的 YOLO 着实让人头疼&#xff0c;虽然数字的更新并非旧版技术的过时&#xff0c; 但是这肯定会让很多在校同学增加很多焦虑情绪。这里还是请大家辩证看待。 v10 这次…

C语言编译链接

翻译环境和运行环境 翻译环境 翻译环境就是在这将源代码转换成可执行的二进制指令&#xff08;机器指令&#xff09;。 进行编译和链接过程。 .c源程序先单独经过编译器生成对应的目标文件.obj&#xff08;在windows环境下&#xff09;.o&#xff08;在Linux环境下&#xff…

CRMEB开源商城系统:全开源、高灵活性的电商解决方案

一、引言 随着电子商务的飞速发展&#xff0c;越来越多的企业和个人开始关注如何快速搭建一个稳定、高效且功能丰富的在线商城系统。在这样的背景下&#xff0c;CRMEB开源商城系统应运而生&#xff0c;凭借其前后端分离的架构、丰富的功能模块以及易用性&#xff0c;成为了众多…

C++模板——非类型模板参数、模板的特化以及模板的分离编译

目录 非类型模板参数 模板的特化 概念 函数模板特化 类模板特化 全特化 偏特化 模板的分离编译 什么是分离编译 模板的分离编译 解决方法 模板总结 非类型模板参数 模板参数可分为类型形参和非类型形参。类型形参&#xff1a; 出现在模板参数列表中&#xff0c;跟…

【python】删除一个列表中的所有的1

删除所有的1 x [1, 1, 6, 3, 9, 4, 5, 1, 1, 2, 1, 9, 6, 4] 使用lambda函数和filter来过滤掉x中的1 filtered_x list(filter(lambda n: n ! 1, x)) 不是1的数字&#xff0c;存进x列表&#xff0c;filter用于插入元素到第二个位置 print(filtered_x) # 输出: [6, 3, 9, …

第13章 层次式架构设计理论与实践

层次式架构的核心思想是将系统组成为一种层次结构&#xff0c;每一层为上层服务&#xff0c;并作为下层客户。其实不管是分层还是其他的架构都是为了解耦&#xff0c;更好的复用&#xff0c;只要秉承着这种思想去理解一切都迎刃而解了。 13.1 层次上体系结构概述 回顾一下软件…

【docker】安装harbor出现问题: Running 1/1 ✘ Network harbor_harbor Error

安装harbor出现问题&#xff1a; [] Running 1/1 ✘ Network harbor_harbor Error 0.2s failed to create network harbor_harbor: Error response from daemon: Fa…

节水“云”科普丨北京昌平VR节水云展馆精彩上线

2024年5月15日上午&#xff0c;由北京昌平区水务局主办的“推进城市节水&#xff0c;建设美丽昌平——2024年全国城市节约用水宣传周暨‘坚持节水优先 树立节水标杆’昌平节水在行动主题实践活动”隆重举办&#xff0c;活动期间&#xff0c;昌平区水务局应用VR虚拟现实技术创新…

目标检测数据集 - 工地工人安全设备佩戴检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;工地工人安全设备佩戴检测数据集&#xff0c;真实场景数据生成增强后高质量图片数据&#xff0c;涉及场景丰富&#xff0c;比如楼宇建筑工地工人作业数据、道路建筑工地工人作业数据、室内工地工人作业数据、露天挖掘场景工人作业数据、工地工人自拍摆拍…

【数据分析】Numpy和Pandas库基本用法及实例--基于Japyter notebook实现

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 承接上篇的博客 数据分析—技术栈和开发环境搭…

使用Java 读取PDF表格数据并保存到TXT或Excel

目录 导入相关Java库 Java读取PDF表格数据并保存到TXT Java读取PDF表格数据并保存到Excel 在日常工作中&#xff0c;我们经常需要处理来自各种来源的数据。其中&#xff0c;PDF 文件是常见的数据来源之一。这类文件通常包含丰富的信息&#xff0c;其中可能包含重要的表格数据…

大数据面试题 —— Hive

目录 Hive 是什么为什么要使用 HiveHive 的优缺点Hive的实现逻辑&#xff0c;为什么处理小表延迟比较高你可以说一下 HQL 转换为 MR 的任务流程吗 ***你可以说一下 hive 的元数据保存在哪里吗 ***Hive与传统数据库之间的区别Hive内部表和外部表的区别 ***hive 动态分区与静态分…

28 Debian如何配置PXE网络装机(全自动无人值守)

作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian如何配置PXE网络装机(全自动无人值守) 《傅老师Debian小知识库系列之28》——原创 ==前言== 傅老师Debian小知识库特点: 1、最小化拆解Debian实用技能; 2、所有操作在VMware虚拟机实测完成…

Rocky Linux 9.4 正式版发布 - RHEL 100% 1:1 兼容免费发行版

Rocky Linux 9.4 正式版发布 - RHEL 100% 1:1 兼容免费发行版 Rocky Linux 由 CentOS 项目的创始人 Gregory Kurtzer 领导 请访问原文链接&#xff1a;Rocky Linux 9.4 正式版发布 - RHEL 100% 1:1 兼容免费发行版&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…

登录记住密码背景颜色修改

1&#xff0c;在login.vue中&:-webkit-autofill里面的css替换成如下 &:-webkit-autofill {box-shadow: 0 0 0px 1000px $bg inset !important;-webkit-text-fill-color: $cursor !important;}