Using Laravel with Vue and <router-link> does not update the content as expected

For my project, I am using Laravel with Vue. On the main page, I have listed all articles and when a user clicks on a specific article, a new page opens displaying that article with other prominent articles shown on the side like this: .https://i.stack.imgur.com/sNg4b.jpg

Here is the code for the main page:

    <template>
    <div class="container-fluid">
        <div class="row">


            <div class=" col-lg-3 d-none d-lg-block top-article">
                <top-articles />
            </div>


            <div class="col-12 col-lg-2">
                <new-articles />
            </div>


            <div class="col-lg-2 d-none d-lg-block OurStories2">
                 <div v-for="article in articles" :key="article.id"  class="height">
                <router-link :to="{ name: 'SinglePost', params: { id: article.id } }">
                <div class="NewArticle">
                    <img :src="'/images/1617619359.jpg'" class="img-fluid newarticles-img">
                    <h6 class="NewArticleTitle">{{ article.title.ar }}</h6>
                </div>
                </router-link>
                <div>
                <p class="NewArticleBody">{{ article.excerpt.ar + ' Read more' }}</p>
                </div>
              </div>
            </div>


            <div class="col-lg-2 d-none d-lg-block">
                <our-stories />
            </div>



        </div>
    </div>
</template>

<script>
import NewArticles from './NewArticles.vue';
import OurStories from './OurStories.vue';
import TopArticles from './TopArticles';
    export default {
        components:{
                TopArticles,
                OurStories,
                NewArticles
        },
        data() {
            return {
                articles: []
            }
        },
        created() {
            this.axios
                .get('http://localhost:8000/api/articles/')
                .then(response => {
                    this.articles = response.data;
                });
        },
        methods: {
            deleteProduct(id) {
                this.axios
                    .delete(`http://localhost:8000/api/articles/${id}`)
                    .then(response => {
                        let i = this.articles.map(data => data.id).indexOf(id);
                        this.articles.splice(i, 1)
                    });
            }
        }
    }
</script>

On the post page: https://i.stack.imgur.com/51wAl.jpg

Here is the code for the post page:

    <template>
    <div>
        <go-back />
         <div class="container">
             <div class="row">
                 <div class="col-lg-6 col-12">
                     <!-- <img :src="'/images/articles/'+ articles.image" class="img-fluid img"> -->
                     <img :src="'/images/articles/1617007463.jpg'" class="img-fluid img">
                     <p>{{articles.body.en}}</p>
                 </div>
                  <div class="col-lg-3 d-none d-lg-block">
                       <top-articles />
                     {{articlesId}}
                 </div>
                     <div class="col-lg-3 our-stories d-none d-lg-block">
                     <our-stories />
                 </div>
             </div>

               <div>
         <router-view :key="$route.path"> </router-view>
              </div>
         </div>


            {{articlesId}}

    </div>
</template>

<script>
import GoBack from '../GoBack';
import OurStories from '../OurStories.vue';
import TopArticles from '../TopArticles.vue';
export default {
    components:{
        GoBack,
        TopArticles,
        OurStories
    },
    data(){
        return{
          articles: "",
          articlesId:this.$route.params.id,
          image:"https://via.placeholder.com/1520x400"
        }
    },

    props: {
        id: {
        type:Number,
        required: true
    },
    },

     created() {
             this.axios
                .get('http://localhost:8000/api/articles/')
                .then(response => {
                  this.articles =  response.data.find(  response  => response.id === parseInt(this.id)); //id parameter type, your items has id as number type but router return string and we use strict comparison in Product component.so Use parseInt(this.$route.params.id)
                  console.log(this.articlesId);
                });

    }
}
</script>
  • The issue at hand is that upon clicking an article on the main page, it opens on the post page along with top articles displayed on the side. However, when a user clicks on one of these side articles on the post page, the content does not change (only the URL's ID updates to the new article ID) but the content remains the same previous article. The desired outcome is for the content to update whenever a user clicks on an article from the side panel on the post page.

Answer №1

To improve the structure of your code, it is recommended to move the axios request to a method and then call that method inside the created hook. Additionally, utilize watch to reactively handle route changes and trigger the axios request again within the watch block.

<script>
import GoBack from '../GoBack';
import OurStories from '../OurStories.vue';
import TopArticles from '../TopArticles.vue';
export default {
    components:{
        GoBack,
        TopArticles,
        OurStories
    },
    data(){
        return{
            articles: "",
            articlesId:this.$route.params.id,
            image:"https://via.placeholder.com/1520x400"
        }
    },

    props: {
        id: {
            type:Number,
            required: true
        },
    },

    created() {
        this.getArticles();

    },
    methods: {
        getArticles() {
            this.axios
                .get('http://localhost:8000/api/articles/')
                .then(response => {
                    this.articles = response.data.find(response => response.id === parseInt(this.id)); //id parameter type, your items has id as number type but router return string and we use strict comparison in Product component.so Use parseInt(this.$route.params.id)
                    console.log(this.articlesId);
                });
        },
    },
    watch: {
        $route(to, from) {
            // react to route changes...
            this.articlesId = this.$route.params.id
            this.getArticles();
        }
    },
}
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Connecting socket.io to a Vue.js single page application using Javascript

I am new to Vue.js, Socket.io, and Node.js. Recently, I developed a single-page application that allows communication between a Node.js server running on a Raspberry Pi and a Siemens S7-1500 PLC connected via Ethernet. The Raspberry Pi acts as a WiFi acces ...

Utilizing Vuetify's datatable search property in conjunction with an autocomplete component

Currently, I am in the process of setting up a dropdown filter for each column within my Vuetify data table. It appears that the Vuetify autocomplete component offers the functionality I need, but I'm uncertain about how to utilize the values from the ...

Implementation issue with Hashids library in Vue.js causing functionality hiccups

I'm having trouble getting the library hashids to cooperate with vue.js The method I would like to use is: <template> <div class="container"> {{ hashids.encode('1') }} </div> </template> <script& ...

What is the reason for parent rows not stretching fully across the width of the page?

I am working on creating a simple table in Vue.js with Bootstrap. When the arrow is clicked, the child row is displayed, and I want it to appear below the parent row. I achieved this by setting display:flexbox; flex-direction:column; Here is the HTML tabl ...

Utilizing Nuxt3's auto-import feature alongside Eslint

I'm having trouble finding an eslint setup that is compatible with Nuxt3's auto-import feature to prevent no-undef errors. I have tried various packages like @antfu/eslint-config, plugin:nuxt/recommended, @nuxt/eslint-config, @nuxtjs/eslint-confi ...

Encountering 401 unauthorized error in Laravel Passport, Vue.js, and Axios integration

I am fairly new to VueJS and I am trying to retrieve data from a Laravel (passport) API. To do this, I have used npm i axios for making API requests. Below is the script code from my App.vue file: import axios from 'axios'; export default { da ...

Guide to integrating a menu in Vue.js

I am currently facing an issue with importing a component from vue.js into my App.vue file. Here is the code for the component: <template> <h1> Hello</h1> </template> <script> export default { } </script> And here ...

Retrieve information from deeply nested JSON and showcase using Vue-Multiselect

My goal is to fetch data from the server and present it in Multiselect using nested JSON, which can be done through Vue-Multiselect. Once displayed, I should have the ability to add new tags as needed, essentially updating the data. While I can display o ...

Using the Trigger Method in a Vue JS Component with Sibling Components

Seeking assistance once again for a VueJS2 project. Currently, I have a setup with a parent component, along with child1 and child2. The scenario is that the form in child1 needs to receive data from child2, which acts as a table. When a checkbox on a row ...

Discovering the method to incorporate a data-icon attribute within select options using vue.js

UPDATE before modification dataIcon: " @/images/flag-ukraine.svg" after modification dataIcon: require("@/assets/svg/flag-ukraine.svg"), notable change with require() I am using Materialize CSS select. When I use a URL for dataIcon ...

Validating Laravel emails with JavaScript blur and utilizing AJAX and jQuery

Looking for a way to validate a form in Laravel without hitting the submit button? I've tried some code, but only the email format validation seems to be working. Any tips on what I should do next? I'm new to Ajax. PS: When I enter a valid email ...

Issue encountered while compiling Vue.js template

Hey there, I need help with my Vue app. When I run it, only part of the app shows up and the add event section is not displaying any data. I had a similar error before in a different area which I was able to fix, but now I'm struggling to figure it ou ...

The vuestrap spinner is struggling to catch the shown event

https://github.com/yuche/vue-strap/blob/master/src/Spinner.vue https://github.com/yuche/vue-strap/blob/master/docs/example/spinnerDocs.vue Upon reviewing the provided example, I have attempted to replicate the same functionality here: https://jsfiddle.net ...

Iterate through each item in PHP using a Laravel foreach loop and display only the items that belong to the same

I'm facing an issue with displaying my data in the desired format. Let me illustrate with an example of an array: $items = 0 => [ 'name' => 'foo' 'description' => & ...

The Nuxt app runs smoothly on CodeSandbox, but is experiencing issues on my personal computer

I have successfully created a small nuxt.js app, and it is functioning perfectly on CodeSandbox. You can check it out by following this link: https://codesandbox.io/s/github/Ayman-Tarig/nuxt-test/tree/master/?fontsize=14 However, when I try to run the app ...

The functions that have been imported are not defined

I encountered a Error in created hook: "TypeError: _api__WEBPACK_IMPORTED_MODULE_0__.default.$_playerApi_getPlayers is not a function" issue while using Webpack through Vue CLI on my webpage. Below is the structure of my project directory: . + main.js + ...

Select a particular cell's background color within a v-for iteration

Utilizing Vue.js, I populate a table with data using the following code: <tr v-for="droit in listedroit"> <td>{{ droit.id_u }}</td> <td>{{ droit.role }}</td> <td>{{ droit.id_e }}</td> <td>{{ droit.droits ...

How can I implement a personalized Transformer in Gridsome?

One challenge I'm facing is incorporating a proprietary file format into my Gridsome website, where each file will create a new page. A Transformer typically handles this task, but unfortunately, there is no existing plugin for the specific file type ...

Compose an email in Vue.js without relying on any third-party API integration

Looking to send emails via SMTP Protocol without relying on any third-party integrations or APIs. Please provide a detailed, step-by-step solution. No need for existing code reflection, just ensuring error-free execution. ...

How do you set up a variable for a component template in October CMS?

Code snippet: {% partial 'content/main' %} Partial for services: {% component 'services' %} Component code: public function prepareVars() { $this->page['servicesList'] = $this->getProperty(); // functio ...