Ben*_*Max 10 javascript vue-resource vue-router vuex vuejs2
在我从组件的脚本中获取电影细节之前.该功能首先检查商店的电影ID是否与路线的参数电影ID相同.如果相同则不从服务器API获取电影,否则从服务器API获取电影.
它工作正常.但现在我正试图从商店的变异中获取电影细节.但是我收到了错误
未捕获的TypeError:无法读取未定义的属性'$ route'
如何使用vue-router ($route)访问params和vue-resource ($http)以从vuex存储中的服务器API获取?
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)
});
}
},
},
});
Run Code Online (Sandbox Code Playgroud)
组件脚本:
export default {
computed: {
movie() {
return this.$store.state.movieDetail;
}
},
created: function () {
this.$store.commit('checkMovieStore');
},
}
Run Code Online (Sandbox Code Playgroud)
Amr*_*pal 15
要使用$http或$router在您的vuex商店中,您需要使用主vue实例.虽然我不建议使用它,但我会在回答实际问题后添加我推荐的内容.
在您main.js或您创建vue实例的任何地方,例如:
new Vue({
el: '#app',
router,
store,
template: '<App><App/>',
components: {
App
}
})
Run Code Online (Sandbox Code Playgroud)
或类似的东西,你也可能也添加了插件vue-router和vue-resource插件.
对此做一点修改:
export default new Vue({
el: '#app',
router,
store,
template: '<App><App/>',
components: {
App
}
})
Run Code Online (Sandbox Code Playgroud)
我现在可以在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)
});
}
}
Run Code Online (Sandbox Code Playgroud)
并通过回答Austio推移,这种方法应该是action因为mutations没有被设计来处理异步.
现在采用推荐的方式来做到这一点.
您component可以访问route params并提供给action.
methods: {
...mapActions({
doSomethingPls: ACTION_NAME
}),
getMyData () {
this.doSomethingPls({id: this.$route.params})
}
}
Run Code Online (Sandbox Code Playgroud)该action再通过抽象的API服务文件进行调用(读plugins)
[ACTION_NAME]: ({commit}, payload) {
serviceWhichMakesApiCalls.someMethod(method='GET', payload)
.then(data => {
// Do something with data
})
.catch(err => {
// handle the errors
})
}
Run Code Online (Sandbox Code Playgroud)你actions做一些异步工作并将结果提供给a mutation.
serviceWhichMakesApiCalls.someMethod(method='GET', payload)
.then(data => {
// Do something with data
commit(SOME_MUTATION, data)
})
.catch(err => {
// handle the errors
})
Run Code Online (Sandbox Code Playgroud)Mutations应该是唯一修改你的state.
[SOME_MUTATION]: (state, payload) {
state[yourProperty] = payload
}
Run Code Online (Sandbox Code Playgroud)示例 包含端点列表的文件,如果您具有不同的api端点,例如:test,staging,production等,则可能需要它们.
export const ENDPOINTS = {
TEST: {
URL: 'https://jsonplaceholder.typicode.com/posts/1',
METHOD: 'get'
}
}
Run Code Online (Sandbox Code Playgroud)
以及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) }
}
Run Code Online (Sandbox Code Playgroud)
queryAdder,如果它很重要,我正在使用它将params添加到url.
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
}
Run Code Online (Sandbox Code Playgroud)