简体   繁体   中英

What would be the most efficient way to structure a VueJS app with this logic?

I have an app that will display data fetched from a series of sources, depending on a condition. The problem is the way I fetch, organize, and return the data is different depending on the original source (I even have to import other libraries just for one method).

I currently have it set up like the example below, but what happens when my list of sources grows to, say, 100? How should I be structuring the app? Thank you!

<template>
    <div>
        <h1>{{data.title}}</h1>
        <h2>{{data.subtitle}}</h2>
        <p>{{data.description}}</p>
    </div>
</template>

<script>
export default {
    data() {
            return {
                data: {}
            }
        },
        methods: {
            getFetchMethod() {
                var i = Math.floor(Math.random() * 3);
                if (i == 0) {
                    this.getData();
                } else if (i == 1) {
                    this.getDataThisWay();
                } else if (i == 2) {
                    this.getDataAnotherWay();
                } else {
                    this.getDataEtc();
                };
            },
            getData() {
                this.data = {
                    'title': 'Foo',
                    'subtitle': 'Bar',
                    'description': 'Blah'
                };
            },
            getDataThisWay() {
                this.data = {
                    'title': 'Foo',
                    'subtitle': 'Bar',
                    'description': 'Blah'
                };
            },
            getDataAnotherWay() {
                this.data = {
                    'title': 'Foo',
                    'subtitle': 'Bar',
                    'description': 'Blah'
                };
            },
            getDataEtc() {
                this.data = {
                    'title': 'Foo',
                    'subtitle': 'Bar',
                    'description': 'Blah'
                };
            }
        },
        mounted() {
            this.getFetchMethod();
        }
}
</script>

<style lang="css">
</style>

This has nothing to do with VueJS. You should create an array of objects, each with their own data set. You can then use your random number as an index.

// store all your data in an array (you could make this part of the vuejs data object
var datasets = [
    {
        title: 'Foo',
        subtitle: 'Bar',
        description: 'Blah'
    },
    {
        title: 'Foo2',
        subtitle: 'Bar2',
        description: 'Blah2'
    }
    // etc...
];

// get a random number based on the length of your array
var i = Math.floor(Math.random() * datasets.length);

// use the random number to index your array
this.data = datasets[i];

UPDATE: You say that you've got multiple functions that all get data differently, you could do the same approach by putting the functions into an array an indexing them.

// put all the method references (no calling parens) into an array
var methods = [
    this.getData,
    this.getDataThisWay,
    this.getDataEtc
];

var i = Math.floor(Math.random() * datasets.length);

// index the array then call the particular method
this.data = datasets[i]();

Additionally, if your methods rely on a particular context, you can use call() to supply a specific context that's different from this .

this.data = datasets[i].call(this); // where this is the current context

I'd probably make the template into its own component that takes props for the title, subtitle, and description. The parent component will then be responsible for for passing the data into this child component based on however it got the data.

Child.vue

<template>
    <div>
        <h1>{{title}}</h1>
        <h2>{{subtitle}}</h2>
        <p>{{description}}</p>
    </div>
</template>

<script>
export default {
    props: ["title", "subtitle", "description"]
}
</script>

Parent.vue

<template>
    <div>
        <button @click="way1">Way 1</button>
        <button @click="way2">Way 2</button>
        <child :title="title" :subtitle="subtitle" :description="description"></child>
    </div>
</template>

<script>
import Child from "./Child.vue"

export default {
    components:{
        Child
    },
    data(){
        return {
            title: "",
            subtitle: "",
            description: ""
        };
    },
    methods: {
        way1(){
            this.title="way 1 title";
            this.subtitle="way 1 subtitle"
            this.description="way 1 description"
        },
        way2(){
            this.title="way 2 title";
            this.subtitle="way 2 subtitle"
            this.description="way 2 description"
        }
    }
}
</script>

EDIT: I'd also recommend importing a "data provider" into the Parent.vue who can have any logic for getting the data, but the expectation would be that it returns it in a known shape which can then easily be passed into the child component

Parent2.vue

<template>
    <div>
        <button @click="get">Get</button>
        <child :title="title" :subtitle="subtitle" :description="description"></child>
    </div>
</template>

<script>
import dataProvider from "./dataProvider"
import Child from "./Child.vue"

export default {
    components:{
        Child
    },
    data(){
        return {
            title: "",
            subtitle: "",
            description: ""
        };
    },
    methods: {
        get(){
            var data = dataProvider.get();
            this.title=data.title;
            this.subtitle=data.subtitle;
            this.description=data.description;
        }
    }
}
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM