一、扫盲扫盲
学习NUXT之前要了解SSR。
1.关于SSR 服务端渲染
Server Side Rendering(服务端渲染):
后端先调用数据库,获得数据之后,将数据和页面元素进行拼接,组合成完成的html页面,在直接返回给浏览器,供用户浏览.
目的是:
为了解决单页面应用的 SEO 的问题,对于一般网站影响不大,但是对于论坛类,内容类网站来说是致命的,搜索引擎无法抓取页面相关内容,也就是用户搜不到此网站的相关信息。
SSR 还适用以下场景:
1、客户端的网络比较慢
2、客户端运行在老的或者直接没有 JavaScript 引擎上
2.关于BSR 客户端渲染
客户端渲染:
数据由浏览器通过ajax动态取得,在通过js将数据填充到dom元素上最终展示到网页上.
动态的通过js生成页面进行渲染
二、NUXT
NUXT.JS:一个简便的vue框架,最常用的就是用来作SSR(服务器端渲染),就相当于vue服务器端渲染.
Nuxt.js 使用 Webpack 和 vue-loader 、 babel-loader 来处理代码的自动化构建工作(如打包、代码分层、压缩等等).
Nuxt.js:适合做新闻、博客、电影、咨询等需要搜索引擎提供流量的项目。
1.优点
1.基于 Vue.js
2. 自动代码分层
3.服务端渲染
4.强大的路由功能,支持异步数据
5.静态文件服务
6.ES6/ES7 语法支持
7.打包和压缩 JS 和 CSS
8.HTML头部标签管理
9.本地开发支持热加载
10.集成ESLint(js验证工具)
11.支持各种样式预处理器: SASS、LESS、 Stylus等
2.安装
//安装
yarn create nuxt-app <项目名>
现在在vs命令行运行的话,不会有一个完整的目录结构,俺是后来自己加上去的
nuxt安装官方文档
3.目录结构
目录结构分工如下:
目录文件名 | 作用 |
---|---|
.nuxt | Nuxt自动生成,临时的用于编辑的文件,build |
assets | 用于组织未编译的静态资源如 LESS、SASS 或 JavaScript |
components | 用于自己编写的 Vue.js 组件 |
layouts | 布局目录,用于组织应用的布局组件参考 |
middleware | 用于存放中间件参考 |
pages | 用于存放写的页面,Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配置。参考 |
plugins | 插件目录,用于存放Javascript 插件。参考 |
static | 静态文件目录,用于存放应用的静态文件 |
store | 用于组织应用的 Vuex 状态管理, store 目录下创建一个 index.js 文件可激活这些配置参考 |
.editorconfig | 开发工具格式配置 |
.eslintrc.js | ESLint的配置文件,用于检查代码格式 |
.gitignore | 配置git不上传的文件 |
.babelrc | 在Babel(js编译器)执行编译的过程中,会从项目的根目录下的 .babelrc文件中读取配置 |
nuxt.config.js | 用于组织 Nuxt.js 应用的个性化配置,已覆盖默认配置参考 |
package.json | 描述依赖关系和对外暴露的脚本接口 包管理配置文件 |
文件的路径建议都采用绝对路径,表格如下:
例:怎么在 /pages/user/me.vue 引入一个 static 文件夹里的图片
<img src="~static/img/logo.png" alt="Logo"/>
3.1 Nuxt.js 默认的配置(nuxt.config.js)
Nuxt.js 默认的配置涵盖了大部分使用情形,可通过 nuxt.config.js 来覆盖默认的配置。
head
借助 head 属性,Nuxt.js 让你可以在 nuxt.config.js 中配置应用的 meta 信息。
参考vue-meta配置
//类型:object
module.exports = {
head: {
titleTemplate: '%s - Nuxt.js',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'Meta description' }
]
}
}
CSS
该配置项用于定义应用的全局(所有页面均需引用的)样式文件、模块或第三方库。
css配置
build
Nuxt.js 允许你根据服务端需求,自定义 webpack 的构建配置。
build配置
modules
该配置项允许您将 Nuxt 模块添加到项目中。modules配置
buildModules:使用buildModules有助于加快生产启动速度,并显着减少node_modules生产部署的规模。
插件
- 先在plugins里头增加js文件,然后在nuxt.config.js里用vendor属性配置plugins
- yarn或者npm安装插件
4.路由
Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
要在页面之间使用路由,我们建议使用 标签。
nuxt.js路由和vue- router是一脉相承的,vue需要自己个手动配置,nuxt的话可以根据目录自动生成。
路由参考文档
基本思路:
pages目录:
Nuxt.js 自动生成的路由配置如下:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'admin',
path: '/admin/admin,
component: 'pages/admin/admin.vue'
},
{
name: ' success',
path: '/admin/success,
component: 'admin/success.vue'
}
]
}
在layout默认文件里头,可以用写基本的路由
动态路由
在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue
对应vue-router如下:
index、user、_slug同级
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}
扩展:二级展示区替换一级展示区
只需要在二级目录下加一个index.vue,并且将pages下的同名文件内容复制到二级index里,就能实现这个效果!
这样点击商品就是这样的展示效果啦
<template>
<div>
<h1>商品</h1>
<!-- 用nuxt-link传参数 -->
<nuxt-link to="/goods/1?a=1&b=2">商品01</nuxt-link>
<nuxt-link to="/goods/2?a=11&b=22">商品02</nuxt-link>
<nuxt-link :to="{name:'goods-id',params:{id:3},query:{a:1111,b:222}}">商品03</nuxt-link>
<nuxt-link :to="{name:'goods-id',params:{id:445},query:{a:1123,b:888}}">params是会在地址栏中显示id的 </nuxt-link>
<nuxt/>
</div>
</template>
展示区的展示小结
扩展 :设置默认的路由地址为pages/index
是因为nuxt不能跳转到localhost:300/index,俺昨天整了半天没解决,今天好了
首先在布局layout里头设置首页路径为/index
然后在nuxt.conf.js里头配置
router:{
middleware:'auth',
// 扩展路由 其实可以重定向吧?
// 设置默认的路由地址为pages/index.vue而不是./
extendRoutes(routes,resolve){
console.log(routes);
routes.push({
name: 'home',
path: '/index',
component: resolve(__dirname,'pages/index.vue')
})
}
},
tips:
1.路由路径带有:id?参数,表示该路径是可选的,设置为必选必须要在这个目录下加一个index.vue索引文件。
2.路由参数校验:调用validate方法
NUXT.js可以在动态路由组件中定义路由参数校验方法,(相当于在组件js中直接写)
路由校验
async validate({ params, query, store }) {
// await operations
return true // 如果参数有效
return false // 将停止Nuxt.js呈现页面并显示错误页面
}
export default {
//如果校验方法返回的值不为 true, Nuxt.js 将自动加载显示 404 错误页面。
validate({ params }) {
// Must be a number
return /^\d+$/.test(params.id)
}
}
约定式路由
1.nuxt页面跳转
在layout中使用nuxt-link可以进行页面跳转
和vue里头的index.vue有些相似
展示区
<template>
<div>
<!-- 页面跳转 -->
<nuxt-link to="/">首页</nuxt-link>
<nuxt-link to="/goods">商品</nuxt-link>
<nuxt-link to="/login">登录</nuxt-link>
<nuxt-link to="/registe">注册</nuxt-link>
<nuxt/>
</div>
</template>
效果如图:
2.nuxt声明式跳转:
实现效果如下:将goods.vue里头的参数传到goods/_id.vue详情页
声明式跳转:商品03
name:(路由名) 目录名-其他目录名-文件名
params:(key) 要对等文件名
<template>
<div>
<h1>商品</h1>
<!-- 用nuxt-link传参数 -->
<nuxt-link to="/goods/1?a=1&b=2">商品01</nuxt-link>
<nuxt-link to="/goods/2?a=11&b=22">商品02</nuxt-link>
<nuxt-link :to="{name:'goods-id',params:{id:3},query:{a:1111,b:222}}">商品03</nuxt-link>
<nuxt-link :to="{name:'goods-id',params:{id:445},query:{a:1123,b:888}}">params是会在地址栏中显示id的 </nuxt-link>
<nuxt/>
</div>
</template>
效果:在地址栏中显示传递的id和其它参数的值
二、在方法中传递
跳转
getDescribe(id) {
// 直接调用$router.push 实现携带参数的跳转
this.$router.push({
path: `/describe/${id}`,
})
接收
$route.params.id
注意:页面之间的跳转使用query 不然的话刷新页面后会找不到参数
跳转
this.$router.push({
path: '/describe',
query: {
id: id
}
})
接收
$route.query.id
嵌套路由
创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
别忘了在父组件(.vue文件) 内增加 用于显示子视图内容。
pages/
--| user/
-----| index.vue(嵌套首页)
-----| user-list.vue(嵌套个人详情页面)
--| user.vue(在这里添加<nuxt-link>页面跳转,将<nuxt />摆在下头)
--| index.vue
路由守卫
5.异步数据 asyncData
asyncData 方法,使得你能够在渲染组件之前异步获取数据。
- asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。
- 你可以利用 asyncData方法来获取数据并返回给当前组件。
数据交互和跨域读取数据
首先要导入axios
yarn add @nuxtjs/axios
在nuxt.config.js里头加入模块
modules: [
'@nuxtjs/axios'
],
方法
1. 返回一个promise
(和vue的异步组件的概念都些相似) ,nuxt.js 会等待该Promise被解析之后才会设置组件的数据,从而渲染组件.
export default {
asyncData({ params }) {
return axios.get(`https://my-api/posts/${params.id}`).then(res => {
return { title: res.data.title }
})
}
}
2. 使用 async 或 await
export default {
async asyncData({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
跨域读取数据:
- 写一个list.json
{
"user1" : {
"name" : "mahesh",
"password" : "password1",
"profession" : "teacher",
"id": 1
},
"user2" : {
"name" : "suresh",
"password" : "password2",
"profession" : "librarian",
"id": 2
},
"user3" : {
"name" : "ramesh",
"password" : "password3",
"profession" : "clerk",
"id": 3
}
}
- 用node.js写一个RESTful API
var express = require('express');
var app = express();
var fs = require("fs");
var path = require('path'); //系统路径模块
//创建get接口
app.get('/list', function (req, res) {
fs.readFile( './list.json','utf8', function (err, data) {
console.log( data );
res.end( data );
});
})
var server = app.listen(3001, function () {
var port = server.address().port
console.log("应用实例,访问地址为 http://localhost:%s", port)
})
浏览器显示如图:
终端显示:
然后在nuxt-config-js,
//跨域
axios: {
proxy: true
},
proxy: {
"/api": "http://localhost:3001"//代理转发的地址
},
在index里头
export default {
async asyncData({$axios}){
let res1 = await $axios({URL:'http://localhost:3001/list'});
//读取接口里头的数据
console.log(res1.data.user1);
}
}
6.Vuex状态🌲
Nuxt.js 会尝试找到 src 目录(默认是应用根目录)下的 store 目录,如果该目录存在,它将做以下的事情:
- 引用 vuex 模块
- 设置 Vue 根实例的 store 配置项
Nuxt.js 支持两种使用 store 的方式,你可以择一使用:
普通方式:
store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index 是根模块)
在store下写一个index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = () => new Vuex.Store({
state: {
counter: 1
},
mutations: {
increment(state) {
state.counter++
}
}
})
export default store;
在pages下创一个counter.vue
<template>
<div>
<p>{{$store.state.counter}}</p>
<button @click="$store.commit('increment')"> </button>
</div>
</template>
模块方式:
export const state = () => ({
counter: 0
})
export const mutations = {
increment(state) {
state.counter++
}
}