VueJS/Nuxt/Vuex: 如何将内容从状态插入到模板中
VueJS/Nuxt/Vuex: How to insert content into template from state
我是 VueJS 的新手,我正在尝试构建一个应用程序,使用 VueJS、Nuxt 和 Vuex 以及 WordPress REST API 从 WordPress 实例中提取内容。我能够连接到 API,并且我有通过状态拉入的内容,但我无法弄清楚如何从状态获取数据并将其导入模板。我尝试的所有操作都会导致 "x is not a function" 或 "x is not defined" 错误。
我查看了各种在线博客文章,但找不到有效的解决方案。我哪里错了?
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
我是 VueJS 的新手,我正在尝试构建一个应用程序,使用 VueJS、Nuxt 和 Vuex 以及 WordPress REST API 从 WordPress 实例中提取内容。我能够连接到 API,并且我有通过状态拉入的内容,但我无法弄清楚如何从状态获取数据并将其导入模板。我尝试的所有操作都会导致 "x is not a function" 或 "x is not defined" 错误。
我查看了各种在线博客文章,但找不到有效的解决方案。我哪里错了?
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