nuxtjs中asyncData异步数据请求、代理配置、fetch网络请求、vuex的使用、中间件处理

news2024/11/26 22:42:58

文章目录

  • 1. asyncData异步数据请求
  • 2. 代理配置
  • 3. fetch网络请求
  • 4. vuex
    • 4.1 state中的数据展示
    • 4.2 同步方法与异步方法
    • 4.3 数据持久化处理
  • 5. 中间件处理


1. asyncData异步数据请求

Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 和 fetch 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。

asyncData 方法会在组件(限于页面组件,页面组件就是写在 pages 中的组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData方法来获取数据,Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。

注意:由于asyncData方法是在组件初始化前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

<template>
  <div>
    <h3>正在热映</h3>
    <hr>
    <ul>
      <li v-for="item in films" :key="item.filmId">{{ item.name }}</li>
    </ul>
    <hr>
    <nuxt-link to="/">首页</nuxt-link>
  </div>
</template>

<script>
export default {
  data() {
    return {
      films: []
    }
  },
  // 这个函数在服务端执行,参数为一个上下文件对象
  async asyncData({ $axios }) {
    // 如果在此处你进行网络请求,在没有设置baseUrl或代理时,请一定要写全路径,否则得不到你想要的请求
    // https://api.iynn.cn/film 域名也可以写在 nuxt.config.js 配置文件的 baseUrl 中
    let ret = await $axios.get('https://api.iynn.cn/film/api/v1/getNowPlayingFilmList?cors=T&cityId=110100&pageNum=1&pageSize=10')
    // console.log(ret.data.data.films)
    // 返回一个对象,它就赋值到data配置中
    return ret.data.data
  }
}
</script>

<style lang="scss" scoped>

</style>

在这里插入图片描述

注意:在上面的案例中,虽然是服务端渲染,但还是需要后端做跨域处理,因为单单刷新当前请求数据的页面(或者是地址栏回车)时,由于是服务端渲染,所以不存在跨域,但是如果时通过路由跳转到当前页面时,就会出现跨域问题。

2. 代理配置

假如服务端没有帮我们做跨域处理,我们就需要在 nuxt.config.js 中写代理配置。注意写代理时不能再 baseURL 中写全路径。

  axios: {
    // baseURL: '/',
    proxy: true
  },

  proxy: {
    '/api': {
      target: 'https://api.iynn.cn/film',
      changeOrigin: true
    }
  },

  server: {
    // 改端口
    port: 8080
  },

在这里插入图片描述

3. fetch网络请求

我们现在让子组件来负责数据的展示,而父组件负责数据的请求,使用 axios 该怎么做呢?

父组件:

<template>
  <div>
    <h3>正在热映</h3>
    <hr>
    <film-item :films="films" />
    <hr>
    <nuxt-link to="/">首页</nuxt-link>
  </div>
</template>

<script>
export default {
  data() {
    return {
      films: []
    }
  },
  // 参数为一个上下文件对象
  async asyncData({ $axios }) {
    // 如果在此处你进行网络请求,在没有设置baseUrl或代理时,请一定要写全路径,否则得不到你想要的请求
    let ret = await $axios.get('/api/v1/getNowPlayingFilmList?cityId=110100&pageNum=1&pageSize=10')
    return ret.data.data
  }
}
</script>

<style lang="scss" scoped>

</style>

子组件:

<template>
  <div>
    <h3>子组件</h3>
    <ul>
      <li v-for="item in films" :key="item.filmId">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  props: ['films']
}
</script>

<style lang="scss" scoped>

</style>

在这里插入图片描述

我们在第一小节中就知道,asyncData 方法只能在页面组件中使用,而子组件在 components 中,假如我们现在要将网络请求写在子组件中,该怎么做呢?这时候就需要用到 fetch方法。

父组件:

<template>
  <div>
    <h3>正在热映</h3>
    <hr>
    <film-item />
    <hr>
    <nuxt-link to="/">首页</nuxt-link>
  </div>
</template>

<script>
export default {
    
}
</script>

<style lang="scss" scoped>

</style>

子组件:

<template>
  <div>
    <h3>子组件</h3>
    <ul>
      <li v-for="item in films" :key="item.filmId">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      films: []
    }
  },
  // fetch它可以运行在任何的组件中
  async fetch() {
    let ret = await this.$axios.get('/api/v1/getNowPlayingFilmList?cors=T&cityId=110100&pageNum=1&pageSize=10')
    this.films = ret.data.data.films
  }
}
</script>

<style lang="scss" scoped>

</style>

在这里插入图片描述

4. vuex

Nuxt.js 会尝试找到 src 目录(默认是应用根目录)下的 store 目录,如果该目录存在,它将做以下的事情:

  1. 引用 vuex 模块
  2. 将 vuex 模块 加到 vendors 构建配置中去
  3. 设置 Vue 根实例的 store 配置项

4.1 state中的数据展示

store/count.js:

// 以独立的函数方法来定义vuex中的state数据
// 函数的名称一定叫 state
export const state = () => ({
  num: 100
})

pages/count/index.vue:

<template>
  <div>
    <h3>路由 /count</h3>
    <hr>
    <div>vuex中的state数据显示:{{ num }}</div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {

  computed: {
    // 方式1
    // num() {
    //   return this.$store.state.count.num
    // }
    // 方式2
    ...mapState('count', ['num']),
  },
}
</script>

<style lang="scss" scoped>

</style>

在这里插入图片描述

4.2 同步方法与异步方法

store/count.js:

// 以独立的函数方法来定义vuex中的state数据
// 函数的名称一定叫 state
export const state = () => ({
  num: 100
})

// 同步
export const mutations = {
  addNum(state, payload) {
    state.num += payload
  }
}

// 异步
export const actions = {
  asyncAddNum({ commit }, payload) {
    setTimeout(() => {
      commit('addNum', payload)
    }, 1000);
  }
}

pages/count/index.vue:

<template>
  <div>
    <h3>路由 /count</h3>
    <hr>
    <div>vuex中的state数据显示:{{ num }}</div>
    <button @click="addNum">+++++</button>
  </div>
</template>

<script>
import { mapState, mapGetters } from 'vuex'
export default {

  computed: {
    // 方式1
    // num() {
    //   return this.$store.state.count.num
    // }
    // 方式2
    ...mapState('count', ['num']),
    // ...mapGetters('count', ['showNum'])
  },
  methods: {
    addNum() {
      // 同步
      this.$store.commit('count/addNum', 1)
      // 异步
      // this.$store.dispatch('count/asyncAddNum', 2)
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

在这里插入图片描述

推荐插件Nuxt,它可以快速生成 vuex 相关的文件:

在这里插入图片描述

使用方式:按下 ctrl+shift+p 输入 nuxt 然后选择 create store ,最后输入文件名称就可以创建成功:

在这里插入图片描述

在这里插入图片描述

4.3 数据持久化处理

安装js-cookie(客户端路由切换时使用)和cookie-parse(服务端渲染时使用):

yarn add js-cookie cookie-parse

mock 假数据(static/login.json):

{
  "code":0,
  "msg":"ok",
  "data":{
    "uid":1000,
    "token":"fewjlfjewklfewj;fewj;few;"
  }
}

登录页面:

<template>
  <div>
    <h3>我是一个登录页面</h3>
    <hr>
    <div>
      <input type="text" v-model="formData.username">
    </div>
    <div>
      <input type="text" v-model="formData.password">
    </div>

    <hr>
    <button @click="doLogin">进入系统</button>
  </div>
</template>

<script>
// 这样导入,在初始时,在服务器渲染时,它也会导入,这样影响性能
// import cookie from 'js-cookie'

// 渲染环境判断的全局变量
// console.log(process.server);
// console.log(process.client);

// 性能优化所用
const cookie = process.client ? require('js-cookie') : null

export default {
  layout: 'empty',
  data() {
    return {
      formData: {
        username: 'admin',
        password: 'admin888'
      }
    }
  },
  methods: {
    async doLogin() {
      // 进行登录请求的验证
      let ret = await this.$axios.get('/login.json')
      // 登录成功,写入到cookie中,进行vuex数据持久化处理
      cookie.set('token', ret.data.data.token)
      cookie.set('uid', ret.data.data.uid)
      // 写入到vuex中
      this.$store.commit('user/setUserInfo', ret.data.data)

      // 跳转到后台
      this.$router.push('/admin')
    }
  }

}
</script>

<style lang="scss" scoped>

</style>

store/index.js:

export const actions = {
  // 在服务器加载时,会主动执行1次
  nuxtServerInit({ commit }, { req }) {
    // 在服务器端得到当前的cookie数据,cookie数据是通过请求头发送给服务器
    // string
    // token=fewjlfjewklfewj%3Bfewj%3Bfew%3B; uid=1000
    // 方案1
    let cookieStr = req.headers.cookie
    if (cookieStr) {
      let jsonCookie = cookieStr.split(';').reduce((p, c) => {
        let [key, value] = c.split('=')
        p[key.trim()] = value
        return p
      }, {})
      // 同步到vuex中 -- 解决刷新丢失问题
      commit('user/setUserInfo', jsonCookie)
    }
    // 方案2
    // try {
    //   let cookieStr = req.headers.cookie
    //   let jsonCookie = cookieStr.split(';').reduce((p, c) => {
    //     let [key, value] = c.split('=')
    //     p[key.trim()] = value
    //     return p
    //   }, {})
    //   // 同步到vuex中 -- 解决刷新丢失问题
    //   commit('user/setUserInfo', jsonCookie)
    // } catch (error) {

    // }
  }
}

store/user/state.js:

export default () => ({
  uid: 0,
  token: ''
})

store/user/mutations.js:

export default {
  setUserInfo(state, payload) {
    state.uid = payload.uid
    state.token = payload.token
  }
}

在这里插入图片描述

5. 中间件处理

在根目录下创建 middleware 文件,每一个中间件都应该放在这个目录下。

middleware/logincheck.js:

export default ({ store, redirect }) => {

  if (!store.state.user.token) {
    redirect('/login')
  }
}

上面这个中间件表示如果不是登录状态,就会重定向到登录页面。

注册全局中间件:

全局中间件就是每进入一个页面都会执行的中间件,相当于全局前置守卫。它需要在 nuxt.config.js 的 router 中进行配置。

  router: {
    // 全局中间件注册
    middleware: 'checklogin',
    // 动态添加路由 但是一定要注意在pages中不能有_.vue这样的文件,否则路由匹配不成功[push]
    extendRoutes(routes, resolve) {
      /* routes.push({
        path: '/abc',
        component: resolve(__dirname, 'pages/about.vue')
      }) */
      // 如果你用_.vue,则需要用unshift方法来动态添加路由信息
      routes.unshift({
        path: '/abc',
        component: resolve(__dirname, 'pages/about.vue')
      })
    }
  },

匹配布局:

相当于路由独享守卫,写在 layouts/default.vue 中。

<template>
  <div>
    <!-- 它可以理解为子路由 嵌套路由 -->
    <!-- <h3>我是一个默认的全局布局文件</h3> -->
    <!-- 如果你用了全局布局,则在此处一定要添加一个挂载点 -->
    <nuxt />
  </div>
</template>

<script>
export default {
  // 路由独享
  // middleware: 'checklogin'
}
</script>

<style lang="scss" scoped>

</style>

匹配页面:

相当于组件内守卫。

<template>
  <div>
    <h3>我是一个后台</h3>
    <!-- 如果它是一个嵌套路由,则在此处一定要放置挂载点 -->
    <nuxt-child />
  </div>
</template>

<script>
export default {
  // 写在组件或父组件中
  middleware: 'checklogin'
}
</script>

<style lang="scss" scoped>

</style>

如果不是登录状态,就跳转到登录页面,用组件内中间件更合适。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

天宇优配|突然爆雷!大跌15%!

大家好&#xff0c;来一起重视上午的市场行情及最新资讯~ 11月30日上午&#xff0c;上证指数低开0.27%&#xff0c;深证成指跌0.16%&#xff0c;创业板指跌0.16%。盘面上&#xff0c;地产股持续发力&#xff0c;大消费、金融、航运等板块回调。 港股方面&#xff0c;恒指低开0…

命令模式

文章目录思考命令模式1.命令模式的本质2.何时选用命令模式3.优缺点4.实现耦合写法命令模式写法命令模式撤销思考命令模式 命令模式就是解耦强耦合代码&#xff0c;用户只关心功能的实现&#xff0c;开发者却可以利用命令模式在这之间加一些小动作&#xff0c;比如&#xff1a;撤…

天翎知识文档系统+群晖NAS,助力企业实现移动化学习

编者按&#xff1a;移动化学习成为一种社会发展趋势&#xff0c;本文分析了企业移动化学习的意义&#xff0c;并提出了企业移动化学习的一款全新解决方案——天翎知识文档系统群晖NAS。 关键词&#xff1a;多端适配&#xff0c;学习培训&#xff0c;智能问答&#xff0c;在线预…

Javascript脚本运算符执行顺序对照表

Javascript脚本运算符执行顺序对照表&#xff1a;在线查看Javascript脚本运算符执行优先级别 窍门&#xff1a; CtrlF 快速查找 Javascript脚本运算符优先级&#xff0c;是描述在计算机计算表达式时执行运算的先后顺序。Javascript脚本运算符优先级表&#xff0c;同一行中的运算…

巴西队提前出线,预定大力神杯?数据分析告诉你,到底谁才是冠军

2022年卡塔尔世界杯的第一轮小组赛&#xff0c;已经在众多惊诧、悲伤、惊喜的情绪中结束&#xff0c;而仅仅是第一轮的小组比赛&#xff0c;不断爆出的冷门就足以使人大跌眼镜了&#xff1a; 连续34场世界大赛不败的潘帕斯雄鹰——阿根廷&#xff0c;1-2负于世界排名51的沙特&…

天宇优配|百股涨停再现,沪指盘中创近两个月新高

周二A股商场呈现普涨格局&#xff0c;上证指数上涨2.31%&#xff0c;盘中最高点位创出最近两个月新高。各大职业板块近乎全线上涨&#xff0c;地产板块个股掀起涨停潮&#xff0c;数十只地产债盘中涨光临停。此外&#xff0c;A股大金融体现强势&#xff0c;疫苗股则尾盘忽然暴力…

号称Java圣经,Github上爆火的1058页JVM全栈小册到底有什么魅力

对于JVM&#xff0c;我想大部分小伙伴都是要面试了才会去学&#xff0c;其余时间基本不会去看&#xff08;掐指一算&#xff0c;你们书架上面的深入理解Java虚拟机第三版应该都一层灰了吧【手动狗头】&#xff09;。但值得一说的是&#xff0c;当你工作多年之后&#xff0c;你遇…

基于LSCF和LSFD算法在频域中识别快速实现的MIMO研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

TensorFlow Lite 是什么?用 TensorFlow Lite 来转换模型(附代码)

文章目录TensorFlow Lite 做了什么&#xff1f;将一个模型用 TensorFlow Lite 转换训练一个简易模型保存模型转换模型加载 TFLite 模型并分配张量进行预测将在猫狗大战数据集上进行迁移学习的 MobileNetV2 转换到 TensorFlow Lite将模型转换到 TensorFlow Lite优化模型Referenc…

DFL3:软件版本的选择和安装详解

这本是一个简单的问题&#xff0c;但是对于新手而言&#xff0c;所有问题&#xff0c;总是说的越清楚越仔细越好。我之所以这么说&#xff0c;肯定是有人问了。所以我就专门开一篇文章来说一说&#xff0c;软件版本的异同&#xff0c;以及如何选择。针对不同的语言&#xff0c;…

如何快速定位到报错日志中的关键信息,一招学会,赶快GET吧

一般的服务器日志一个可能大的有几十上百m&#xff0c;小的也得几百k&#xff0c;里面内容是比较多的&#xff0c;如拿到日志没思路去看的话&#xff0c;下面一些办法可以让你快速定位到日志中的异常错误信息 文章目录步骤1:定位到错误信息再那个日志中(grep)步骤2:查看日志上下…

[附源码]计算机毕业设计springboot教育企业网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

鲲鹏devkit性能分析工具介绍(三)

鲲鹏devkit性能分析工具介绍&#xff08;三&#xff09; 本篇主要讲解鲲鹏devkit性能分析工具的访存分析功能 访存分析 访存统计分析基于CPU访问缓存和内存的PMU事件&#xff0c;分析存储的访问次数、命中率、带宽等情况。 Miss事件分析基于ARM SPE&#xff08;Statistical…

固话号码认证有什么好处?固话号码认证有什么作用?

固话号码认证为企业提供号码认证服务&#xff0c;在来电时显示企业信息&#xff0c;可提高电话号码辨识度&#xff0c;防止错误标记&#xff0c;确保展现的企业信息与企业的手机终端、APP等多平台展示信息一致&#xff0c;保证品牌企业的身份及商业价值。 那如何上线号码认证服…

图的初识·基本概念

文章目录基本概念图有两种基本形式无向图的表示有向图的表示基本概念 图结构也是数据结构的一部分。而且还有一点小难。图是由多个结点链接而成的&#xff0c;但是一个结点可以同时连接多个其他结点&#xff0c;多个节点也可以同时指向一个节点。【多对多的关系】 图结构是任意…

iPhone升级iOS 16后出现提示“面容ID不可用”怎么办?

最近&#xff0c;很多用户在苹果社区反馈&#xff0c;iPhone升级iOS 16后Face ID不能用了&#xff0c;尝试重置Face ID时&#xff0c;系统会弹窗提示“面容ID不可用&#xff0c;稍后尝试设置面容ID。” 如果你的iPhone在没有摔落手机或是手机进水的情况下出现这个弹窗&#xff…

电脑游戏录屏哪个好用免费?这2款录屏软件,用过都说好!

​相信很多小伙伴都有过在游戏中的精彩操作吧。有些小伙伴想要把自己在游戏中的精彩操作分享给朋友&#xff0c;可是却不知道有什么好用免费的游戏录屏软件&#xff0c;能够将自己游戏里的亮眼表现录制下来。那么电脑游戏录屏哪个好用免费&#xff1f;接下来小编分享2款永久免费…

PyQt5 窗口数据传递

PyQt5 窗口数据传递单一窗口数据传递多窗口数据传递&#xff1a;调用属性多窗口数据传递&#xff1a;信号与槽开发应用程序时&#xff0c;若只有一个窗口则只需关心这个窗口里面的各控件之间如何传递数据。如果程序有多个窗口&#xff0c;就要关心不同的窗口之间是如何传递数据…

History、Location

History、Location 学习路线&#xff1a;JavaScript_BOM->Window对象->confirm()、setInterval()、setTimeout()->History、Location->闪烁的灯泡 History History 对象是 JavaScript 对历史记录进行封装的对象。 History 对象的获取 使用 window.history获取&a…

云小课|云小课教您如何选择Redis实例类型

阅识风云是华为云信息大咖&#xff0c;擅长将复杂信息多元化呈现&#xff0c;其出品的一张图(云图说)、深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云。更多精彩内容请单击此处。 摘要&#xff1a;购买Redis实例时&#xff0c;实例类型有单机、主备、Pr…