83.最佳回复(四)

未匹配的标注

本节说明

  • 对应视频教程第 83 小节:Thread Authorization

本节内容

到目前为止,我们的最佳回复功能还剩最后一个小地方需要处理,那就是Best Rply按钮的权限问题。在目前,所有人都能看见按钮,这与我们的初衷不符。我们只让话题的创建者有权限看见。首先我们来重构下权限文件:
forum\resources\assets\js\authorizations.js

let user = window.App.user;

module.exports = {
    owns (model,prop = 'user_id') {
        return model[prop] == user.id;
    }
};

现在我们可以只用owns方法,就可以判断当前用户是否是threadreplyowner。我们来加上权限控制:
forum\resources\assets\js\components\Reply.vue

    .
    .
    <div class="panel-footer level" v-if="authorize('owns',reply) || authorize('owns',reply.thread)">
            <div v-if="authorize('owns',reply)">
                <button class="btn btn-xs mr-1" @click="editReply">Edit</button>
                <button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
            </div>

            <button class="btn btn-xs btn-default ml-a" @click="markBestReply" v-if="authorize('owns',reply.thread)">Best Reply</button>
        </div>
        .
        .

最后地最后,我们对组件做点小重构。我们为Reply组件设置了data属性,但是可读性不如直接命名为reply。我们按照这个方向进行重构:
forum\resources\assets\js\components\Replies.vue

    .
    .
    <div v-for="(reply ,index) in items" :key="reply.id">
            <reply :reply="reply" @deleted="remove(index)"></reply>
        </div>
        .
        .

reply代替datathis.id代替this.data.id
forum\resources\assets\js\components\Reply.vue

<template>
    <div :id="'reply'+id" class="panel" :class="isBest ? 'panel-success' : 'panel-default'">
        <div class="panel-heading">
            <div class="level">
                <h5 class="flex">
                    <a :href="'/profiles/'+reply.owner.name"
                        v-text="reply.owner.name">
                    </a> said <span v-text="ago"></span>
                </h5>

                <div v-if="signedIn">
                    <favorite :reply="reply"></favorite>
                </div>
            </div>
        </div>

        <div class="panel-body">
            <div v-if="editing">
                <form @submit.prevent="update">
                    <div class="form-group">
                        <textarea class="form-control" v-model="body" required></textarea>
                    </div>

                    <button class="btn btn-xs btn-primary" >Update</button>
                    <button class="btn btn-xs btn-link" @click="cancelReply" type="button">Cancel</button>
                </form>
            </div>

            <div v-else v-html="body"> </div>
        </div>

        <div class="panel-footer level" v-if="authorize('owns',reply) || authorize('owns',reply.thread)">
            <div v-if="authorize('owns',reply)">
                <button class="btn btn-xs mr-1" @click="editReply">Edit</button>
                <button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
            </div>

            <button class="btn btn-xs btn-default ml-a" @click="markBestReply" v-if="authorize('owns',reply.thread)">Best Reply</button>
        </div>
    </div>
</template>
<script>
    import Favorite from './Favorite.vue';
    import moment from 'moment';

    export default {
        props: ['reply'],

        components: { Favorite },

        data() {
            return {
              editing: false,
              id: this.reply.id,
              body: this.reply.body,
              isBest: this.reply.isBest,
            };
        },

        computed: {
            ago() {
              return moment(this.reply.created_at).fromNow() + '...';
            }
        },

        created() {
          window.events.$on('best-reply-selected',id => {
             this.isBest = (id === this.id)
          });
        },

        methods:{
            update() {
                axios.patch('/replies/' + this.reply.id,{
                        body:this.body
                    })
                    .catch(error => {
                        flash(error.response.data,'danger');
                    });

                this.editing = false;

                flash('Updated!');
            },

            destroy() {
                axios.delete('/replies/' + this.id);

                this.$emit('deleted',this.id);
            },

            editReply(){
                this.old_body_data = this.body;
                this.editing = true;
            },

            cancelReply(){
                this.body = this.old_body_data;
                this.old_body_data = '';
                this.editing = false;
            },

            markBestReply() {
                this.isBest = true;

                axios.post('/replies/' + this.id + '/best');

                window.events.$emit('best-reply-selected',this.id);
            }
        }
    }
</script>

下一节我们进入下一个功能的开发,Good Luck!

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~