Laravel 实战开发知乎: 对答案进行点赞
打赏作者

medivhzhan

user的点赞和关注的api返回可以不可以这么写呢?

public function users($id)
{
    $user = Auth::guard('api')->user();

    return response()->json(['voted' => $user->hasVoted($id)]);
}

还有上面的 $user = Auth::guard(‘api’)->user(); 已经用了好几次,能不能直接封装个helperFunction呢?

JellyBool 回复 medivhzhan

完全可以的!!

liujun 回复 medivhzhan

json里面的好像不行 我试过 但是不知道为什么

wl876645

hasVotedFor方法中这样写好不好?
this>votes()>contains(this->votes()->contains(answer)

JellyBool 回复 wl876645

这个是跟之前实现过的 in_array 是差不多的,是查出来一个 collection 的数据,再判断这一堆数据是否有传入的 answer。

而视频中的是直接根据两个条件 (user_id,answer_id)来直接查询是否存在,个人觉得都是一次查询情况下,视频中的要稍微好一丢丢

wl876645 回复 JellyBool

明白了 谢谢~~~~

liujun 回复 wl876645

我一直这么写的

saraphimelvis

在最后的那段vue的代码中,我收到一个warning,没有办法直接编辑count参数。

“Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “count” ”

请问应该如何修改vue的代码?

Arun 回复 saraphimelvis

因为在2.0中prop取消双向绑定,数据流动只能是单向流动,而且在组件内不能修改外层传递进来的props数据,你只要在data中创建一个props属性的副本,然后去操作创建的副本应该就可以了。根据你的提示应该是这样的

weir2009

如果不用异步,用普通的刷新页面的方式来处理,像这样:
view:

<a href="/answer/{$answer->id}/votes" class="pull-right btn btn-default 
                            {Auth::user()->isVoted($answer->id) ? "btn-primary" : ""}">
                                {$answer->votes_count}
                            </a>
public function isVoted($answer_id)
    {
        $count = $this->votes()->where('answer_id', $answer_id)->count();
        if ($count > 0){
            $this->votes()->find($answer_id)->increment('votes_count');
            return true;
        }
        return false;
    }

流程是走通了,但是刷新页面点赞数就增加的问题,要怎么解决呢?

JellyBool 回复 weir2009

很正常吧,这个逻辑:

 $count = $this->votes()->where('answer_id', $answer_id)->count();
        if ($count > 0){
            $this->votes()->find($answer_id)->increment('votes_count');
            return true;
        }
weir2009 回复 JellyBool

那要怎么写才能解决问题呢,能给个思路吗?

JellyBool 回复 weir2009

this>votes()>find(this->votes()->find(answer_id)->increment(‘votes_count’);

这个删掉就好了吧。

weir2009 回复 JellyBool

但是删掉之后点赞数就不会变了。怎么把点赞数的处理从这个函数里面分离出来呢?

JellyBool 回复 weir2009

这个方法:

public function isVoted($answer_id)
    {
        $count = $this->votes()->where('answer_id', $answer_id)->count();
        if ($count > 0){
            $this->votes()->find($answer_id)->increment('votes_count');
            return true;
        }
        return false;
    }

跟点赞数增加或者减少不应该有任何的关系啊

yujiak

这个视频在大概20分钟的时候就播放不了了

JellyBool 回复 yujiak

恩,我这边重新修复了。。

北漂张小白

为什么$user = Auth::guard('api')->user();打印出来会是null呢?明明登陆了,followers 都能打印出user;

JellyBool 回复 北漂张小白

这个是使用的 api 的认证,靠的是 api_token 来认证的

北漂张小白 回复 JellyBool

是的,问题解决了,因为访问api的时候没有带apiToken。

JellyBool 回复 北漂张小白

嗯哼,相信再过一段时间,你也可以玩得很溜了。

北漂张小白 回复 JellyBool

我在努力…还是要向你学习,哈哈…

JellyBool 回复 北漂张小白

你是这个站中最认真和努力的几个之一,其他的那几个小伙伴感觉都小有成就了,比如这个 https://github.com/jcc

北漂张小白 回复 JellyBool

厉害厉害,我差有点远…

JellyBool 回复 北漂张小白

没差得远,等你顿悟就OK了,很快就可以找到自己的天地

RoseEnd

把之前一个用户删了之后,随便登录一个其他账号,打开首页就会出现Trying to get property of non-object错误

JellyBool 回复 RoseEnd

有些地方你需要注意判断登录进来才可以

RoseEnd

点赞的时候出现```vue.js?3de6:485 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “count”

found in

—> at /home/vagrant/Code/zhihu.app/resources/assets/js/components/UserVoteButton.vue
~~这个错误,但是功能可以正常使用!

JellyBool 回复 RoseEnd

这个是 warning ,新版的 vuejs 不推荐直接修改 props 的数据,你将props 的数据存到data先,再操作就好了

iopkq999

我想问一个问题,就是在vue获取后端数据,不是会在data那先return一个默认值吗?
例如这个voted:false

例如已经赞同了这个答案,每次我去刷新页面,这个按钮就总是会先显示白色(false),等请求结束后 才会显示蓝色的按钮。
如何才能直接显示 已赞同这个答案(蓝色按钮)

不知道我表述清楚没,

JellyBool 回复 iopkq999

使用 mounted 做请求,或者直接 props 传进来。在意 v-cloak 做隐藏就好。

iopkq999 回复 JellyBool

就是使用了mounted做请求,它会这样,先显示默认值,然后请求结束了,才会显示请求后的值。。。好郁闷啊 ,这样子用户体验很不好呢

iopkq999 回复 JellyBool
mounted() {
            axios.post('/api/answer/'+ this.answer + '/votes/users').then(response =>{
                this.voted = response.data.voted
            })
        },
        data() {
            return {
                voted: false,
                voted_count: this.count
            }
        },

它会先显示voted:false(白色按钮未投票),mounted请求完后把请求的voted赋值给this.voted true(请求完后才会显示蓝色按钮已投票)

JellyBool 回复 iopkq999

就使用 v-loack 来做 css 样式设置就好了:


        .order table.table thead>tr>th {
            font-weight: bolder;
            font-size: 16px;
        }
        [v-cloak] .v-cloak--block {
            display: block;
        }
        [v-cloak] .v-cloak--inline {
            display: inline;
        }
        [v-cloak] .v-cloak--inlineBlock {
            display: inline-block;
        }
        [v-cloak] .v-cloak--hidden {
            display: none;
        }
        [v-cloak] .v-cloak--invisible {
            visibility: hidden;
        }
        .v-cloak--block,
        .v-cloak--inline,
        .v-cloak--inlineBlock {
            display: none;
        }

    

使用 component 的时候这样:

<component v-cloak></component>
iopkq999 回复 JellyBool

不行诶 对于样式的闪烁是解决不了的,v-cloak对于{ }这个闪烁才有效

JellyBool 回复 iopkq999

那我就不知道了,我觉得是你那个地方没写对吧。

本站就是用的这种方式,感觉是可以的

iopkq999 回复 JellyBool

我问了一些做前端的朋友,他们说现在vue是得用动画去做一个loading的东西,然后vue v-show v-if这些去判断请求是否请求完成,请求完成后 就把loading动画去掉就好了。现在挺多网站都是这样做的 好像。jelly怎么看呢

JellyBool 回复 iopkq999

额。。。这个也是一个解决办法。v-cloak 就是 vue 官方给的解决方案。

https://www.codecasts.com/discuss/vue/vue-nested-loop-how-to-take-the-child-loop-data-length-2093

比如你点开这个链接,收藏那个就是 vue 的组件,应该满足你的需求。

Flourishing
如果Vuejs是2.0以上 不再支持直接对 props:里面的数据直接操作 我们可以建立副本 再来操作
props:['answer','count'],

        data() {
            return {
                voted :false ,
                voted_count: this.count
            }
        },
        computed: {
            text() {
                return this.voted_count
            }
        },
        methods:{
            vote() {
                axios.post('/api/answer/vote',{'answer':this.answer}).then(response => {
                    this.voted = response.data.voted
                    response.data.voted ? this.voted_count ++ : this.voted_count --
                })
            }
        }