【问题标题】:Vue - Nested component won't update its data and re-renderVue - 嵌套组件不会更新其数据并重新渲染
【发布时间】:2020-07-09 15:45:13
【问题描述】:

这里是场景。我可以上传一个LiteratureReview,每个可以包含一个或多个Quote。所以我拥有的是LiteratureReview(Parent) 和Quote(Child) 组件。我使用 Axios 获取和发布数据。我的后端是 Laravel。

LiteratureReviewQuote 从应用实例中获取数据。发送 post 请求后,LiteratureReview 将更新并重新呈现页面。但是当我想在其文献综述中添加Quote时,它并没有更新,我需要刷新页面。

app.js(或 main.js)

export const app = new Vue({
    el: '#app',

    data: function () {
        return {
            literatureReviews: [],
            quotes: [],
        }
    },
    mounted() {
        axios.all([
            axios.get('/literature-review'),
            axios.get('/quote')
        ]).then(axios.spread((first_response, second_response) => {
            this.literatureReviews = first_response.data
            this.quotes = second_response.data
        }))
    }
});

index.blade.php

<literature-review v-for="(literatureReview, index) in literatureReviews" v-bind:loop="index + 1"
            v-bind:key="literatureReview.id" v-bind:literature_review_id="literatureReview.id"
            v-bind:topic="literatureReview.topic" v-bind:type="literatureReview.type"
            v-bind:year="literatureReview.year" v-bind:link="literatureReview.link"></literature-review>

文学评论(组件;父级)

<template>
    <div class="literature-card mb-5 rounded">
        .
        .
        .
        <quote v-for="quote in filterByLiteratureReview(quotes, literature_review_id)" v-bind:key="quote.id"
            v-bind:literature_review_id="literature_review_id" v-bind:quote="quote.quote" v-bind:page="quote.page"></quote>
    </div>
</template>

<script>
    import { app } from '../app.js'
    import { store } from '../app.js'

    export default {
        props: ['loop', 'literature_review_id', 'topic', 'type', 'year', 'link'],
        data() {
            return {
                quotes: app.quotes,
                sharedObject: store,
            }
        },
        methods: {
            filterByLiteratureReview(quotes, literature_review_id) {
                return this.quotes.filter(quote => quote.literature_review_id == literature_review_id)
            },
            updateLitIdForAddingQuote(value) {
                this.sharedObject.setLiteratureReviewIdAction(value)
            },
        }
    }
</script>

引用(组件;子)

<template>
    <div>
        <div class="row no-gutters px-3 pt-3">
            <div class="col" style="white-space: pre-wrap;">{{ quote }}</div>
        </div>
        <div class="row no-gutters" style="border-bottom: solid black 2px;">
            <div class="col py-4 pr-3 text-right">Pg {{ page }}</div>
        </div>
    </div>
</template>

<script>
    export default {
        props: ['id', 'literature_review_id', 'quote', 'page'],
    }
</script>

Axios 发表文献评论

axios.post('/literature-review', {
    topic: this.topic,
    type: this.type,
    year: this.year,
    link: this.link,
}).then( response => {
    $('#addSourceModal').modal('hide')
}).finally(
    axios.get('/literature-review').then(response => app.literatureReviews = response.data)
)

Axios 发布报价

axios.post('/quote', {
    literature_review_id: this.sharedObject.state.literature_review_id,
    quote: this.quote,
    page: this.page
}).then( response => {
    console.log(response)
    $('#addQuoteModal').modal('hide')
    // location.reload();
}).finally(
    axios.get('/quote').then(response => app.quotes = response.data)
)

【问题讨论】:

  • 当您发出帖子请求时,您是否在literature-review 中获得更新的道具?
  • 我从一个弹出模式更新数据,它本身是一个组件但与这两个无关
  • 我的意思是,发完帖子后,你能在literature-review componet 看到更新的道具吗?
  • 哦,对于 literature-review 是的,但对于 quote 不是,尽管方法相同
  • 这是由于您的 filterByLiteratureReview 方法而发生的。当数据发生变化时,它不知道再次运行。您可以尝试将其转换为计算属性。或者您需要传递一个key,它会在您发帖时更新。当key改变时,会强制Quote重新渲染。

标签: javascript vue.js vuejs2 axios vue-component


【解决方案1】:

这个article 在某种程度上帮助我解决了这个问题。所以基本上,数据是从弹出模式的提交按钮更新的。我制作了这个按钮来向根this.$root.$emit('forceRerender') 发出一个事件,该事件在创建时由LiteratureReviewthis.$root.$on('forceRerender', this.forceRerender) 接收。 LiteratureReview 组件然后运行其包含axios.get('/quote').then(response =&gt; this.quotes = response.data)forceRerender()

模态

<script>
    export default {
        props: ['target'],
        methods: {
            submit() {
                this.$emit('submit')
                this.$root.$emit('forceRerender')
            }
        }
    }
</script>

文学评论部分

<script>
    import {
        app
    } from '../app.js'
    import {
        store
    } from '../app.js'

    export default {
        props: ['loop', 'literature_review_id', 'topic', 'type', 'year', 'link'],
        data() {
            return {
                quotes: app.quotes,
                sharedObject: store,
            }
        },
        created() {
            this.$root.$on('forceRerender', this.forceRerender)
        },
        methods: {
            filterByLiteratureReview(quotes, literature_review_id) {
                return this.quotes.filter(quote => quote.literature_review_id == literature_review_id)
            },
            updateLitIdForAddingQuote(value) {
                this.sharedObject.setLiteratureReviewIdAction(value)
            },
            forceRerender() {
                axios.get('/quote').then(response => this.quotes = response.data)
            }
        }
    }
</script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-18
    • 2023-01-10
    • 2018-10-14
    • 2018-04-19
    • 2017-11-09
    • 2022-11-27
    • 2019-07-30
    • 2023-02-16
    相关资源
    最近更新 更多