一篇文章带你快速入门 Nuxt.js 服务端渲染

news2024/10/6 10:40:04

在这里插入图片描述

1. Nuxt.js 概述

1.1 我们一起做过的SPA

  • SPA(single page web application)单页 Web 应用,Web 不再是一张张页面,而是一个整体的应用,一个由路由系统、数据系统、页面(组件)系统等等,组成的应用程序。

  • 我们之前学习的Vue就是SPA中的佼佼者。

  • SPA 应用广泛用于对SEO要求不高的场景中

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2 什么是SEO

  • SEO:搜索引擎优化(Search Engine Optimization), 通过各种技术(手段)来确保,我们的Web内容被搜索引擎最大化收录,最大化提高权重,最终带来更多流量。

  • 非常明显,SPA程序不利于SEO

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • SEO解决方案:提前将页面和数据进行整合

    • 前端:采用SSR
  • 后端:页面静态化 (freemarker 、thymeleaf、velocity)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.3 什么是SSR技术

  • 服务端渲染(Server Side Render),即:网页是通过服务端渲染生成后输出给客户端。

    • 在SSR中,前端分成2部分:前端客户端、前端服务端
    • 前端服务端,用于发送ajax,获得数据
    • 前端客户端,用于将ajax数据和页面进行渲染,渲染成html页面,并响应给调用程序(浏览器、爬虫)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 如果爬虫获得html页面,就可以启动处理程序,处理页面内容,最终完成SEO操作。

1.4 SPA和SSR对比

SPA单页应用程序SSR服务器端渲染
优势1.页面内容在客户端渲染
2. 只关注View层,与后台耦合度低,前后端分离
3.减轻后台渲染画面的压力
1.更好的SEO,搜索引擎工具可以直接查看完全渲染的画面
2.更快的内容到达时间 (time-to-content),用户能更快的看到完整渲染的画面
劣势1.首屏加载缓慢
2.SEO(搜索引擎优化)不友好
1.更多的服务器端负载
2.涉及构建设置和部署的更多要求,需要用Node.js渲染
3.开发条件有限制,一些生命周期将失效
4.一些常用的浏览器API无法使用

1.5 什么是Nuxt.js

  • Nuxt.js 是一个基于 Vue.js 的通用应用框架。

    • Nuxt支持vue的所有功能,此类内容为前端客户端内容。
    • Nuxt特有的内容,都是前端服务端内容。
  • 通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染

  • Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。

2 入门案例

2.1 create-nuxt-app 介绍

  • Nuxt.js 提供了脚手架工具 create-nuxt-app

  • create-nuxt-app 需要使用 npx

  • npx 命令为 NPM版本5.2.0默认安装组件

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2 安装

npx create-nuxt-app <project-name>
  • 例如
npx create-nuxt-app demo_nuxt02

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.3 启动

npm run dev

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • nuxtjs改善

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.4 访问

http://localhost:3000

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. 目录结构

3.1 目录

目录名称描述
assets资源目录,用于存放需要编译的静态资源。例如:LESS、SASS等
默认情况下,Nuxt使用Webpack若干加载器处理目录中的文件
componentsvue组件目录,Nuxt.js 不会增强该目录,及不支持SSR
layouts布局组件目录
pages页面目录,所有的vue视图,nuxt根据目录结构自动生成对应的路由。
plugins插件目录
static静态文件目录,不需要编译的文件
storevuex目录
nuxt.config.jsnuxt个性化配置文件,内容将覆盖默认
package.json项目配置文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.2 别名

  • assets 资源的引用:~ 或 @

    // HTML 标签
    <img src="~assets/13.jpg" style="height:100px;width:100px;" alt="">
    <img src="~/assets/13.jpg" style="height:100px;width:100px;" alt="">
    <img src="@/assets/13.jpg" style="height:100px;width:100px;" alt="">
    
    // CSS
    background-image: url(~assets/13.jpg);
    background-image: url(~/assets/13.jpg);
    background-image: url(@/assets/13.jpg);
    
  • static 目录资源的引用:/ 直接引用

    //html标签
    <img src="/12.jpg" style="height:100px;width:100px;" alt="">
    
    //css
    background-image: url(/12.jpg);
    
  • 实例

    <template>
      <div>
        <!-- 引用 assets 目录下经过 webpack 构建处理后的图片 -->
        <img src="~assets/13.jpg" style="height:100px;width:100px;" alt="">
    
        <!-- 引用 static 目录下的图片 -->
        <img src="/12.jpg" style="height:100px;width:100px;" alt="">
    
        <!-- css -->
        <div class="img1"></div>
        <div class="img2"></div>
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
      .img1 {
        height: 100px;
        width: 100px;
        background-image: url(~assets/13.jpg);
        background-size: 100px 100px;
        display: inline-block;
      }
      .img2 {
        height: 100px;
        width: 100px;
        background-image: url(/12.jpg);
        background-size: 100px 100px;
        display: inline-block;
      }
    </style>
    

4 路由

4.1 路由概述

  • Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
  • 要在页面之间切换路由,我们建议使用<nuxt-link> 标签。
标签名描述
<nuxt-link>nuxt.js中切换路由
<Nuxt />nuxt.js的路由视图
<router-link>vue默认切换路由
<router-view/>vue默认路由视图

4.2 基础路由

  • 自动生成基础路由规则
路径组件位置及其名称规则
/pages/index.vue默认文件 index.vue
/userpages/user/index.vue默认文件 index.vue
/user/onepages/user/one.vue指定文件
  • 实例

    情况1:访问路径,由pages目录资源的名称组成(目录名称、文件的名称)
      - 资源位置: ~/pages/user/one.vue
      - 访问路径:http://localhost:3000/user/one
    
    
    情况2:每一个目录下,都有一个默认文件 index.vue
      - 资源位置: ~/pages/user/index.vue
      - 访问路径:http://localhost:3000/user
    
  • 思考:/user 可以匹配几种文件?

    • pages/user.vue 文件 【优先级高】
    • pages/user/index.vue 文件

4.3 动态路由

  • 在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
路由中路径匹配组件位置及其名称
/pages/index.vue
/user/:idpages/user/_id.vue
/:slugpages/_slug/index.vue
/:slug/commentspages/_slug/comments.vue
  • 实例1:获得id值,创建资源 user/_id.vue
<template>
  <div>
    查询详情 {{this.$route.params.id}}
  </div>
</template>

<script>
export default {
  transition: 'test',
  mounted() {
    console.info(this.$route)
  },
}
</script>

<style>

</style>

4.4 动态命名路由

  • 路径 /news/123 匹配_id.vue还是_name.vue

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 我们可以使用<nuxt-link>解决以上问题

    • 通过name 确定组件名称:“xxx-yyy”
    • 通过params 给对应的参数传递值
<nuxt-link :to="{name:'news-id',params:{id:1002}}">第2新闻</nuxt-link>
<nuxt-link :to="{name:'news-name',params:{name:1003}}">第3新闻</nuxt-link>

4.5 默认路由

路径组件位置及其名称
不匹配的路径pages/_.vue
  • 404页面,可以采用 _.vue进行处理

4.6 嵌套路由(知道)

  • 创建嵌套子路由,你需要添加一个 父组件Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。

    • 要求:父组件 使用<nuxt-child/> 显示子视图内容
    pages/
    --| book/						//同名文件夹
    -----| _id.vue
    -----| index.vue
    --| book.vue					//父组件
    
  • 步骤1:编写父组件 pages/child/book.vue

    <template>
      <div>
          <nuxt-link to="/child/book/list">书籍列表</nuxt-link> |
          <nuxt-link to="/child/book/123">书籍详情</nuxt-link> |
          <hr>
          <nuxt-child />
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
    
    </style>
    
    
  • 步骤2:编写子组件 pages/child/book/list.vue

    <template>
      <div>书籍列表</div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
    
    </style>
    
    
  • 步骤3:编写子组件 pages/child/book/_id.vue

    <template>
      <div>书籍详情{{$route.params.id}} </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
    
    </style>
    
    

4.7 过渡动效(了解)

4.7.1 全局过渡动效设置

  • Nuxt.js 默认使用的过渡效果名称为 page

    • .page-enter-active样式表示进入的过渡效果。
    • .page-leave-active样式表示离开的过渡效果。
  • 步骤1:创建 assets/main.css,编写如下内容:

    .page-enter-active, .page-leave-active {
      transition: opacity .5s;
    }
    .page-enter, .page-leave-active {
      opacity: 0;
    }
    
  • 步骤2:nuxt.config.js 引入main.css文件

    module.exports = {
      css: [
        'assets/main.css'
      ]
    }
    

4.7.1 自定义动画

  • 如果想给某个页面自定义过渡特效的话,只要在该页面组件中配置 transition 字段即可:

  • 步骤1:在全局样式 assets/main.css 中添加名称为test的过渡效果

    .test-enter-active, .test-leave-active {
      transition: all 2s;
      font-size:12px;
    }
     .test-enter, .test-leave-active {
      opacity: 0;
      font-size:40px;
    }
    
    
  • 步骤2:需要使用特效的vue页面编写如下:

    export default {
      transition: 'test'
    }
    

4.8 案例:学生管理

  • 需求1:首页

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 需求2:点击,学生管理

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 需求3:点击“添加”按钮

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 需求4:点击修改按钮

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 需求5:详情

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5. 视图

5.1 默认模板(了解)

  • 定制化默认的 html 模板,只需要在应用根目录下创建一个 app.html 的文件。

  • 默认模板:

    <!DOCTYPE html>
    <html {{ HTML_ATTRS }}>
      <head {{ HEAD_ATTRS }}>
        {{ HEAD }}
      </head>
      <body {{ BODY_ATTRS }}>
        {{ APP }}
      </body>
    </html>
    
  • 修改模板,对低版本IE浏览器进行支持(兼容IE浏览器)

    <!DOCTYPE html>
    <!--[if IE 9]><html lang="en-US" class="lt-ie9 ie9" {{ HTML_ATTRS }}><![endif]-->
    <!--[if (gt IE 9)|!(IE)]><!--><html {{ HTML_ATTRS }}><!--<![endif]-->
      <head {{ HEAD_ATTRS }}>
        {{ HEAD }}
      </head>
      <body {{ BODY_ATTRS }}>
        {{ APP }}
      </body>
    </html>
    

5.2 默认布局【掌握】

5.2.1 布局概述

  • 布局:Nuxt.js根据布局,将不同的组件进行组合。

  • 模板:html页面,是布局后所有组件挂载的基础。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.2.2 布局分析

  • layouts/default.vue 默认布局组件
    • 访问路径根据路由,确定执行组件
    • 组件具体显示的位置,有布局来确定

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.2.3 公共导航

  • 修改 layouts/default.vue
<template>
  <div>
    <nuxt-link to="/">首页</nuxt-link> |
    <nuxt-link to="/user/login">登录</nuxt-link> |
    <nuxt-link to="/user/123">详情</nuxt-link> |
    <nuxt-link to="/about">默认页</nuxt-link> |
    <nuxt-link to="/nuxt/async">async</nuxt-link> |
    <hr/>
    <Nuxt />
  </div>
</template>

5.3 自定义布局

  • 在layouts目录下创建组件:layouts/blog.vue

    <template>
    	<div>
            开头<br/>
            <nuxt/>
            结束<br/>
        </div>
      
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
    
    </style>
    
    
  • 在需要的视图中使用 blog布局

    <script>
    export default {
      layout: 'blog'
      //...
    }
    </script>
    
    

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.4 错误页面(了解)

  • 编写layouts/error.vue页面,实现个性化错误页面
<template>
  <div>
    <div v-if="error.statusCode == 404">
      404 页面不存在 {{error.message}}
    </div>
    <div v-else>
      应用程序错误
    </div>
    <nuxt-link to="/">首 页</nuxt-link>
  </div>
</template>

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

<style>

</style>

  • 解决问题: 404 、500、连接超时(服务器关闭)
  • 总结:所学习的技术中,有2种方式处理错误页面
    • 方式1:默认路径,_.vue (先执行)
    • 方式2:错误页面,~/layouts/error.vue

6 Nuxt组件特殊配置

6.1 概述

  • Nuxt页面组件实际上是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项(在Vue组件的基础上,添加了额外功能)
特殊配置项描述
asyncDataSSR进行异步数据处理,也就是服务器端ajax操作区域。
fetch在渲染页面之前获取数据填充应用的状态树(store)
head配置当前页面的head标签,整合第三方css、js等。
layout指定当前页面使用的布局
transition指定页面切换的过渡动效
scrollToTop布尔值,默认: false。 用于判定渲染页面前是否需要将当前页面滚动至顶部。

6.2 模板代码

<template>
  <h1 class="red">Hello {{ name }}!</h1>
</template>

<script>
export default {
  asyncData (context) {					//异步处理数据, 每次加载之前被调用
    return { name: 'World' }
  },	
  fetch () {							//用于在渲染页面之前获取数据填充应用的状态树(store)
    
  },
  head: {								//配置当前页面的 Meta 标签
  },
  layout: '自定义布局名'					//自定义布局
  ...
}
</script>

<style>
.red {
  color: red;
}
</style>

6.3 head - 入门

  • html模板代码

    <html>
    <head>
    	<meta charset="UTF-8" />
    	<title>我是标题</title>
    	<link rel="stylesheet" type="text/css" href="css外部文件"/>
    	<script src="js外部文件" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
    </body>
    </html>
    
  • 通过nuxt提供head属性,可以给单个也是设置:标题、外部css、外部js 等内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 基本模板

    <script>
    export default {
      head: {
        link: [],       //导入第三方css文件,可以导入多个
        script: []      //导入第三方js文件,可以导入多个
      }
    }
    </script>
    
  • 完整代码

<template>
  <div>
    详情页 {{$route.params.id}} <br/>

    <div class="bg2"></div>
    <div class="bg3"></div>

  </div>
</template>

<script>
export default {
  head: {
    title: '详情页',
    link: [
      {rel:'stylesheet',href:'/style/img.css'},....
    ],
    script: [
      { type: 'text/javascript', src: '/js/news.js' }
    ]
  }
}
</script>

<style>
  .bg2 {
    background-image: url('~static/img/2.jpg');
    width: 300px;
    height: 300px;
    background-size: 300px;
  }
</style>

7. ajax操作

7.1 整合 axios

7.1.1 默认整合

  • 在构建项目时,如果选择axios组件,nuxt.js将自动与axios进行整合

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.1.2 手动整合(可选)

  • 步骤1:package.json有axios的版本

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      "dependencies": {
        "@nuxtjs/axios": "^5.13.1",
      },
    
  • 步骤2:安装

    npm install
    
  • 步骤3:nuxt.config.js 以模块的方式添加axios

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      modules: [
        // https://go.nuxtjs.dev/axios
        '@nuxtjs/axios',
      ],
    

7.1.3 常见配置

  • 修改 nuxt.config.js 进行baseURL的配置

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      // Axios module configuration: https://go.nuxtjs.dev/config-axios
      axios: {
        baseURL:'http://localhost:10010/'
      },
    

7.2 使用axios发送ajax

  • 在vue页面中,通过 this. a x i o s . x x x ( ) 操作 a j a x 。 t h i s . axios.xxx() 操作ajax。this. axios.xxx()操作ajaxthis.axios 与之前 axios等效。

    this.$axios.post("/search-service/search",this.searchMap).then( res => {
        //获得查询结果
        this.searchResult = res.data.data;
    });
    

7.3 使用asyncData发送 ajax

  • asyncData中的ajax将在“前端服务端执行”,在浏览器看到是数据,而不是ajax程序。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.3.1 发送一次请求

  • 语法:
export default {
	async asyncData( context ) {  //context就相当于其他地方的this
        //发送ajax
        let { data } = await context.$axios.get('路径','参数')
        // 返回结果
        return {变量: 查询结果从data获取 }
	},
}
  • 实例

    <template>
      <div>{{echo}}</div>
    </template>
    
    <script>
    export default {
      async asyncData(context) {
        // 发送ajax
        let {data} = await context.$axios.get('/service-consumer/feign/echo/abc')
        // 返回数据
        return {
          echo: data
        }
      },
    }
    </script>
    
    <style>
    
    </style>
    
    

7.3.2 发送多次请求

  • 语法1:

    export default {
        async asyncData( content ) {
            let [结果1,结果2] = await Promise.all([ ajax请求1, ajax请求2])
            return {
                变量1: 结果1,
                变量2: 结果2
            }
        },
    }
    
  • 语法2:

    export default {
        async asyncData( content ) {
            let [{数据:别名1},{数据:别名2}] = await Promise.all([ ajax请求1, ajax请求2])
            return {
                变量1: 别名1,
                变量2: 别名2
            }
        },
    }
    
    //演化过程
    let response = ajax请求
    let [response,response] = await Promise.all([ajax1,ajax2])
    let [{data},{data}] = await Promise.all([ajax1,ajax2])
    let [{data:别名1},{data:别名2}] = await Promise.all([ajax1,ajax2])
    
  • 实例

<template>
  <div>{{echo}} {{echo2}}</div>
</template>

<script>
export default {
  async asyncData(context) {
    // 发送ajax
    let [{data:echo}, {data:echo2}] = 
                await Promise.all([
                    context.$axios.get('/service-consumer/feign/echo/abc'),
                    context.$axios.get('/service-consumer/client/echo/abc')
                ])

    // 返回数据
    return {
      echo,
      echo2
    }
  },
}
</script>

<style>

</style>

7.4 使用fetch发送 ajax

  • fetch 方法用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 步骤1:创建store/index.js

    export const state = () => ({
      str: 0
    })
    
    export const mutations = {
      setData (state, value) {
        state.str = value
      }
    }
    
  • 步骤2:测试页面

    <template>
      <div>
        <!-- 显示数据 -->
        {{$store.state.str}}
      </div>
    </template>
    
    <script>
    
    export default {
      async fetch( {store, $axios} ) {
        // 发送ajax
        let { data } = await $axios.get('/service-consumer/feign/echo/abc')
        // 设置数据
        store.commit('setData' , data )
      }
    }
    </script>
    
    <style>
    
    </style>
    
    

7.5 插件:自定义axios

7.5.0 分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7.5.1 客户端

  • 步骤一:在nuxt.conf.js中配置客户端插件,设置 mode 为 client

      plugins: [
        { src: '~plugins/api_client.js', mode: 'client' }
        //{ src: '~plugins/api.js', ssr: false }
      ],
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 步骤二:编写 plugins/api_client.js 对 内置的 $axios进行增强

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    //自定义函数
    const request = {
      test : (params) => {
        return axios.get('/service-consumer/feign/echo/abc',{
          params
        })
      },
    }
    
    var axios = null
    export default ({ $axios }, inject) => {
    
      //3) 保存内置的axios
      axios = $axios
    
      //4) 将自定义函数交于nuxt
      // 使用方式1:在vue中,this.$request.xxx()
      // 使用方式2:在nuxt的asyncData中,content.app.$request.xxx()
    
      inject('request', request)
    }
    
    

7.5.2 服务端

  • 步骤一:配置服务端插件,设置 mode 为 server

      plugins: [
        { src: '~plugins/api_client.js', mode: 'client' },
        { src: '~plugins/api_server.js', mode: 'server' },
        //{ src: '~plugins/api.js', ssr: false },
        //{ src: '~plugins/api.server.js', ssr: true }
      ],
    
  • 步骤二:编写 plugins/api.server.js 对 内置的 $axios进行增强

    const request = {
      test : (params) => {
        return axios.get('/service-consumer/feign/echo/abc',{
          params
        })
      },
      
    }
    
    var axios = null
    export default ({ $axios, redirect, process }, inject) => {
    
      //赋值
      axios = $axios
    
      //4) 将自定义函数交于nuxt
      // 使用方式1:在vue中,this.$requestServer.xxx()
      // 使用方式2:在nuxt的asyncData中,content.app.$requestServer.xxx()
      inject('requestServer', request)
    }
    
    
  • 注意:前端服务端插件,不支持切换路由。也就是说刷新可以访问,使用<nuxt-link>切换不能访问。解决方案:

    • 方案1:修改mode,支持client和service。
    • 方案2:使用 location.href = ‘路径’ 进行跳转

7.5.3 插件配置总结

//方式1:通过src设置文件,通过mode设置模式
plugins: [
	{ src: '~/plugins/apiclient.js', mode: 'client' },		//前端客户端
	{ src: '~/plugins/apiserver.js', mode: 'server' },		//前端服务端
    { src: '~/plugins/api.js' }								//前端客户端 + 前端服务端
]

//方式2:通过命名来确定模式
plugins: [
    '~/plugins/api.client.js',				//前端客户端
    '~/plugins/api.server.js',				//前端服务端
    '~/plugins/api.js',						//前端客户端 + 前端服务端
]

8. Vuex 状态树

8.1 根模块数据操作

  • 步骤一:创建 store/index.js 添加一个 counter变量,并可以继续累加操作

    export const state = () => ({
      counter: 0
    })
    
    export const mutations = {
      increment (state) {
        state.counter++
      }
    }
    
    
  • 步骤二:在页面中,使用

    <template>
      <div>
        首页 {{counter}}
        <input type="button" value="+" @click="increment"/>
      </div>
    </template>
    
    <script>
    import { mapState,mapMutations } from 'vuex'
    export default {
      computed: {
        ...mapState(['counter'])
      },
      methods: {
        ...mapMutations(['increment'])
      },
    }
    </script>
    
    <style>
    
    </style>
    
    

8.2 其他模块数据操作

  • 步骤一:创建其他模块 store/book.js

    export const state = () => ({
      money: 0
    })
    
    export const mutations = {
      addmoney (state) {
        state.money += 5
      }
    }
    
  • 步骤二:使用指定模块中的数据

    <template>
      <div>
        金额:{{money}} <br>
        <input type="button" value="累加" @click="addMoney(5)">
      </div>
    </template>
    
    <script>
    import {mapState, mapMutations} from 'vuex'
    export default {
      methods: {
        // ...mapMutations({'方法名':'模块/action名称'})
        ...mapMutations({'addMoney':'book/addMoney'})
      },
      computed: {
        //...mapState('模块名称',['变量'])
        ...mapState('book',['money'])
      }
    }
    </script>
    
    <style>
    
    </style>
    

8.3 完整vuex模板

// state为一个函数, 注意箭头函数写法
const state = () => ({
  user: 'jack'
})

// mutations为一个对象
const mutations = {
  setUser(state, value) {
    state.counter = value
  }
}
// action执行mutation
const actions = {
  userAction (context,value){
    // 可以发送ajax
    context.commit('setUser',value)
  }

}

// 获取数据
const getters = {
  getUser (state) {
    return state.user
  }
}
export default {
  namespace: true,	// 命名空间,强制要求,在使用时,加上所属的模块名,例如:book/addmoney
  state,
  mutations,
  actions,
  getters
}

9. nuxt流程总结

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

10. Nuxt整合Element UI

11 综合练习

10.1 练习1:学生列表

  • 表结构

    #班级表
    create table tab_class(
      cid int primary key auto_increment,
      cname varchar(50)
    );
    insert into tab_class(cid, cname) values(1,'Java56');
    insert into tab_class(cid, cname) values(2,'Java78');
    
    #学生表
    create table tab_student(
      sid int primary key auto_increment,
      sname varchar(50),
      cid int
    );
    
    insert into tab_student(sname,cid) values('张三',1);
    insert into tab_student(sname,cid) values('李四',1);
    insert into tab_student(sname,cid) values('王五',2);
    insert into tab_student(sname,cid) values('赵六',2);
    
    
  • 需求:查询学生列表信息

    • 要求1:可以进行“班级”条件查询
    • 要求2:对“班级”数据进行SEO
    • 要求3:学生数据不进行SEO

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

10.2 练习2:

10.2.1 表结构:

CREATE TABLE tb_teacher(
  tid INT PRIMARY KEY AUTO_INCREMENT,
  tname VARCHAR(50) COMMENT '老师姓名',
  TYPE INT COMMENT '老师类型:1.授课老师、2.助理老师、3.辅导员老师'
);
INSERT INTO tb_teacher(tid,tname,TYPE) VALUES(1,'梁桐老师',1);
INSERT INTO tb_teacher(tid,tname,TYPE) VALUES(2,'马坤老师',2);
INSERT INTO tb_teacher(tid,tname,TYPE) VALUES(3,'仲燕老师',3);
INSERT INTO tb_teacher(tid,tname,TYPE) VALUES(4,'袁新奇老师',1);
INSERT INTO tb_teacher(tid,tname,TYPE) VALUES(5,'任林达老师',2);
INSERT INTO tb_teacher(tid,tname,TYPE) VALUES(6,'王珊珊老师',3);

CREATE TABLE tb_class(
  cid INT PRIMARY KEY AUTO_INCREMENT,
  cname VARCHAR(50) COMMENT '班级名称',
  teacher1_id INT COMMENT '授课老师',
  teacher2_id INT COMMENT '助理老师',
  teacher3_id INT COMMENT '辅导员老师'
);

INSERT INTO tb_class(cid,cname,teacher1_id,teacher2_id,teacher3_id) VALUES(1,'Java56',1,2,3);
INSERT INTO tb_class(cid,cname,teacher1_id,teacher2_id,teacher3_id) VALUES(2,'Java78',1,2,3);
INSERT INTO tb_class(cid,cname,teacher1_id,teacher2_id,teacher3_id) VALUES(3,'Java12',4,5,6);
INSERT INTO tb_class(cid,cname,teacher1_id,teacher2_id,teacher3_id) VALUES(4,'Java34',4,5,6);

10.2.2 需求:查询

  • 需求:使用“自定义axios”完成
    • 查询班级详情
    • 通过班级名称模糊查询
    • 查询班级的同时,查询老师信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

10.2.3 扩展需求:添加

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

end

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

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

相关文章

【AI】以大厂PaaS为例,看人工智能技术方案服务能力的方向(2/2)

目录 三、解决方案 3.1 人脸身份验证 3.2 图像审核&#xff08;暴恐、色情等&#xff09; 3.3 人脸会场签到 3.4 机器人视觉 3.5 视频审核 3.6 电商图文详情生成 3.7 智能客服 接上回&#xff1a; 【AI】以大厂PaaS为例&#xff0c;看人工智能技术方案服务能力的方向&…

【mysql】事物与隔离级别

事物 事务(Transaction)是并发控制的基本单位。所谓的事务呢&#xff0c;它是一个操作序列&#xff0c;这些操作要么都执行&#xff0c;要么都不执行&#xff0c;它是一个不可分割的工作单位。 事务具有四大特性&#xff0c;通常称为ACID特性&#xff1a; 原子性&#xff08…

数据可视化免费化:趋势背后的动因

在数字化浪潮的推动下&#xff0c;数据可视化已成为解读和利用数据的关键工具。作为一个需要经常接触各种数据可视化软件的设计师&#xff0c;我发现数据可视化工具的免费化进程正在加速。为何越来越多的数据可视化工具选择走向免费之路&#xff1f;让我们一起探讨其中的原因。…

经典神经网络——ResNet模型论文详解及代码复现

论文地址&#xff1a;Deep Residual Learning for Image Recognition (thecvf.com) PyTorch官方代码实现&#xff1a;vision/torchvision/models/resnet.py at main pytorch/vision (github.com) B站讲解&#xff1a; 【精读AI论文】ResNet深度残差网络_哔哩哔哩_bilibili …

有关实时3D渲染:定义、工作原理和应用方向

随着新兴技术——3D渲染的发展&#xff0c;交互应用的质量有了极大的提高。用实时三维渲染软件创建的沉浸式数字体验&#xff0c;几乎与现实没有区别了。随着技术的逐步改进&#xff0c;在价格较低的个人工作站上渲染3D图像变得更加容易&#xff0c;设计师的投入也逐渐变少。 什…

一文搞懂什么是Hadoop

Hadoop概念 什么是Hadoop Hadoop是一个由Apache基金会所开发的用于解决海量数据的存储及分析计算问题的分布式系统基础架构。 广义上来说&#xff0c;Hadoop通常指一个跟广泛的概念——Hadoop生态圈。 以下是hadoop生态圈中的技术&#xff1a; Hadoop优势 hadoop组成 HDFS…

单例模式---饿汉式、懒汉式

一、什么是单例模式 单例模式&#xff0c;指的是一个类中的对象只能有一个&#xff0c;它在内存中只会创建一次对象的设计模式。 二、饿汉式 public class SingleTon {// 私有的构造方法private SingleTon() {};// 1. 饿汉式private static SingleTon instance new SingleTon…

【Java 基础】26 枚举

文章目录 1. 什么是枚举2. 定义3. 使用1&#xff09;常量2&#xff09;遍历3&#xff09;switch 4. 属性和方法1&#xff09;属性2&#xff09;方法 5. 实现原理6. 使用场景总结 1. 什么是枚举 枚举是列出某些有穷序列集的所有成员的程序&#xff0c;或者是一种特定类型对象的计…

第17章:随堂复习与企业真题(反射机制)

第17章&#xff1a;随堂复习与企业真题&#xff08;反射机制&#xff09; 一、随堂复习 1. 反射的概述&#xff08;熟悉&#xff09; Java给我们提供了一套API&#xff0c;使用这套API我们可以在运行时动态的获取指定对象所属的类&#xff0c;创建运行时类的对象&#xff0c;…

12.08

1.头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget(); signals:v…

One-to-Few Label Assignment for End-to-End Dense Detection阅读笔记

One-to-Few Label Assignment for End-to-End Dense Detection阅读笔记 Abstract 一对一&#xff08;o2o&#xff09;标签分配对基于变换器的端到端检测起着关键作用&#xff0c;最近已经被引入到全卷积检测器中&#xff0c;用于端到端密集检测。然而&#xff0c;o2o可能因为…

Aligning Large Multi-Modal Model with Robust Instruction Tuning

Abstract 尽管多模态任务取得了有希望的进展&#xff0c;但当前的大型多模态模型&#xff08;LMM&#xff09;很容易产生与相关图像和人类指令 不一致的描述的幻觉。 LRV-指令。我们通过引入第一个大型且多样化的视觉指令调整数据集来解决这个问题&#xff0c;该数据集名为大…

DOS 批处理 (一)

DOS 批处理 1. 批处理是什么&#xff1f;2. DOS和MS-DOS3. 各种操作系统shell的区别Shell 介绍图形用户界面&#xff08;GUI&#xff09;shell命令行界面&#xff08;CLI&#xff09;的 shell命令区别 1. 批处理是什么&#xff1f; 批处理(Batch)&#xff0c;也称为批处理脚本…

el-tree数据量过大,造成浏览器卡死、崩溃

el-tree数据量过大&#xff0c;造成浏览器卡死、崩溃 场景&#xff1a;树形结构展示&#xff0c;数据超级多&#xff0c;超过万条&#xff0c;每次打开都会崩溃 我这里采用的是引入新的插件虚拟树&#xff0c;它是参照element-plus 中TreeV2改造vue2.x版本虚拟化树形控件&…

基于微服务架构的外卖系统源码开发

在当前互联网时代&#xff0c;外卖行业蓬勃发展&#xff0c;用户对于高效、智能的外卖服务需求不断增加。为了满足这一需求&#xff0c;采用微服务架构的外卖系统成为了开发的主流方向。本文将探讨基于微服务的外卖系统源码开发&#xff0c;涉及到关键技术和示例代码。 1. 微…

远程控制如何赋能智能制造?贝锐向日葵制造业场景案例解析

随着数字化转型在制造业的不断深入&#xff0c;企业在产线端也逐渐投入更多智能化设备&#xff0c;数字化、智能化设备其中一个比较显著的优势就是可以依托互联网实现远程运维和调试&#xff0c;大大提升产线设备的稳定性和工作效率&#xff1b;而远程调试运维一个重要的实现方…

ALTERNET STUDIO 9.1 Crack

ALTERNET STUDIO 9.1 发布 宣布 AlterNET Studio 9.1 版本今天上线。AlterNET Studio 9.0 是一个中期更新&#xff0c;重点是改进我们所有的组件库。 以下是 AlterNET Studio 9.1 的发布亮点&#xff1a; Roslyn C# 和 Visual Basic 解析器现在支持代码修复/代码重构。 代码修复…

el-date-picker时间控制范围为过去时间不可选

<el-date-picker :picker-options"startPickerOptions()" value-format"yyyy-MM-dd HH:mm:ss" v-model"form.applyFixPlan" type"datetime" placeholder"选择日期时间"> </el-date-picker> 在method中定义star…

【ESP32 IDF】ESP32移植u8g2库,实现oled界面显示

ESP32移植u8g2库&#xff0c;实现oled界面显示 1. 简单描述2. 环境准备1. 硬件准备2. 软件准备 3. IIC屏幕 【基于 ssd1362 256*64 】4. SPI屏幕 【基于 ssd1306 128*32】 1. 简单描述 开发方式为 IDF5.0参考连接为 iic基于esp-idf移植使用u8g2 spi基于esp-idf移植使用u8g2 …

插入排序——直接插入排序和希尔排序(C语言实现)

文章目录 前言直接插入排序基本思想特性总结代码实现 希尔排序算法思想特性总结代码实现 前言 本博客插入排序动图和希尔排序视频参考大佬java技术爱好者&#xff0c;如有侵权&#xff0c;请联系删除。 直接插入排序 基本思想 直接插入排序是一种简单的插入排序法&#xff…