封装vue 点赞或者收藏组件

  • 末尾有解释如何使用
  • 完整组件,粘贴复制即可用
  • 思路:
    1.进入页面,父组件将数据传递给子组件,数据包含:图标样式、字体图标是否高亮状态、请求地址、发送请求时需要的数据。
    2点击字体图标,动画+1或者-1效果出现,同时给后台发送请求,保存点赞状态。
  • 代码如下
<template>
    <div class="isZan-container">
      <span @click="addLike()" :class="{'isLike':likeClass}" class="container-inner">
          <transition @before-enter="beforeEnter" @enter="enter"
                      @after-enter="afterEnter">
              <span class="addOne" v-if="isLike">+1</span>
              <span class="cancleOne" v-if="like">-1</span>
          </transition>
          <i :class="[icon,{'isLike':likeClass}]"></i>
         {{getLikeClass.title }}:{{getLikeClass.technicalListDetail.t_zan}}
      </span>
    </div>
</template>

<script>

    import qs from 'qs';

    export default {
        name: "isLike",
        data() {
            return {
                isLike: false, // 点赞+1
                like: false, // 点赞-1
                likeClass: "", //点赞后样式改变
                commentLike_id: "",//请求数据时点赞Id
                postLike: "",
                cancleLike: "",
                icon: '',
            }
        },
        props: ['getLikeClass'],

        methods: {
            // 权限
            getCookie(name) {
                let value = '; ' + document.cookie;
                let parts = value.split('; ' + name + '=');
                if (parts.length === 2) return parts.pop().split(';').shift()
            },
            //点击增加收藏和点赞(动画和样式)
            addLike() {
                //判断是点赞
                if (this.likeClass) { //说明已经点赞,这次是取消
                    this.like = !this.like; //-1显示
                    this.likeClass = !this.likeClass; //样式还原
                    this.setLikeCount(); //请求点赞
                } else {
                    this.isLike = !this.isLike; //说明未点赞,这次是点赞,显示+1
                    this.likeClass = !this.likeClass;
                    this.setLikeCount();//请求点赞
                }
            },
            //发送请求记录点赞
            setLikeCount: function () {
                if (this.isLike) { //如果是点赞 +1
                    this.$http.post(this.postLike, qs.stringify({
                        'article_id': this.$route.query.id,
                        'from_uid': this.$store.state.userId,
                    }), {headers: {'X-CSRFToken': this.getCookie('csrftoken')}}).then((res) => {
                        res = res.data;
                        // console.log(res);
                        let error = res.errmsg; //请求数据时点赞Id
                        if (res.payload && !res.status) {
                            this.$message({
                                message: '谢谢您的点赞',
                                type: 'success',
                                duration: 800
                            });
                            this.$emit('getArticleDetail')
                        } else {
                            this.$message({
                                message: '' + error + ',请先登录',
                                type: 'fail',
                                duration: 500
                            })
                        }
                    }).catch(function (error) {
                        alert(error)
                    });
                } else {
                    this.$http.delete(this.cancleLike + this.commentLike_id + '/',
                        {headers: {'X-CSRFToken': this.getCookie('csrftoken')}})
                        .then((res) => {
                            res = res.data;
                            let error = res.errmsg;
                            // console.log(res);
                            if (res.payload && !res.status) {
                                this.$message({
                                    message: '已取消点赞',
                                    type: 'success',
                                    duration: 800,
                                });
                                this.$emit('getArticleDetail')
                            } else {
                                this.$message({
                                    message: '' + error + '',
                                    type: 'fail',
                                    duration: 8
                                })
                            }
                        });
                }
            },
            beforeEnter(el) {
                //动画开始进入前
                el.style.transform = "translate(0,0)"
            },
            enter(el, done) {
                // console.log(el);
                //动画执行时
                el.offsetWidth;
                el.style.transform = "translate(10px,-22px)";
                el.style.transition = "all 0.6s ease";
                done()
            },
            afterEnter(el) {
                //动画结束时
                // console.log(this.likeClass);
                if (this.likeClass) { // 如果是true动画出现的是+1,出现后再隐藏
                    this.isLike = !this.isLike;
                } else {
                    this.like = !this.like;
                }
            },
        },
        watch: {
            getLikeClass: {
                // 深度监听
                handler(val) {
                    this.commentLike_id = val.technicalListDetail.is_zan; //取消点赞时用
                    //进入详情页判断是否已经点赞
                    this.likeClass = this.commentLike_id !== undefined;
                    this.icon = val.icon;
                    this.postLike = val.postLike;
                    this.cancleLike = val.cancelLike;
                    // console.log(this.cancleLike)
                },
                deep: true

            }
        }
    }
</script>

<style scoped lang="stylus">
    .isZan-container {
        cursor: pointer
        font-size 14px
        color :grey
        .container-inner {
            position relative
            .isLike {  //点击后,图标选中样式
                color: #FF3300
            }
            .addOne { //动画+1
                position absolute
                right 0
                top: 0px
                font-size 20px
                font-weight bold
                color #FF3300
            }
            .cancleOne{ //-1的样式
                position absolute
                right 0
                top: 0
                font-size 20px
                font-weight bold
                color darkgreen
            }
            i {
                font-size 20px
            }

        }
        .container-inner:hover {
            /*color green*/
            font-size 16px
        }
    }


</style>
  • 父组件中传入的数据
  • giveFollow : { technicalListDetail: { // 在进入页面时请求数据获取 t_zan: "", is_zan: '' }, icon: "icon-ali-appreciate", postLike: API.appreciateArticle_list, cancelLike: API.appreciateArticle_detail, title: "点赞数" },
  • 使用:在父组件中
  • 解释:giveFollow是父组件传递给子组件的数据,getArticleDetail是父组件才加载时就获取数据的函数。
   <is-like :getLikeClass="giveFollow" @getArticleDetail="getArticleDetail"></is-like>
           
  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值