【问题标题】:Access page data on component访问组件上的页面数据
【发布时间】:2020-09-04 06:44:12
【问题描述】:

我正在使用 NUXT 编写我的第一个应用程序。我在这个问题上停留了 2 天,所以我决定问,即使我认为这是一个简单答案的问题(它必须是)。

在我项目的 layouts 我有一个 default.vue 和一个 home.vue

default.vue:

<template>  
  <div>
    <!-- call Header component, this has an nav menu -->
    <Header />

    <!-- call Hero component -->
    <Hero />

    <nuxt />

    <Footer />

  </div>
</template>

<script>
import Header from '~/components/Header.vue'  
import Footer from '~/components/Footer.vue'
import Hero from '~/components/Hero.vue'  

export default {  
  components: {
    Header,
    Footer,
    Hero
  },
}
</script>  

我希望 显示每个页面的数据(标题、副标题和 imageUrl)。这些数据有时来自 apollo 查询请求,有时在页面文件中定义。

我已阅读文档并在此处搜索答案,但我无法实现它。我认为必须考虑 Vuex 商店,但我不知道该怎么做。

谢谢

【问题讨论】:

    标签: vue.js layout vuex nuxt.js apollo


    【解决方案1】:

    您可以在 vuex 中使用 nuxtServerInit 操作作为填充页面数据的一种方式。

    如果您在布局中使用 nuxt >= 2.12, you can use the new-and-improved fetch hook 进行 apollo 查询。

    【讨论】:

      【解决方案2】:

      我做到了!

      所以,我花了一些时间才弄清楚,但在这个过程中我学到了很多东西。 我将在这里提供一些我在此解决方案中使用过的参考资料。

      让我们按照我的做法。我不知道这是否是最好的,但在这里就像一个魅力。

      我在我的 store 文件夹中创建了一个 hero.js 文件:

        data: {
          title: "",
          subtitle: "",
          imgUrl: ""
        }
      })
      
      export const mutations = {
        setData (state, obj) {
          state.data = {...state.data, ...obj}
        }
      }
      
      export const getters = {
        getHero (state) {
          return state.data
        }
      }
      

      然后在我的 default.vue 上我做了:

        <div>
          <!-- call Header component -->
          <Header />
      
          <!-- call Hero component with his slots-->
          <Hero>
            <template v-slot:title>
              <h1 class="title">{{ hero.title }}</h1>
            </template>
      
            <template v-slot:subtitle>
              <h2 class="subtitle">{{ hero.subtitle }}</h2>
            </template>
      
            <template v-slot:heroImg>
              <img :src="hero.imgUrl" />
            </template>
          </Hero>
      
          <!-- This is where all yours pages will be -->
          <nuxt />
      
          <Footer />
      
        </div>
      </template>
      
      <script>  
      // Import Header component
      import Header from '~/components/Header.vue'  
      import Footer from '~/components/Footer.vue'  
      import Hero from '~/components/Hero.vue'  
      
      import { mapGetters } from 'vuex'
      
      export default {
        data(){
          return {
            //declaring hero Obj to contain hero data
            hero: {
              title: "",
              subtitle: "",
              imgUrl: ""
            }
          }
        },
      
        components: {
          Header,
          Footer,
          Hero
        },
      
        //Getting getHero getter from hero.js and saving it to newHero
        computed: mapGetters({
          newHero: 'hero/getHero'
        }),
      
        //watching newHero to change and then updating this.hero Obj. This action will update the displayed data
        watch: {
          newHero: function (obj) {
            this.hero = {...this.hero, ...obj}
          }
        }
      }
      </script>  
      

      在这里我声明变量并存储到 Vuex 存储中:

      <template>  
      ...
      </template>
      
      <script>  
      
      export default {
        data() {
          return {
            hero: {
              title: "Awesome Static title",
              subtitle: "Awesome static subtitle"
            }
          }
        },
      
        //Saving the declared Hero to Vuex Store, then my default.vue will be able to get it through this.$store.getters  
        mounted() {
          this.$store.commit("hero/setData", this.hero);
        },
      }
      </script>  
      

      在某些页面上,标题是从数据库中获取的(使用 Apollo 的 GraphQL)。然后我做了:

      <template>
      ...
      </template>
      
      <script>
      import getLojaInfo from '~/apollo/queries/loja/loja.gql'
      
      export default {  
        //declaring data
        data() {
          return {
            lojas: Array,
            loading: 0,
            hero: {
              title: "",
              subtitle: "",
              imgUrl: ""
            }
          }
        },
      
        //making the query
        apollo: {
          lojas: {
            $loadingKey: 'loading',
            prefetch: true,
            query: getLojaInfo,
            variables () {
              return { slug: this.$route.params.singleLoja }
            },
            //it will wait for query result that and then populate this hero, it will update the hero title, subtitle and image
            result(ApolloQueryResult, key) {
              this.hero.title = ApolloQueryResult.data.lojas[0].name
              this.hero.subtitle = ApolloQueryResult.data.lojas[0].description
              this.hero.imgUrl = ApolloQueryResult.data.lojas[0].logo.url
      
            //then commit it to Vuex Store
              this.$store.commit("hero/setData", this.hero);
      
            }
          },
        },
      }
      </script>
      

      谢谢大家,我会很感激为我的代码做出贡献。

      【讨论】:

        猜你喜欢
        • 2019-10-05
        • 1970-01-01
        • 2014-10-28
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        • 2022-01-24
        • 2020-05-01
        • 1970-01-01
        相关资源
        最近更新 更多