当前位置: 首页 > news >正文

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

在这里插入图片描述

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-axiosaxios: {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//发送ajaxlet { data } = await context.$axios.get('路径','参数')// 返回结果return {变量: 查询结果从data获取 }},
}
  • 实例

    <template><div>{{echo}}</div>
    </template><script>
    export default {async asyncData(context) {// 发送ajaxlet {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) {// 发送ajaxlet [{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} ) {// 发送ajaxlet { 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) 保存内置的axiosaxios = $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){// 可以发送ajaxcontext.commit('setUser',value)}}// 获取数据
const getters = {getUser (state) {return state.user}
}
export default {namespace: true,	// 命名空间,强制要求,在使用时,加上所属的模块名,例如:book/addmoneystate,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

相关文章:

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

1. Nuxt.js 概述 1.1 我们一起做过的SPA SPA&#xff08;single page web application&#xff09;单页 Web 应用&#xff0c;Web 不再是一张张页面&#xff0c;而是一个整体的应用&#xff0c;一个由路由系统、数据系统、页面&#xff08;组件&#xff09;系统等等&#xff0…...

导入JDBC元数据到Apache Atlas

前言 前期实现了导入MySQL元数据到Apache Atlas, 由于是初步版本&#xff0c;且功能参照Atlas Hive Hook&#xff0c;实现的不够完美 本期对功能进行改进&#xff0c;实现了导入多种关系型数据库元数据到Apache Atlas 数据库schema与catalog 按照SQL标准的解释&#xff0c;…...

大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现

大数据项目——基于Django/协同过滤算法的房源可视化分析推荐系统的设计与实现 技术栈&#xff1a;大数据爬虫/机器学习学习算法/数据分析与挖掘/大数据可视化/Django框架/Mysql数据库 本项目基于 Django框架开发的房屋可视化分析推荐系统。这个系统结合了大数据爬虫、机器学…...

[网鼎杯 2020 朱雀组]phpweb1

提示 call_user_func()函数先通过php内置函数来进行代码审计绕过system&#xff08;##不止一种方法&#xff09; 拿到题目养成一个好的习惯先抓个包 从抓到的包以及它首页的报错来看&#xff0c;这里死活会post传输两个参数func以及p func传输函数&#xff0c;而p则是传输参数的…...

深度学习之注意力机制

注意力机制与外部记忆 注意力机制与记忆增强网络是相辅相成的&#xff0c;神经网络去从内存中或者外部记忆中选出与当前输入相关的内容时需要注意力机制&#xff0c;而在注意力机制的很多应用场景中&#xff0c;我们的外部信息也可以看作是一个外部的记忆 这是一个阅读理解任务…...

WordPress:解决xmlrpc.php被扫描爆破的风险

使用WordPress的朋友都知道&#xff0c;一些【垃圾渣渣】会利用xmlrpc.php文件来进行攻击&#xff0c;绕过WP后台错误登录次数限制进行爆破。虽然密码复杂的极难爆破&#xff0c;但及其占用服务器资源。 方法一、利用宝塔防火墙&#xff08;收费版&#xff09; 一般可以直接使…...

Fiddler抓包模拟器(雷电模拟器)

Fiddler设置 List item 打开fiddler,的options 点击OK,重启fiddler 模拟器 更改网络设置 IP可以在电脑上终端上查看 然后在模拟器浏览器中输入IP:端口 安装证书...

RepidJson将内容写入文件

使用 RapidJSON 将内容写入文件的步骤如下&#xff1a; 创建一个 rapidjson::Document 对象&#xff0c;将需要写入文件的内容存储到其中。创建一个 rapidjson::StringBuffer 对象来保存 JSON 字符串。将 rapidjson::Document 对象转换为 JSON 字符串&#xff0c;并将其放入 r…...

Endnote使用教程

原由 最近要进行开题报告&#xff0c;要求不低于60文献的阅读与引用&#xff0c;单独插入引入我觉得是非常繁琐的事情&#xff0c;所以就借助Endnote这个工具&#xff0c;减少我们的工作量。 使用方法 第一步&#xff1a;先新建一个数据库&#xff0c;这样子可以在这个数据库…...

java中用Thead创建线程和用Runnable创建线程的区别是什么?

在 Java 中&#xff0c;创建线程的两种主要方式是通过继承 Thread 类和通过实现 Runnable 接口。下面是它们之间的主要区别&#xff1a; 1. 继承 Thread 类&#xff1a; class MyThread extends Thread {public void run() {// 线程执行的代码} }// 创建并启动线程 MyThread …...

0013Java程序设计-基于Vue的上课签到系统的设计与实现

文章目录 **摘 要**目录系统设计4.2学生签到4.3 签到信息列表4.4 用户信息管理5.1系统登录5.1.1 登录5.1.2 清除用户登记记录5.1.3 登录拦截 5.2用户管理5.2.2 用户添加5.2.3 用户编辑5.2.4 用户删除5.2.5 用户分页 5.3签到信息5.3.1签到信息列表 5.4学生签到5.4.1学生签到 开发…...

2.修改列名与列的数据类型

修改字段名与字段数据类型 1.修改字段名 有时&#xff0c;在我们建好一张表后会突然发现&#xff0c;哎呀&#xff01;字段名貌似写错了&#xff01;怎么办&#xff1f;要删了表再重新建一个新表吗&#xff1f;还是要删了这个字段再新建一个新的字段&#xff1f; 都不用&…...

[Firefly-Linux] RK3568 Ubuntu固件分区详解

RK为了方便开发与产品定制&#xff0c;自己定义了一套固件的分区&#xff0c;这些分区信息存放在parameter.txt文件中&#xff0c;Firefly参考这个文件定义了自己的Ubuntu分区&#xff0c;文件为parameter-ubuntu.txt&#xff0c;存放于Linux_SDK的device/rockchip/rk356x目录下…...

SpringBoot项目访问resources下的静态资源

1.新建一个配置文件夹&#xff0c;放配置类 2.编辑 WebMvcConfig.java package com.southwind.configuration;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import or…...

Qt之面试经验

1.恒生芸擎网络 技术没怎么问&#xff0c;一面问对方工作日常会涉及的一些东西&#xff08;自动发布&#xff09;&#xff0c;二面公司流程&#xff0c;三面其他&#xff08;没发offer&#xff09; 2.光珀智能科技 涉及AI算法落地&#xff0c;问了点基础问题&#xff0c;比如…...

数据库基础概念与范式反范式总结

文章目录 一、基本概念1、属性2、元组3、关系4、超键5、候选键6、主键7、主属性8、外键9、函数依赖完全依赖 二、数据库范式1、第一范式&#xff08;1NF&#xff09;2、第二范式&#xff08;2NF&#xff09;3、第三范式&#xff08;3NF&#xff09;4、巴斯-科德范式&#xff08…...

tanstack/react-query使用手册

1. useQuery useQuery的使用一、data是后端成功返回的数据&#xff0c; 第一次的值为undefined 二、isLoading是指数据是否正在加载的状态&#xff0c;通常用于判断请求是否还在进行中。当isLoading为true时&#xff0c;表示数据正在加载中&#xff0c;当isLoading为false时&a…...

camera2对摄像头编码h264

MediaCodec编码摄像头数据 前置&#xff1a;保存的一些成员变量 // 摄像头开启的 handler private Handler cameraHandler; // Camera session 会话 handler private Handler sessionHandler; //这里是个Context都行 private AppCompatActivity mActivity; // 这个摄像头所有需…...

Apache solr XXE 漏洞(CVE-2017-12629)

任务一&#xff1a; 复现环境中的漏洞 任务二&#xff1a; 利用XXE漏洞发送HTTP请求&#xff0c;在VPS服务器端接受请求&#xff0c;或收到DNS记录 任务三&#xff1a; 利用XXE漏洞读取本地的/etc/passwd文件 1.搭建环境 2.开始看wp的时候没有看懂为什么是core&#xff0c;然…...

​HTML代码混淆技术:原理、应用和实现方法详解

HTML代码混淆是一种常用的反爬虫技术&#xff0c;它可以有效地防止爬虫对网站数据的抓取。本文将详细介绍HTML代码混淆技术的原理、应用以及实现方法&#xff0c;帮助大家更好地了解和运用这一技术。 一、HTML代码混淆的原理 HTML代码混淆是指将HTML源码通过特定的算法进行加…...

quickapp_快应用_系统接口应用

系统接口 在项目中使用到的接口都需要在配置文件manifest.json中声明&#xff0c;不然会报如下警告 [WARN] 请在 manifest.json 文件里声明项目代码中用到的接口: system.storage, service.account, system.package, system.webview[1]检查某app是否在手机上安装 官方文档&a…...

sqlmap400报错问题解决

python sqlmap.py -r sql.txt --batch --techniqueB --tamperspace2comment --risk 3 --force-ssl–batch 选项全部默认 不用再手动输入 –techniqueB 使用布尔盲注&#xff0c;该参数是指出要求使用的注入方式 –tamperspace2comment使用特殊脚本&#xff0c;space2comment是把…...

【S32DS报错】-2-提示Error while launching command:arm-none-eabi-gdb –version错误

目录 1 Error错误提示 2 Error错误原因 3 如何消除Error错误 结尾 【S32K3_MCAL从入门到精通】合集&#xff1a; S32K3_MCAL从入门到精通https://blog.csdn.net/qfmzhu/category_12519033.html 1 Error错误提示 使用S32DSJ-LinK下载程序&#xff0c;在Dedug Configurati…...

Windows核心编程 HOOK

目录 HOOK概述 HOOK API SetWindowsHookExA 函数(winuser.h) UnhookWindowsHookEx 函数(winuser.h) NextHookEx 函数(winuser.h) 局部钩子 全局钩子 为什么全局钩子需要用dll作为过程函数&#xff1f; HOOK概述 本质&#xff1a;Windows消系统的消息过滤器。 全局钩子…...

P4 Qt如何添加qss样式表文件和添加图片资源

目录 前言 01 添加图片资源文件 02 添加qss文件 前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Qt基础_ChenPi的博客-CSDN博客》✨✨✨ &#x1f33a;本篇简介 &#xff1a;这一章…...

【华为OD题库-085】路灯照明II-Java

题目 在一条笔直的公路上安装了N个路灯&#xff0c;从位置0开始安装&#xff0c;路灯之间间距固定为100米。 每个路灯都有自己的照明半径&#xff0c;请计算第一个路灯和最后一个路灯之间&#xff0c;无法照明的区间的长度和。输入描述 第一行为一个数N&#xff0c;表示路灯个数…...

附录1、vuepress中的Markdown语法

# 一、标题 # 说明&#xff1a; #后面跟的内容就是标题&#xff0c;一个#就是一级标题&#xff0c;有几个#就是几级标题&#xff0c;例如2级标题就有两个##&#xff0c;markdown的2级和3级标题会默认自动作为子目录&#xff0c; 注意&#xff1a;#后面必须有个空格&#xff0…...

【matlab程序】matlab画螺旋图|旋转图

%% 数学之美====》螺旋线 % 海洋与大气科学 % 20231205 clear;clc;close all; n=10; t=0:0.01:2pin; R=1; xx=nan(length(t),1);yy=nan(length(t),1); for i=1:length(t) xx(i)=Rcos(t(i)); yy(i)=Rsin(t(i)); R=R+1; end figure set(gcf,‘position’,[50 50 1200 1200],‘col…...

计算三位数每位上数字的和

分数 10 作者 python课程组 单位 福州大学至诚学院 补充程序实现计算&#xff1a; 输入一个三位的整数&#xff08;不接受实数&#xff09;&#xff0c;求这个三位数每一位上数字的和是多少&#xff1f;例如&#xff1a;输入&#xff1a;382&#xff0c;输出&#xff1a;和为…...

Gavin Wood:财库保守主义偏离了初心,应探索 Fellowship 等更有效的资金部署机制

波卡创始人 Gavin Wood 博士最近接受了 The Kusamarian 的采访&#xff0c;分享了他的过往经历、对治理的看法&#xff0c;还聊到了 AI、以太坊、女巫攻击、财库等话题。本文整理自 PolkaWorld 对专访编译的部分内容&#xff0c;主要包含了 Gavin 对治理、财库提案、生态资金分…...