2017-03-02 27 views
6

इससे पहले कि मैं घटक की लिपि से फिल्म विवरण प्राप्त कर रहा था। फ़ंक्शन पहले जांचता है कि स्टोर की मूवी आईडी रूट की परम मूवी आईडी के समान है या नहीं। यदि यह वही है तो सर्वर एपीआई से फिल्म न प्राप्त करें, या फिर सर्वर एपीआई से फिल्म प्राप्त करें।

यह ठीक काम कर रहा था। लेकिन अब मैं स्टोर के उत्परिवर्तन से फिल्म विवरण प्राप्त करने की कोशिश कर रहा हूं। हालांकि मैं त्रुटि

Uncaught TypeError: Cannot read property '$route' of undefined

कैसे पैरामीटर और Vue-संसाधन ($http) तक पहुँचने के लिए Vue रूटर ($route) उपयोग करने के लिए vuex दुकान में सर्वर एपीआई से प्राप्त करने के लिए मिल रहा है?

store.js:

export default new Vuex.Store({ 
    state: { 
     movieDetail: {}, 
    }, 
    mutations: { 
     checkMovieStore(state) { 
      const routerMovieId = this.$route.params.movieId; 
      const storeMovieId = state.movieDetail.movie_id; 
      if (routerMovieId != storeMovieId) { 
       let url = "http://dev.site.com/api/movies/movie-list/" + routerMovieId + "/"; 
       this.$http.get(url) 
        .then((response) => { 
         state.movieDetail = response.data; 
        }) 
        .catch((response) => { 
         console.log(response) 
        }); 
      } 
     }, 
    }, 
}); 

घटक स्क्रिप्ट:

export default { 
    computed: { 
     movie() { 
      return this.$store.state.movieDetail; 
     } 
    }, 
    created: function() { 
     this.$store.commit('checkMovieStore'); 
    }, 
} 

उत्तर

5

अपने vuex स्टोर में $http या $router का उपयोग करने के लिए, आपको मुख्य vue उदाहरण का उपयोग करना होगा। हालांकि मैं इसका उपयोग करने की अनुशंसा नहीं करता हूं, लेकिन मैं वास्तविक प्रश्न का उत्तर देने के बाद जो भी सिफारिश करता हूं उसे जोड़ दूंगा।


में अपने main.js या जहाँ भी आप की तरह अपने Vue उदाहरण पैदा कर रहे:

new Vue({ 
    el: '#app', 
    router, 
    store, 
    template: '<App><App/>', 
    components: { 
    App 
    } 
}) 

या कुछ इसी तरह, आप भी vue-router और vue-resource प्लगइन्स भी जोड़ दिया हो।

यह करने के लिए एक मामूली संशोधन करने से:

export default new Vue({ 
    el: '#app', 
    router, 
    store, 
    template: '<App><App/>', 
    components: { 
    App 
    } 
}) 

मैं अब यह vuex दुकानों में तो जैसे आयात कर सकते हैं:

//vuex store: 
import YourVueInstance from 'path/to/main' 

checkMovieStore(state) { 
const routerMovieId = YourVueInstance.$route.params.movieId; 
const storeMovieId = state.movieDetail.movie_id; 
if (routerMovieId != storeMovieId) { 
    let url = "http://dev.site.com/api/movies/movie-list/" + routerMovieId + "/"; 
    YourVueInstance.$http.get(url) 
    .then((response) => { 
     state.movieDetail = response.data; 
    }) 
    .catch((response) => { 
     console.log(response) 
    }); 
    } 
} 

और के रूप में Austio द्वारा जवाब चला जाता है, इस विधि एक action होना चाहिए mutations एसिंक को संभालने के लिए डिज़ाइन नहीं किए गए हैं।


अब इसे करने के अनुशंसित तरीके से आ रहा है।

  1. आपका componentroute params पहुँच सकते हैं और यह action को प्रदान कर सकते हैं।

    methods: { 
        ...mapActions({ 
        doSomethingPls: ACTION_NAME 
        }), 
        getMyData() { 
        this.doSomethingPls({id: this.$route.params}) 
        } 
    } 
    
  2. action तो एक पृथक एपीआई सेवा फ़ाइल (read plugins)

    [ACTION_NAME]: ({commit}, payload) { 
        serviceWhichMakesApiCalls.someMethod(method='GET', payload) 
        .then(data => { 
         // Do something with data 
        }) 
        .catch(err => { 
         // handle the errors 
        }) 
    } 
    
  3. के माध्यम से कॉल करता है आपका actions कुछ async काम करते हैं और एक mutation के परिणाम प्रदान करते हैं।

    serviceWhichMakesApiCalls.someMethod(method='GET', payload) 
        .then(data => { 
         // Do something with data 
         commit(SOME_MUTATION, data) 
        }) 
        .catch(err => { 
         // handle the errors 
        }) 
    
  4. Mutations केवल लोगों को अपने state संशोधित करने के लिए किया जाना चाहिए।

    [SOME_MUTATION]: (state, payload) { 
        state[yourProperty] = payload 
    } 
    

उदाहरण एक फ़ाइल जो अंतिम बिंदुओं की एक सूची है, आप इसे की आवश्यकता हो सकती है अगर तुम जो की तरह अलग अलग एपीआई अंतिमबिंदुओं है तैनाती के विभिन्न चरणों है: परीक्षण, मचान, उत्पादन, आदि

export const ENDPOINTS = { 
    TEST: { 
    URL: 'https://jsonplaceholder.typicode.com/posts/1', 
    METHOD: 'get' 
    } 
} 

और मुख्य फ़ाइल जो एक सेवा के रूप Vue.http लागू करता है:

import Vue from 'vue' 
import { ENDPOINTS } from './endpoints/' 
import { queryAdder } from './endpoints/helper' 
/** 
* - ENDPOINTS is an object containing api endpoints for different stages. 
* - Use the ENDPOINTS.<NAME>.URL : to get the url for making the requests. 
* - Use the ENDPOINTS.<NAME>.METHOD : to get the method for making the requests. 
* - A promise is returned BUT all the required processing must happen here, 
*  the calling component must directly be able to use the 'error' or 'response'. 
*/ 

function transformRequest (ENDPOINT, query, data) { 
    return (ENDPOINT.METHOD === 'get') 
     ? Vue.http[ENDPOINT.METHOD](queryAdder(ENDPOINT.URL, query)) 
     : Vue.http[ENDPOINT.METHOD](queryAdder(ENDPOINT.URL, query), data) 
} 

function callEndpoint (ENDPOINT, data = null, query = null) { 
    return new Promise((resolve, reject) => { 
    transformRequest(ENDPOINT, query, data) 
     .then(response => { return response.json() }) 
     .then(data => { resolve(data) }) 
     .catch(error => { reject(error) }) 
    }) 
} 

export const APIService = { 
    test() { return callEndpoint(ENDPOINTS.TEST) }, 
    login (data) { return callEndpoint(ENDPOINTS.LOGIN, data) } 
} 

क्वेरी एडर यदि यह महत्वपूर्ण है, तो मैं यूआरएल में पैरा जोड़ने के लिए इसका उपयोग कर रहा था।

export function queryAdder (url, params) { 
    if (params && typeof params === 'object' && !Array.isArray(params)) { 
    let keys = Object.keys(params) 
    if (keys.length > 0) { 
     url += `${url}?` 
     for (let [key, i] in keys) { 
     if (keys.length - 1 !== i) { 
      url += `${url}${key}=${params[key]}&` 
     } else { 
      url += `${url}${key}=${params[key]}` 
     } 
     } 
    } 
    } 
    return url 
} 
+0

मैंने एक क्रिया में मुख्य vue उदाहरण को संदर्भित करने के लिए एक चर का उपयोग किया। उस क्रिया को एक घटक के बनाए गए हुक के दौरान बुलाया जाता है। उस समय, मुख्य vue उदाहरण का संदर्भ उपलब्ध नहीं है, जो अपवाद की ओर जाता है। – Teddy

+0

यह तब होता है जब उस घटक को उस मार्ग पर पहली बार लोड किया जाता है, जब उपयोगकर्ता ब्राउज़र रीलोड बटन पर क्लिक करता है। यदि ऐप पहले ही लोड हो चुका है, तो उस घटक पर नेविगेट करना ठीक काम करता है। क्या इस मामले में कोई कामकाज है? – Teddy

+0

टाइपरर: अपरिभाषित – Teddy

2

तो कुछ चीजें, $ दुकान और $ मार्ग Vue उदाहरण है, जिनमें से गुण क्यों उनमें से अंदर तक पहुँच रहे हैं Vuex उदाहरण काम नहीं कर रहा है। इसके अलावा, म्यूटेशन synchonous क्या आप कार्यों

  1. उत्परिवर्तन => एक समारोह है कि राज्य को देखते हुए और कुछ तर्क राज्य mutates की जरूरत है कर रहे हैं

  2. कार्रवाई => http कॉल की तरह async काम करें और उसके बाद के लिए परिणाम के लिए प्रतिबद्ध एक उत्परिवर्तन

तो http को प्रेषित करने वाली एक क्रिया बनाएं। ध्यान रखें यह छद्म कोड है।

//action in store 
checkMovieStore(store, id) { 
    return $http(id) 
    .then(response => store.commit({ type: 'movieUpdate', payload: response }) 
} 

//mutation in store 
movieUpdate(state, payload) { 
    //actually set the state here 
    Vue.set(state.payload, payload) 
} 

// created function in component 
created: function() { 
    return this.$store.dispatch('checkMovieStore', this.$route.params.id); 
}, 

अब आप अपने बनाए गए समारोह आईडी, कि पूरा हो गया है एक बार यह मान के साथ दुकान को अद्यतन करता है, जो http कॉल करता है के साथ checkMovieStore कार्रवाई डिस्पैचिज।

संबंधित मुद्दे