javascript - VueJS/Nuxt/Vuex : How to insert content into template from state

标签 javascript vue.js vuex wordpress-rest-api nuxt.js

我是 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/

相关文章:

javascript - 使用从表单发布返回到 Web 服务的结果

javascript - 使用 JavaScript 从 JPEG 中读取 JPEG 注释的最合适方法是什么?

vue.js - 当 vuex store 中的特定状态发生变化时发出事件

javascript - 使用 Lodash.remove 通过 Vuex 突变更改状态不会触发我的 Vue 组件中的响应式(Reactive)重新渲染

javascript - Vuex 调度不返回

javascript - 如何将类应用于 div 的第一个按钮?

javascript - Openlayers 在 map 上方添加自定义 div

vue.js - Vue 2.0 组件 - 无法呈现模板中的所有 <div>

typescript - 扩展或覆盖 vuex 存储的类型定义

javascript - Vue.js 如何从 Json 属性获取键(左侧值)。