当新参数传递给组件时更新组件(VUE JS)

时间:2020-07-29 16:34:12

标签: javascript vue.js vue-component vue-router

已编辑-

最好重新开始。

我有一个VUE js CLI应用程序-它从APP.vue页面调用数据库,然后将数据分配到其他页面和导航栏-

导航栏调用路由器功能:

loadRouter(articles){
          this.$router.push({name: 'Articles', params: {articles: articles}})
      }

但是,这现在导致2个问题:

  1. 单击新导航后,组件不会重新加载新数据

  2. 我收到一个错误:

    错误:避免了冗余导航到当前位置:“ / articles”。

enter image description here

代码:

app.vue <<<<此文件进行提取调用,然后将数据传递到组件导航栏(在<Navbar :articleData="articleData"/>中可见)

<template>
  <div id="app">
    <div class="topElements">
      <Navbar :articleData="articleData"/>
      
      <router-view/>
    </div>
      <Footer />
  </div>
</template>

<script>
import Navbar from '@/components/Nav.vue'

import Footer from '@/components/Footer.vue'
export default {
  components: {
    Navbar,
    Footer
  },
  data(){
    return {
      articleData: null,


      //   set up a variable for the local host as this will change later when the enviroment moves online
      enviroment: 'http://localhost:1337/',
    }
  },
  created(){
    fetch(`${this.enviroment}languages`)
    .then(responce => responce.json())
    .then(data => {this.articleData = data})
  }
}
</script>

Navbar.vue <<,这是用户选择语言(文章)的地方-这是通过@click事件完成的,该事件随后调用$route.push Article组件和道具的回调

template>
  <div class="navigationContainer">
      <div class="languageContainer" v-for="item in articleData" :key="item.id">
          <h2 @click="loadRouter(item.articles)">{{ item.title }}</h2>
      </div>
  </div>
</template>

<script>
export default {
  name: 'Navbar',
  props: ['articleData'],
  data(){
      return{

      }
  },
  methods: {
      loadRouter(articles){
          this.$router.push({name: 'Articles', params: {articles: articles}})
      }
  } 
}
</script>

Articles.vue <<最后,文章页面通过作为道具传递来显示此处的所有文章(最初的道具会加载,但在单击新导航栏时会重新加载,而我上面提到的错误是显示)

Articles.vue

<template>
  <div class="articleContainer">
     <p>{{ articles }}</p>  <<< just to display if the props has come through correctly - will be changed later
  </div>
</template>

<script>
export default {
    name: 'Articles',
    props: ['articles'],
    data(){
      return{
        articleData: null,
      }
    },
    watch: {
      articles(){
        this.articleData = this.articles; <<<< trying to update the component when A new $route is detected - I also tried this with $route
        console.log(articleData) <<< checking if it worked.... 
      }
    }
}
</script>

要分配阅读,所以我只想说谢谢您在这里可以提供的任何帮助。

热烈的问候, 沃利

p.s。

询问您可能有的任何问题

已编辑:

文章数据来自:http:// localhost:1337 /语言

它是从STRAPI API中提取的OBJS数组(我已将其公开)

[
{
"id": 1,
"title": "JS",
"created_at": "2020-07-10T08:30:33.156Z",
"updated_at": "2020-07-10T08:30:33.156Z",
"articles": [
{
"id": 4,
"title": "hamburger menu",
"description": "This is where I would explain how to make a front end hamburger menu style for the navigation of a web page",
"created_at": "2020-07-10T08:32:11.474Z",
"updated_at": "2020-07-10T08:32:11.474Z"
}
]
},
{
"id": 2,
"title": "HTML",
"created_at": "2020-07-10T08:30:38.437Z",
"updated_at": "2020-07-10T08:30:38.437Z",
"articles": [
{
"id": 4,
"title": "hamburger menu",
"description": "This is where I would explain how to make a front end hamburger menu style for the navigation of a web page",
"created_at": "2020-07-10T08:32:11.474Z",
"updated_at": "2020-07-10T08:32:11.474Z"
},
{
"id": 5,
"title": "WEB STRUCTURE",
"description": null,
"created_at": "2020-07-10T10:08:44.221Z",
"updated_at": "2020-07-10T10:08:44.221Z"
}
]
},
{
"id": 3,
"title": "CSS",
"created_at": "2020-07-10T08:30:43.107Z",
"updated_at": "2020-07-10T08:30:43.107Z",
"articles": [
{
"id": 4,
"title": "hamburger menu",
"description": "This is where I would explain how to make a front end hamburger menu style for the navigation of a web page",
"created_at": "2020-07-10T08:32:11.474Z",
"updated_at": "2020-07-10T08:32:11.474Z"
}
]
},
{
"id": 4,
"title": "VUE",
"created_at": "2020-07-10T10:52:11.390Z",
"updated_at": "2020-07-10T10:52:11.390Z",
"articles": []
},
{
"id": 5,
"title": "NODE JS",
"created_at": "2020-07-10T10:52:23.351Z",
"updated_at": "2020-07-10T10:52:23.351Z",
"articles": []
},
{
"id": 6,
"title": "SASS",
"created_at": "2020-07-10T10:52:31.450Z",
"updated_at": "2020-07-10T10:52:31.450Z",
"articles": []
},
{
"id": 7,
"title": "PHP",
"created_at": "2020-07-12T19:21:48.620Z",
"updated_at": "2020-07-12T19:21:48.620Z",
"articles": []
},
{
"id": 8,
"title": "GIT",
"created_at": "2020-07-12T19:22:02.208Z",
"updated_at": "2020-07-12T19:22:02.208Z",
"articles": []
}
]

2 个答案:

答案 0 :(得分:1)

您的导航栏可以只使用普通的router-link并将文章绑定到路线的参数上。

Navbar.vue

<template>
  <div class="navigationContainer">
      <div class="languageContainer" v-for="article in articleData" :key="item.id">
          <router-link :to="{name: 'Articles', params: { id: article.id, article: article }}">
            {{ article.title }}
          </router-link>
      </div>
  </div>
</template>
....

您需要更新路线以使用function mode,并从route.params解析出文章,以作为道具输入到您的组件中。

路线

{
    name: 'Articles',
    path: '/articles/:id', 
    props: (route) => ({
        id: route.params.id,
        article: route.params.article,
    })
}

最后,您的文章组件将获得idarticle作为道具。

Articles.vue

<template>
  <div class="articleContainer">
     <p>{{ id }}</p>
     <p>{{ article.title }}</p>
     <p>{{ article.description }}</p>
  </div>
</template>

<script>
export default {
    name: 'Articles',
    props: ['id', 'article'],
    created() {
        if (!this.article) {
            // direct url navigation: you need to fetch the article using `this.id`
        }
    }
}
</script>

Simplified Demo

您需要考虑的一件事。如果用户直接通过网址导航到该路线,则article属性将为null。因此,您需要在组件的created挂钩或路由器导航保护中获取文章。

答案 1 :(得分:0)

我可能会做些不同的操作,如下所示:

  1. 在App.vue中,不要获取整个articleData集合。取而代之的是,只需检索导航栏所需的商品标题和商品ID。

  2. 然后,在Navbar中,只需使用路由器链接即可通过item.id:

          <router-link :to="{name: 'Articles', params: { itemid: item.id}}">
            {{ article.title }}
          </router-link>```
  1. 然后,在“文章”组件中,在mounted()生命周期方法中获取文章详细信息,并从itemid开始。

  2. 最后一步是该帖子的标题,这是确保即使$ route似乎不变的情况下,仍可以触发Articles安装的生命周期方法的必要步骤 。您可以通过将App.vue文件中的<router-view>更改为<router-view :key="$route.fullPath">来完成此操作。

<template>
  <div id="app">
    <div class="topElements">
      <Navbar :articleData="articleData"/>
      
      <router-view :key="$route.fullPath" />
    </div>
      <Footer />
  </div>
</template>

虽然这种方法需要两次获取而不是一次,但您只会获取用户特定路径所需的数据。