【问题标题】:Vue.js on render populate content dynamically via vue.router paramsVue.js 在渲染时通过 vue.router 参数动态填充内容
【发布时间】:2021-09-08 09:55:51
【问题描述】:

正如标题所说,我不太需要解决方案,但我不明白为什么会得到不想要的结果;

运行 v2 vue.js

我在单个组件文件中有一个 vue 组件。

基本上vue应该渲染数据(目前是从“excerciseModules”导入的,这是JSON格式的)。

IT 是动态的,因此它根据 url 路径确定要从 json 中提取什么,然后将其加载到页面中,但渲染是在此之前完成的,我不确定为什么。我创建了其他在概念上做同样事情的视图,它们工作正常。我不明白为什么会有所不同。

我选择了这种方式,因此我不必创建大量路线,而是可以在一个视图组件中处理逻辑(下面这个)。

问题是为什么数据加载为空(它在第一次加载时使用空的“TrainingModules”加载,然后加载“旧”数据。

示例 url 路径是“https...../module1”=页面加载为空

下一个

url 路径是 "https..../module 2" = 页面加载模块 1

下一个

url 路径是“https..../module 1”=页面加载模块 2

//My route
{

        path: '/excercises/:type',
        name: 'excercises',
        props: {
        },
        component: () => import( /* webpackChunkName: "about" */ '../views/training/Excercises.vue')
    }

<template>
<div class="relatedTraining">
    <div class="white section">
        <div class="row">
            <div class="col s12 l3" v-for="(item, index) in trainingModules" :key="index">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title"> {{ item.title }}</span>
                        <p>{{ item.excercise }}</p>
                    </div>
                    <div class="card-action">
                        <router-link class="" to="/Grip">Start</router-link>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</template>

<script>
    console.log('script');
    let trainingModules; //when initialized this is empty, but I would expect it to not be when the vue is rendered due to the beforeMount() in the component options. What gives?
/* eslint-disable */
let init = (params) => {
    console.log('init');
    console.log(trainingModules);
    trainingModules = excerciseModules[params.type];
   

    //return trainingModules
    
}
import { getRandom, randomImage } from '../../js/functions';
import { excerciseModules } from '../excercises/excercises_content.js'; //placeholder for JSON
export default {
    name: 'excercises',
    components: {
    },
    props: {
    },
    methods: {
        getRandom,
        randomImage,
        init
    },
    data() {
        return {
            trainingModules,
        }
    },
    beforeMount(){
        console.log('before mount');
        init(this.$route.params);
    },
    updated(){
        console.log('updated');
        
    },
    mounted() {
        
        console.log('mounted');
        //console.log(trainingModules);
    }
}

</script>


【问题讨论】:

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


    【解决方案1】:

    我不能告诉你为什么你的代码不工作,因为它是一个不完整的例子,但我可以引导你完成一个最小的工作示例,它可以完成你想要完成的工作。

    您要做的第一件事是确保您的 vue-router 配置正确。

    export default new Router({
      mode: "history",
    
      routes: [
        {
          path: "/",
          component: Hello
        },
        {
          path: "/dynamic/:type",
          component: DynamicParam,
          props: true
        }
      ]
    });
    

    这里我配置了一个带有参数的dynamic route matching 的路由,通常称为slug,名称为type。通过在路径中的 slug 之前使用 :,我告诉 vue-router 我希望它是一个路由参数。我还设置了props: true,因为这样可以将 slug 值作为道具提供给我的 DynamicParam 组件。这很方便。

    我的 DynamicParam 组件如下所示:

    <template>
      <div>
        <ul>
          <li v-for="t in things" :key="t">{{ t }}</li>
        </ul>
      </div>
    </template>
    
    <script>
    const collectionOfThings = {
      a: ["a1", "a2", "a3"],
      b: ["b1", "b2"],
      c: [],
    };
    
    export default {
      props: ["type"],
      data() {
        return {
          things: [],
        };
      },
      watch: {
        type: {
          handler(t) {
            this.things = collectionOfThings[t];
          },
          immediate: true,
        },
      },
    };
    </script>
    

    如您所见,我有一个与此组件上可用的 slug 名称匹配的道具。每当 url 中的“slug”发生变化时,我的道具也会发生变化。为了对这些变化做出反应,我设置了一个watcher 来调用一些代码。在这里您可以进行 fetch/axios/xhr 调用以获取真实数据。但是由于您是临时从 JSON 文件加载数据,所以我在这里做与您类似的事情。每当观察者检测到更改时(或第一次因为我设置了immediate: true),我都会将此数据分配给组件上的数据值。

    我创建了一个带有工作演示的代码框:https://codesandbox.io/s/vue-routing-example-forked-zesye

    PS:当创建一个最小的示例问题来隔离有问题的代码时,您会发现人们更乐于接受并渴望提供帮助。你可以在这里阅读更多信息:https://stackoverflow.com/help/minimal-reproducible-example

    【讨论】:

    • 感谢您抽出宝贵时间提供一个工作示例,谢谢您让我成功了。从您的示例中,我了解到,当我想根据某些数据集等的变化“刷新”渲染器/vue 时,我应该使用 watch 吗?顺便说一句,这种设计在 vue 中是最优的吗?在我有限的 vue 时间里,我唯一能想到的就是创建许多路由来达到预期的结果。?再次感谢!
    • 像任何东西一样 - 视情况而定。我描述的方法非常适用于您拥有完全动态数据的场景。例如,想象一个在线商店:您有一个包含所有商品的数据库——并且该列表一直在更新,您不想在每次有新商品可用时重新部署。您的路线可能类似于products/:productId,手表将获取单个产品数据以填充页面。如果您的页面集较少,并且不介意重新部署以添加更多页面,则可以为各个页面创建组件。
    • 很好的解释谢谢,这个例子非常接近地复制了我的场景。
    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2011-11-03
    • 2020-07-20
    相关资源
    最近更新 更多