【问题标题】:Push router after successfully fetching data取数据成功后推送路由器
【发布时间】:2021-08-10 22:08:21
【问题描述】:

是否可以在成功获取/检索数据后将用户重定向到另一个页面?在这种情况下,它是关于验证用户的电子邮件地址。当用户点击电子邮件中的给定链接时,他会被重定向到一个页面,在该页面上他的令牌会发送到后端并进行验证。

如果响应成功,我想自动将用户重定向到“/home”页面。不幸的是,它不能以这种方式工作。

If 语句正在工作,因为我在控制台中收到了响应。

<script>
export default {
  async fetch() {
    this.res = await this.$axios.$post(
      `/api/verify-mail/${this.$route.params.id}`
    )

    if (this.res.success) {
      this.$router.push('/home')
      console.log(this.res)
    }
  }
}
</script>

编辑:(改进的代码)

如果条件肯定为真。我在控制台中收到响应。 { success: true, message: 'Your account has been successfully verified' }

因此,条件正常,它正在控制台中写入,但路由器没有推送。

如果它超出条件,它也不起作用。但我发现了一些有趣的东西。如果我强制出错,路由器可以将我推送到“/home”页面。

async fetch() {
   try {
     const res = await this.$axios.$post(
       `/api/verify-mail/${this.$route.params.id}`
     )

     if (res.success) {
       console.log(res)
       this.$router.push('/home')
     }
   } catch (err) {
     this.$router.push('/home') // only for testing, if I force an error I will be redirected
   }
}

home.vue

<template>
  <div>
    <div v-if="getUser.isVerified === false">
      <IsVerified />
    </div>
    <div>
      <h1>Home</h1>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import IsVerified from '../components/verify/IsVerified.vue'
export default {
  auth: false,
  components: { IsVerified },
  computed: {
    ...mapGetters(['getUser']),
  },
}
</script>

验证邮件/_id.vue

<template>
  <div>Test</div>
</template>

<script>
export default {
  data() {
    return {}
  },
  async fetch() {
    try {
      const res = await this.$axios.$post(
        `/api/verify-mail/${this.$route.params.id}`
      )

      if (res.success) {
        console.log(JSON.parse(JSON.stringify(res)))
        console.log(res)
        this.$router.push('/home')
      }
    } catch (err) {
      this.$router.push('/home') // only for testing, if I force an error
    }
  },
}
</script>

<style></style>

IsVerified.vue 组件(/components/verify/IsVerified.vue)

<template>
  <div class="container">
    <div class="message">
      <p>
        Please confirm your email address
        <span class="bold">{{ getUser.email }}</span> to get full access. Token
        is only avaible for 30 minutes.
      </p>
      <button v-show="isShow" @click="sendNewToken()">Send again</button>
      <p v-show="mailSent" class="mail__sent">Email sent</p>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  data() {
    return {
      isShow: true,
      mailSent: false,
    }
  },

  computed: {
    ...mapGetters(['getUser']),
  },

  methods: {
    async sendNewToken() {
      try {
        const send = await this.$axios.$put('/api/send-new-verify-token', {
          data: this.getUser,
        })
        if (send.success) {
          this.isShow = false
          this.mailSent = true
        }
      } catch (err) {
        console.log(err)
      }
    },
  },
}
</script>

package.json

{
  "name": "frontend",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
    "lint": "npm run lint:js"
  },
  "dependencies": {
    "@nuxtjs/auth-next": "5.0.0-1624817847.21691f1",
    "@nuxtjs/axios": "^5.13.6",
    "@nuxtjs/recaptcha": "^1.0.4",
    "core-js": "^3.15.1",
    "nuxt": "^2.15.7",
    "sass": "^1.37.5"
  },
  "devDependencies": {
    "@babel/eslint-parser": "^7.14.7",
    "@nuxtjs/eslint-config": "^6.0.1",
    "@nuxtjs/eslint-module": "^3.0.2",
    "babel-eslint": "^10.1.0",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-nuxt": "^2.0.0",
    "eslint-plugin-prettier": "^3.4.0",
    "eslint-plugin-vue": "^7.15.1",
    "prettier": "^2.3.2",
    "sass-loader": "^7.3.1"
  }
}

nuxt.config.js

const BackendURL = 'http://localhost:4000'

export default {
  head: {
    title: 'frontend',
    htmlAttrs: {
      lang: 'en',
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' },
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
  },

  css: [
    '~/assets/css/main.scss',
    '~/assets/fonts/Nunito.css',
    '~/assets/css/style.css',
  ],

  components: true,

  buildModules: ['@nuxtjs/eslint-module'],

  modules: ['@nuxtjs/axios', '@nuxtjs/auth-next', '@nuxtjs/recaptcha'],

  axios: {
    proxy: true,
    baseURL: BackendURL,
  },

  proxy: {
    '/api': BackendURL,
  },

  auth: {
    strategies: {
      local: {
        token: {
          property: 'token',
          type: 'Bearer',
          name: 'token',
        },
        user: {
          property: false,
        },
        endpoints: {
          login: { url: '/api/login', method: 'post' },
          user: { url: '/api/user', method: 'get' },
          logout: { url: '/api/logout', method: 'post' },
        },
      },
    },

    redirect: {
      login: '/', // User will be redirected to this path if login is required
      logout: '/', //User will be redirected to this path if after logout, current route is protected
      callback: '/home', //User will be redirected to this path by the identity provider after login
      home: '/home', // User will be redirected to this path after login. (rewriteRedirects: true, ... will rewrite this path)
    },
    rewriteRedirects: false,
  },

  recaptcha: {
    hideBadge: true, // Hide badge element (v3 & v2 via size=invisible)
    language: 'english',
    size: 'normal', // Size: 'compact', 'normal', 'invisible' (v2)
    siteKey: 'secret',
    version: 2,
  },

  build: {
    babel: {
      plugins: [
        ['@babel/plugin-proposal-private-property-in-object', { loose: true }],
      ],
    },
  },
}

【问题讨论】:

  • 这应该可以正常工作。你确定this.res.success 是真的吗?仔细检查这个。也许尝试删除条件,看看它是否正常工作。此外,由于生命周期的原因,请尝试使用本地 res = await this... 变量而不是 this.res。如果重定向不成功,您可以随时在下面设置this.res = res
  • 您好,kissu,感谢您的帮助!我认识你,几个月前你帮助了我 :-) 我已经编辑了这个问题。
  • 顺便说一句,这段代码在哪里调用? fetch() 几乎可以在任何地方使用,但仍然可以使用,只是为了了解您的应用程序的流程。
  • 也可以试试console.log(JSON.parse(JSON.stringify(res))) 并检查它是否能正确返回您所期望的。
  • 代码在普通页面中调用,没有组件。 /pages/verify-mail/_id.vue 使用您的控制台语句,响应也按预期返回。

标签: nuxt.js


【解决方案1】:

你的方法应该行得通。尝试登录this.$router 以查看它是否可用/是否包含路线信息。

如果您以后不需要res,则不必等待承诺。当请求成功时重定向到/home,否则捕获错误并且什么都没有。

<script>
export default {
  fetch() {
    this.$axios
      .$post(` / api / verify - mail /${this.$route.params.id}`)
      .then(() => {
        this.$router.push("/home");
      })
      .catch(error => {
        //handly error that happened during the call
      });
  }
};
</script>

这样它就可以在不使用res 对象的情况下工作。

【讨论】:

  • 为什么不等待async fetch() 钩子中的响应?这是它的主要目的。使用.then 的作用基本相同,只是一种较旧的语法。没有价值。
  • This way it works without using a res object,所以如果负载收到200 响应并将this.res.success 设置为false,那么您要重定向到这里?并非每个 API 都经过深思熟虑。
  • 是否需要异步?也许这很方便,因为$fetch 可以作为方法调用& 可以在路由导航或服务器端访问。
  • 无论您使用什么 API,但如果它返回 200,它应该是正确的响应。
  • 这是一个服务器调用,在 JS 上下文中,它完全需要异步。特别是对于页面/组件的生命周期。 fetch() 在服务器上工作得很好,是的,你可以使用 $fetch 但我看不到这里的重点。
【解决方案2】:

试试这种代码,看看它是否适用于你的用例

<script>
export default {
  async fetch() {
    const postedObject = await this.$axios.$post('https://jsonplaceholder.typicode.com/posts', {
      title: 'foo',
      body: 'bar',
      userId: 1,
    })
    console.log('posted object >>', postedObject)
    if (postedObject.title === 'foo') {
      // try with 'baz', it will not router-push
      this.$router.push({ name: 'home' })
    }
  },
}
</script>

这种代码应该完全可以工作。如果不是,则可能是中间件或您的应用配置存在某些特定问题。
出于测试目的,可能需要一个全新的 Nuxt 应用。

【讨论】:

  • 控制台语句按预期返回。路由器不推...
  • 您的 Nuxt 应用有问题。你能分享你的package.jsonnuxt.config.js 文件吗?另外,您能否向我们展示您的页面组件的全部内容? @Antz
  • 完成。顺便说一句,我如何在此处以正确的方式插入代码?这样它就被着色了。
  • @antz 检查我的编辑,通常是3backticksjshtmljson。点击edit,看看我是怎么编辑的。
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 2023-02-14
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2020-06-26
相关资源
最近更新 更多