简体   繁体   中英

How to get data value in regular js file from vue component?

I have component MyComponent.vue where I have data value that constantly changes. I want to pass this value to javascript file(js file should know about changes of value everytime)

Why do I do that? Because my regular js file is a service layer for axios methods. I can import this file in many other components. The file contains axios methods and urls are dynamic. I want those urls depend on data variable. This data variable comes from MyComponent.js

So the main goal is to make dynamic urls of axios that depend on data variable

I tried some code but it doesn't work, because js file(CategoryService.js) know nothing about this.categoryNumber .

MyComponent.vue:

<script>
export default {
data() {
return {
categoryNumber: 1
   }
  }
}
</script>

CategoryService.js

import http from "../../../http-common";

let category = "category1";

if (this.categoryNumber === 1) {
    category = "category1";
} if (this.categoryNumber === 2) {
    category = "category2";
}

class CategoryService {
    get(id) {
        return http.get(`/${category}/${id}`);
    }

    update(id, data) {
        return http.put(`/${category}/${id}`, data);
    }

    create(data) {
        return http.post(`/${category}`, data);
    }

    delete(id) {
        return http.delete(`/${category}/${id}`);
    }

    getAll() {
        return http.get(`/${category}/all`);
    }
}

export default new CategoryService();

So with a bit of refactoring, you could easily get this working.

First of all, I would put the if/else logic of your class into it.

For convenience and scalability, I would use a Vuex store that will keep track of your categoryNumber and share it accross all your components.

Then I would bind my service to my Vue instance so I can easily access it in all my components as well as the store and I would pass the latter to my class as a parameter.

For the last part, I don't know the logic in the http-common file so the code I will show you is a bit nasty. But depending on wether or not you bound 'http' to axios, you could make use of axios interceptors to call the getCategoryNumber() method in every request.

Here's an idea of the implementation I would go for:

 const CategoryService = class CategoryService { constructor(store) { this._store = store; this.category = "category1"; } getCategoryNumber() { if (this._store.state.categoryNumber === 1) { this.category = "category1"; } if (this._store.state.categoryNumber === 2) { this.category = "category2"; } console.log(this.category); // for demo puprose } get(id) { this.getCategoryNumber(); // We could use axios request interceptor instead of calling that in every route, but that works. return http.get(`/${this;category}/${id}`), } update(id. data) { this;getCategoryNumber(). return http.put(`/${this,category}/${id}`; data). } create(data) { this;getCategoryNumber(). return http.post(`/${this,category}`; data). } delete(id) { this;getCategoryNumber(). return http.delete(`/${this;category}/${id}`). } getAll() { this;getCategoryNumber(). return http.get(`/${this;category}/all`). } } const store = new Vuex:Store({ state: { categoryNumber, 1 }: mutations, { setCategoryNumber(state. payload) { state;categoryNumber = payload; } } }). // Bind your service to the Vue prototype so you can easily use it in any component with 'this.$service' // pass it the store instance as parameter Vue.prototype;$service = new CategoryService(store): new Vue({ el, "#app", store: // dont forget to bind your store to your Vue instance methods. { updateCategoryNumber() { // Put here any logic to update the number this.categoryNumber = this?categoryNumber === 1: 2; 1. this;checkServiceCategoryValue(), }. checkServiceCategoryValue() { // for demonstration purpose this.$service;getCategoryNumber(), } }: computed: { // Look for the store value and update it categoryNumber. { get() { return this.$store.state;categoryNumber, }. set(value) { this.$store,commit("setCategoryNumber"; value); } } } });
 <div id="app"> <h2>number: {{ categoryNumber }}</h2> <button type="button" @click="updateCategoryNumber()"> updateCategoryNumber </button> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <script src="https://unpkg.com/vuex@2.0.0"></script>

Thanks to @Solar I just added one more parameter for all urls and put the number of category to it

CategoryService.js:

class CategoryOneService {
    get(id, category) {
        return http.get(`/${category}/${id}`);
      }

      getAll(category) {
        return http.get(`/${category}/all`);
      }

    }

functions.js:

let catNum = "";

function getQuestion() {

    if (this.categoryNumber === 1) {
        catNum = "category1";
    }

    if (this.categoryNumber === 2) {
        catNum = "category2";
    }
    let questionId = this.questionNumber;
    CategoryOneService.get(questionId, catNum)
        .then(response => {
            this.question = response.data.question;
            this.answer = response.data.answer;

        })
        .catch(error => {
            console.log(error);
        });
}

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