首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在NuxtJS中将数据从组件传递到页面?

如何在NuxtJS中将数据从组件传递到页面?
EN

Stack Overflow用户
提问于 2022-09-06 06:32:31
回答 2查看 47关注 0票数 0

我有一个函数,它返回在子组件中创建的true或false。这个子组件在nuxt页面中被调用。就像这样:

子组件

代码语言:javascript
复制
<template>
  <div>
    <h2 class="font-bold text-2xl text-white">Select Your Role</h2>
    <p class="text-gray-90 my-2">
      Select your role that fit most with your needs
    </p>
    <div>
      <div class="flex gap-3">
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label class="cursor-pointer" for="1">SEO Specialist</label>
          <input
            id="1"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="SEO Specialist"
          />
        </div>
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label for="2">Content Writer</label>
          <input
            id="2"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="Content Writer"
          />
        </div>
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label for="3">Product Manager</label>
          <input
            id="3"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="Product Manager"
          />
        </div>
      </div>
      <div class="flex gap-3 my-3">
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label for="4">Business Owner</label>
          <input
            id="4"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="Business Owner"
          />
        </div>
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label for="5">Freelancer</label>
          <input
            id="5"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="Freelancer"
          />
        </div>
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label for="6">SEO / Marketing Agency</label>
          <input
            id="6"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="SEO / Marketing Agency"
          />
        </div>
      </div>
      <div class="flex gap-3">
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <label for="7">Product Marketing Manager</label>
          <input
            id="7"
            v-model="selectedRole"
            class="opacity-60"
            type="radio"
            value="Product Marketing Manager"
          />
        </div>
        <div
          class="flex items-center gap-3 border border-dark-60 p-3 rounded-lg"
        >
          <cm-input placeholder="Other"></cm-input>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SelectPosition',

  data() {
    return {
      selectedRole: '',
      otherRole: '',
    }
  },
  methods: {
    methods: {
      isValid() {
        this.$emit('update:valid', false)
      },
    },
  },
}
</script>

页文件作为父文件

代码语言:javascript
复制
<template>
  <div class="w-full">
    <div class="flex flex-col">
      <div class="container grid grid-cols-12 gap-8 mx-auto p-12">
        <div class="col-span-3"></div>
        <div class="col-span-6">
          <h1 class="font-bold text-3xl text-white">Setting Up the Crawler</h1>
          <p class="text-gray-60 col-span-6">
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempora
            maiores suscipit doloremque!
          </p>
        </div>
      </div>

      <RegisterProgressBar :value="step" :max="5" />

      <div class="container grid grid-cols-12 gap-8 mx-auto p-12">
        <div class="col-span-3 gap-20 mx-3">
          <transition name="fade-in" mode="out-in">
            <div
              class="flex flex-col gap-4 border border-dark-60 rounded-lg h-[200px] max-h-48 items-center mx-11"
            >
              <img
                src="https://www.gravatar.com/avatar/078a5f992a23c763d83473ebeb359c6d.jpg?d=identicon&s=200"
                width="40"
                height="40"
                alt="team picture"
                class="mt-3"
              />
              <div class="flex flex-col items-center gap-1">
                <h3 class="text-lg font-bold">{{ team_name }}</h3>
                <p>{{ domain_label }}</p>
              </div>
              <cm-tooltip>
                <template #toggler>
                  <span class="underline"> What's this? </span>
                </template>
                <span class="dark:text-dark-80">
                  This is a pre-defined team name for you. You can change the
                  name later in the settings.
                </span>
              </cm-tooltip>

              <div
                v-if="keywords.length !== 0"
                class="flex justify-center rounded-lg p-4 mt-3 bg-dark-90 text-gray-60 w-full text-left"
              >
                <div class="flex flex-col gap-1 text-left">
                  <div>
                    <cm-icon class="bx bx-key" />
                    <span class="mx-3 underline">Keywords</span>
                    <span class="font-bold">{{ keywords.length }}</span>
                  </div>
                  <div v-if="selectedCountry.length !== 0">
                    <cm-icon class="bx bx-building" />
                    <span class="mx-3 underline">Countries</span>
                    <span class="font-bold">{{ selectedCountry.length }}</span>
                  </div>
                  <div v-if="selectedLanguage.length !== 0">
                    <cm-icon class="bx bx-user-voice" />
                    <span class="mx-3 underline">Languages</span>
                    <span class="font-bold">{{ selectedLanguage.length }}</span>
                  </div>
                  <div v-if="device.length !== 0">
                    <cm-icon class="bx bx-devices" />
                    <span class="mx-3 underline">Devices</span>
                    <span class="font-bold">{{ device.length }}</span>
                  </div>
                </div>
              </div>
            </div>
          </transition>
        </div>
        <div class="flex flex-col col-span-6">
          <transition name="fade-in" mode="out-in">
            <component :is="currentStepComponent" />
          </transition>
          <div class="flex gap-3 self-end mt-3">
            <cm-button v-if="step > 1" variant="gray" contextual @click="back"
              >Prev</cm-button
            >
            <cm-button variant="gray" :disabled="isValid">Next</cm-button>
          </div>
        </div>
        <div class="col-span-3"></div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import appConfig from '~/config/globals/appConfig'

import RegisterProgressBar from '~/components/new-register/ProgressBar.vue'
import SelectPosition from '~/components/new-register/SelectPosition.vue'
import SelectPlan from '~/components/new-register/SelectPlan.vue'

export default {
  name: 'UserPosition',

  auth: 'guest',

  components: {
    RegisterProgressBar,
    SelectPosition,
    SelectPlan,
  },

  layout: 'new-register/default2',

  data() {
    return {
      team_name: JSON.parse(localStorage.getItem('app.registration.data'))
        .team_name,
      domain_label: JSON.parse(localStorage.getItem('app.registration.data'))
        .domain_label,
      step: 2,
    }
  },
  computed: {
    ...mapState('registration', {
      domain: 'domain',
      keywords: 'keywords',
      selectedLanguage: 'selectedLanguage',
      selectedCountry: 'selectedCountry',
      device: 'device',
    }),
    currentStepComponent() {
      switch (this.step) {
        case 1:
          return 'SelectPosition'
        case 2:
          return 'SelectPosition'
        case 3:
          return 'SelectPlan'
        case 4:
          return 'SelectLanguage'
        case 5:
          return 'SelectDevice'
        default:
          return ''
      }
    },
  },

  methods: {
    back() {
      this.step--
    },

    next() {
      this.step++
      this.submit()
    },

    submit() {
      try {
        console.log({
          ...this.registrationData,
          position: 'selectedRole',
        })
        this.$storage.setUniversal(appConfig.app.registration, {
          ...this.registrationData,
          position: 'selectedRole',
        })
        this.$cmToast({
          title: 'Data stored successfully!',
          icon: 'bx-info-circle',
          variant: 'success',
        })
      } finally {
        this.isLoading = false
      }
    },
  },
}
</script>

简而言之,如果selectedRole和otherRole数据都是空字符串,我希望使next按钮被禁用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-19 11:11:49

我没有解决这个问题,但我想出了另一个办法,用vuex代替道具。

票数 1
EN

Stack Overflow用户

发布于 2022-09-06 06:44:17

您必须在子组件上接受这个自定义事件,我认为您应该将您的自定义事件命名为updateValid,并且从按钮组件中,您在update:valid中的值是未定义的,您必须传递一个正确的值。

代码语言:javascript
复制
<button :isDisabled="isValid" @updateValid="changeValidVal"></button>

在此之后,您可以创建一个方法,我猜您希望更改isValid的值,这样您就可以在这个函数中这样做了。

代码语言:javascript
复制
changeValidVal(val){
  this.isValid = val
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73617622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档