我是 VueJS 新手,正在尝试构建一个应用程序,使用 VueJS、Nuxt 和 Vuex 以及 WordPress REST API 从 WordPress 实例中提取内容。我能够连接到 API,并且通过状态提取内容,但我无法弄清楚如何从状态获取该数据并将其放入模板中。我尝试的所有操作都会导致“x 不是函数”或“x 未定义”错误。
我在网上查看了各种博客文章,但找不到有效的解决方案。我哪里出错了?
store/index.js
import Vuex from "vuex";
import axios from "axios";
const createStore = () => {
return new Vuex.Store({
state: {
explore: null,
pages: null
},
actions: {
getExplore: function(context) {
return new Promise((resolve, reject) => {
if (context.state.explore) {
resolve()
}
else {
axios.get(path_to_api_endpoint)
.then((response) => {
context.commit('storeExplore', response.data)
resolve()
}).catch((error) => {
reject(error);
});
}
})
},
getSinglePage: function() {
return new Promise((resolve, reject) => {
this.$store.dispatch('getExplore')
.then(() => {
var foundPage = false;
this.$store.state.pages
.filter((page) => {
if(pageName === this.$route.params.slug) {
this.singlePage = page;
foundPage = true;
}
});
foundPage ? resolve() : reject();
})
})
}
},
mutations: {
storeExplore(state, response) {
state.explore = response
},
storePages(state, response) {
state.pages = response }
}
})
}
export default createStore
pages/explore/_slug/index.vue(父组件)
<template>
<div>
<layout-browserupgrade></layout-browserupgrade>
<div class="wrapper" :toggle-nav="showHideNav" :class="navState">
<layout-toolbar @showHideNav="showHideNav"></layout-toolbar>
<layout-hero :pageRef="pageId"></layout-hero>
<explore-detail></explore-detail>
<layout-footer></layout-footer>
</div>
<layout-nav></layout-nav>
</div>
</template>
<script>
import layoutBrowserupgrade from '~/components/layout/browserupgrade.vue'
import layoutToolbar from '~/components/layout/toolbar.vue'
import layoutHero from '~/components/layout/heroStatic.vue'
import layoutFooter from '~/components/layout/footer.vue'
import layoutNav from '~/components/layout/nav.vue'
import exploreDetail from '~/components/pages/detail.vue'
const axios = require('axios');
export default {
components: {
layoutBrowserupgrade,
layoutToolbar,
layoutHero,
layoutFooter,
layoutNav,
exploreDetail
},
created: function() {
this.$store.dispatch('getExplore')
},
data: function() {
return {
navState: 'menu-closed',
feedLoaded: false,
pageDetails: [],
pageId: null,
pageType: 'single',
pageName: this.$nuxt.$route.params.slug
}
},
mounted: function() {
this.pageId = this.$nuxt.$route.params.pageId;
},
watch: {
feedLoaded: function() {
if (this.feedLoaded == true) {
this.pageId = this.pageDetails.id;
} else {
console.log('Feed did not load')
}
}
},
methods: {
showHideNav: function(event) {
if (this.navState == 'menu-closed') {
this.navState = 'menu-open'
} else {
this.navState = 'menu-closed'
}
}
}
}
</script>
pages/detail.vue(页面详细信息组件 - 单页面)
<template>
<main class="main detail-page">
<div>
<h1>Explore {{ title.rendered }}</h1>
<div class="detail-wrapper">
<section class="detail-intro detail-content-block"></section>
<section class="detail-map">
<p>Map</p>
</section>
</div>
<section class="detail-history">
<h1>History</h1>
<div class="detail-content-block"></div>
</section>
<section class="detail-wildlife">
<h1>Wildlife and Flora</h1>
<div class="detail-content-block"></div>
</section>
<section class="detail-places">
<h1>Places to See</h1>
</section>
<section class="detail-facilities">
<h1>Accommodation and Facilities</h1>
<div class="detail-content-block"></div>
</section>
<section class="detail-gettingthere">
<h1>Getting to </h1>
<div class="detail-content-block"></div>
</section>
</div>
</main>
</template>
<script>
export default {
created: function() {
},
data: function() {
return {
pageName: this.$nuxt.$route.params.slug,
pageRef: null,
pageContent: null,
pageType: 'single'
}
},
computed: {
exploreContent: function() {
return this.$store.state.explore
},
getSinglePage: function() {
return this.$store.state.pages
}
},
mounted: function() {
},
methods: {
}
}
</script>
<style lang="scss">
.detail-page {
h1 {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: block;
background-color: $crimson;
color: #fff;
text-align: center;
text-transform: uppercase;
margin: 0;
padding: 20px;
font-family: $font-title;
font-size: 28px;
font-weight: 400;
line-height: 1;
letter-spacing: 2px;
}
p {
font-family: $font-default;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
}
}
.detail-wrapper {
display: grid;
}
.detail-intro {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
}
.detail-map {
grid-column-start: 4;
grid-column-end: 6;
grid-row-start: 1;
grid-row-end: 2;
min-width: 40vw;
min-height: 100%;
background-color: #cccccc;
text-align: center;
align-items: center;
justify-content: center;
p {
align-self: center;
justify-self: center;
}
}
.detail-content-block {
padding: 40px;
}
</style>
我已经删除了所有数据插值以进行测试,只是为了看看我是否能让其中一个部分正常工作。
任何人都可以指出一些可以帮助我的文档,或者告诉我哪里出了问题吗?我认为商店部分是正确的,其余部分让我失望。
感谢您提供的任何帮助,因为我没有时间来解决这个问题。
谢谢!
亚历克斯
最佳答案
在您的页面中使用asyncData
,这是仅在页面内的方法,每次在加载页面组件之前都会调用。
安装 axios npm i axios
。一个基于 Promise 处理 ajax 请求的库。
以及pages/detail.vue
<script>
import axios from 'axios'
...
asyncData({ params }) {
return axios
.get(
APIENDPOINT
)
.then(data => {
return {
data
};
})
.catch(e => context.error());
},
...
</script>
要深入了解,请查看文档 https://nuxtjs.org/guide/async-data
关于javascript - VueJS/Nuxt/Vuex : How to insert content into template from state,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53886466/