首页 > 解决方案 > 如何使我的应用程序的一个组件重新加载,同时保持我的其余组件不重新加载?

问题描述

我一直在使用 Vue.js 构建一个评论应用程序,它得到一个随机的事实(使用 API https://uselessfacts.jsph.pl/random.json?language=en),然后允许用户给出他们的反馈包含无线电和文本输入的表单中的事实。在他们提交反馈后,它会被记录并显示在一个列表中,这是表单下的另一个组件。但是我遇到了一个障碍,因为默认情况下,一旦表单中的信息被提交,页面就会重新加载。这会导致用户提交的任何信息都被擦除。

因此,我尝试通过添加prevent到 html 表单标签(即<form v-on:submit.prevent="handleSubmit">)来修改表单,以便整个页面不会重新加载,但这会导致另一个问题 - 如果不重新加载页面,则无法从 API 中检索到新句子。

我在 Vue 中设置了两个组件,如下所示:

//first component
<template>
<div v-if="randomFact">
    <h3><span>Random fact: </span>{{this.randomFact.text}}</h3>
    <form v-on:submit='handleSubmit'>
        <input type="radio" name="reaction" id="positive" value="positive" v-model="reaction"> 
        <label for="positive">Positive</label><br>
        <input type="radio" name="reaction" id="neutral" value="neutral" v-model="reaction">
        <label for="neutral">Neutral</label><br>
        <input type="radio" name="reaction" id="negative" value="negative" v-model="reaction">
        <label for="negative">Negative</label><br>
        <br>
        <label for="feedback">Feedback</label>
        <br>
        <textarea rows="4" cols="50" name="feedback" v-model="feedback"></textarea>
        <br>
        <input type="submit" value="Submit">
        <br>
    </form>
</div>
</template>

<script>
import { eventBus } from '../main.js';
import Review from '../classes/review.js';

export default {
    name: "review-detail",
    data(){
        return {
            randomFact:"",
            reaction: "",
            feedback:""
        }
    },
    mounted(){
        fetch('https://uselessfacts.jsph.pl/random.json?language=en').then(response=> response.json())
       .then(randomFact=> this.randomFact= randomFact)
       .catch(error=> console.log(error))
    },
    methods: {
        handleSubmit(){
            let review = new Review(this.randomFact.text, this.reaction, this.feedback);
            eventBus.$emit('review-recorded', review)
        }
    } 
}
</script>

//second component
<template>
    <div>
        <ul id="reviews" v-bind="reviews">
            <li v-for="review in reviews" :key="review.reaction">
                <p>Random fact: {{review.randomFact}}</p>
                <p>Reaction: {{review.reaction}}</p>
                <p>Feedback: {{review.feedback}}</p>
            </li>
        </ul>
    </div>
</template>

<script>
import { eventBus } from '../main.js';
import Review from '../classes/review.js';

export default {
    name:'reviews-list',
    data(){
        return{
            reviews:[],
        }
    },
    mounted(){
        eventBus.$on('review-recorded', (review)=>{
            this.reviews.push(review);
        })
    }
}
</script>

那么如何在不重新加载第二个组件的情况下重新加载第一个组件以从 API 获取新信息?我是否错误地设置了我的 Vue 应用程序的两个组件之间的交互?我只想让我的第一个组件的形式中的信息由我的第二个组件记录和显示,同时让我的第一个组件重新加载以获取新的随机事实。

标签: javascriptvue.js

解决方案


您绝对需要阻止浏览器提交表单。<form v-on:submit.prevent="handleSubmit">应该是要走的路。

在您的handleSubmit方法中,您需要在后台使用 HTTP 请求与您的 API 对话。Axios是一个非常流行的解决方案,您可能想看看。

有很多库可以解决这个问题,具体取决于您的需要。我会选择 axios,因为它广为人知并被广泛使用,因此很容易找到好的教程并提供帮助。实际上,您也可以使用标准XMLHttpRequest,但这不是使用 Vue.js 时的最佳选择。


推荐阅读