nuxt.js笔记

6 篇文章 0 订阅

介绍

  • 基于 Vue.js 的通用应用框架。
  • SSR 服务端渲染。在服务端生成html发送至客户端
  • 特性:异步数据加载、中间件支持、布局支持等。
  • 优点:有利于SEO,加载速度快,自动配置路由
  • 依赖 node 和 npm npx(npx在NPM版本5.2.0默认安装)

实现原理

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200704171605100.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg0ODU3Ng==,size_16,color_FFFFFF,t_70

初始化项目

  • $ npx create-nuxt-app <项目名> (Nuxt.js团队创建了脚手架工具 create-nuxt-app)
  • $ npm run dev (http://localhost:3000)
  • $ npm run build 打包

配置ip地址端口号

若端口号冲突,或想运行在本机ip,在package.json中添加config配置

{
	"config":{
		"nuxt":{
			"host":"127.0.0.1",
			"port":"1818"	
		}
	}
}

重启项目即可

配置代理

//找到modules模块,把proxy添加到里面
 modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],

 axios: {
    proxy: true // Can be also an object with default options
  },
  proxy: {
      '/api': {
      changeOrigin: true,
      target: 'http://127.0.0.1:8082', // 允许跨域的服务器地址
      pathRewrite: {
        '^/api': ''
      }
     }
 }

路由

  • 根据目录结构自动生成router.js,无需自己配置
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
// 以上页面结构自动生成如下路由结构
router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
    {
      name: 'user-one',
      path: '/user/one',
      component: 'pages/user/one.vue'
    }
  ]
}

动态路由

  • 动态路由是不同的商品详情对应不同的路由地址,便于搜索引擎收录更多,被搜到的几率更大
  • 文件需以 _ 开头
//目录结构:goods文件夹下面动态路由_id文件
--| goods/
-----| _id.vue
-----| index.vue

//index.vue传参
<nuxt-link :to="{name: 'goods-id', params:{id: 1}}">苹果详情</nuxt-link>
<nuxt-link :to=" '/goods/2' ">橘子详情</nuxt-link>

//_id.vue接受参数,并校验参数,若参数不合格,将会跳转到404页面
<script>
	export default {
		validate({params}){  //params相当于url中的pathname , 而query是路由携带的参数?type=1
			return \^\d+$\.test(params.id)
		}
	}
</script>

嵌套路由

//路由结构:如下users.vue是父路由,其子路由需要放在与他同名的文件夹下users/

pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue

父组件(.vue文件) 内增加 用于显示子视图内容

路由跳转传参

<nuxt-link to="/">跳转首页</nuxt-link>
<nuxt-link :to="{name: 'news',query:{id:'1'}}">跳转新闻页</nuxt-link>
  • params 传值(id会显示地址栏,其他参数不会显示在地址栏)
this.$router.push({ 
	name: 'log-id',
	params:{
		id:12,
		key:value
	}) 
//接受
async asyncData ({ params }) { 
	//  params.id 就是我们传进来的值
}
// 或者 
created () { 
	this.$route.params.xxx
}
  • query传值(所有的参数都会显示在地址栏)
this.$router.push({ 
	name: 'log-id',
	query:{
		id:12,
		key:value
	}) 
//接收
async asyncData ({app,query }) { 
	//  pquery.id 就是我们传进来的值
}
// 或者 
created () { 
	this.$route.query.xxx
}

路由切换添加过渡动画——全局样式配置

  • 在assets文件下新建全局样式文件
  • 在 nuxt.config.js 中配置全局common.css
  • 若引入less文件,需要安装插件 npm i less-loader less ,安装失败还没解决
module.exports = {
  css: [ '@assets/common.css' ]
}
//common.css
.page-enter-active, .page-leave-active {
  transition: opacity .5s;
}
.page-enter, .page-leave-active {
  opacity: 0;
}

单个页面动画

  • 在全局样式里定义单独的过渡样式,然后在所需组件内transition 属性的值设置为 news
//common.css
.news-enter-active, .news-leave-active {
  transition: all .5s;
  color:red;
}
.news-enter, .news-leave-active {
  opacity: 0;
  color:blue;
}
//news.vue
export default {
  transition: 'news'
}

组件的使用

  • 组件定义在components文件夹中,名字格式 :每个单词首字母大写 UserList
  • 组件无需任何引入,直接在页面里使用 <UserList></USerList>

图片的使用 ~assets

<img src="~assets/img/logo-2.png" style="height: 66px" alt="" />

默认模板和默认布局(优选)

默认模板

  • 在根目录下新建一个app.html 文件
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }} //nuxt.config.js中配置的head
  </head>
  <body {{ BODY_ATTRS }}>
  	//可以在这写一段固定的代码,这样机会在每个页面都显示,例如:
  	<h1>欢迎光临</h1>
    {{ APP }} //pages中的页面
  </body>
</html>

默认布局

  • 可通过添加根目录下 layouts/default.vue 文件来扩展应用的默认布局
<template>
  //在默认布局中可以定义pc网站的头部和底部,这样就会在每个页面中显示
  <nuxt/>
</template>

自定义布局

  • 在根目录的layouts文件夹下可以定义特殊的布局,例如某个页面需要特殊的头部
// layouts/blog.vue
<template>
  <div>
    <div>头部</div>
    <nuxt/> // 代表每个页面的占位
  </div>
</template>
  • 在所需要的页面中引入自定义的布局
<template>
<!-- Your template -->
</template>
<script>
export default {
  layout: 'blog'
  // page component definitions
}
</script>

自定义错误页面

  • 在layouts文件夹爱下创建 error.vue 文件 layouts/error.vue ,当404 或 500 的时候跳转
<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">页面不存在</h1>
    <h1 v-else>应用发生错误异常</h1>
    <nuxt-link to="/">首 页</nuxt-link>
  </div>
</template>

<script>
export default {
  props: ['error'], //nuxt自己传递的error对象(包含statusCode)
  layout: 'blog' // 你可以为错误页面指定自定义的布局
}
</script>

基本页面举例

  1. asyncData
- [ ] 在==渲染组件之前==异步获取数据,即在服务端获取数据并生成页面
- [ ] 如果在mounted中掉接口,则是在组件渲染之后获取到数据,然后通过js渲染在客户端
- [ ] 返回一个数据对象给当前组件,可以直接使用,无需再data中定义
- [ ] 由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象

同步调用 async/await
- axios返回的是promise对象,是异步调用
- async/await是同步调用,在数据返回成功之后,才会执行后边的操作

  1. validate :在动态路由组件中定义参数校验方法

    • 如果校验方法返回的值不为 true或Promise中 resolve 解析为false或抛出 Error , Nuxt.js 将自动加载显示 404 错误页面或 500 错误页面。
  2. asyncData 最重要的一个键, 支持 异步数据处理,另外该方法的第一个参数为当前页面组件的 上下文对象。

  3. fetch 与 asyncData 方法类似,用于在渲染页面之前获取数据填充应用的状态树(store)。不同的是 fetch
    方法不会设置组件的数据。详情请参考 关于 fetch 方法的文档。

  4. head 配置当前页面的 Meta 标签, 详情参考 页面头部配置
    API。

  5. layout 指定当前页面使用的布局(layouts 根目录下的布局文件)。详情请参考 关于 布局 的文档。

  6. loading 如果设置为false,则阻止页面自动调用this. n u x t . nuxt. nuxt.loading.finish()和this. n u x t . nuxt. nuxt.loading.start(),您可以手动控制它,请看例子,仅适用于在
    nuxt.config.js 中设置loading的情况下。请参考API 配置 loading 文档。

  7. transition 指定页面切换的过渡动效, 详情请参考 页面过渡动效。

  8. scrollToTop 布尔值,默认: false。用于判定渲染页面前是否需要将当前页面滚动至顶部。这个配置用于 嵌套路由的应用场景。

  9. validate 校验方法用于校验 动态路由的参数。

  10. middleware 指定页面的中间件,中间件会在页面渲染之前被调用, 请参考 路由中间件。

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

<script>
export default {
  data(){
  	return {
  		title:this.$route.params.title
  	}
  },
  props:['name'],
  // 在动态路由组件中定义参数校验方法
  // 举个例子:pages/users/_id.vue
  validate({ params }) {
    // 必须是number类型
    return /^\d+$/.test(params.id)
  }
  // 每次组件加载之前调用,可以在这里调接口,设置组件的数据
  async asyncData ({$axios}) {
    const { data } = await $axios.get('')
    //initdata可以像data中数据一样直接使用,无需再data中定义
    return { initdata:data } 
  },
  // 在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。
  async fetch ({ store, params }) {
    let { data } = await axios.get('http://my-api/stars')
    store.commit('setStars', data)
  },
  head () {
    // 每个页面单独设置meta,title和content
    title:this.title,
    meta:{
		content:'描述',
		name:'',
		hid:'' //唯一标识,跟原来的一样可以覆盖原来的meta
	}
  },
  // and more functionality to discover
  ...
}
</script>

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

密码加解密公共方法的使用

  • plugins/utils
import Vue from 'vue'
import JSEncrypt from './jsencrypt.min.js'

// 密钥对生成 http://web.chacuo.net/netrsakeypair

const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='

const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
  'UP8iWi1Qw0Y='
let utils = {
    install(Vue) {
        Vue.prototype.$encrypt = function(txt){
            const encryptor = new JSEncrypt()
            encryptor.setPublicKey(publicKey) // 设置公钥
            return encryptor.encrypt(txt) // 对数据进行加密
        };
        Vue.prototype.$decrypt = function(txt){
            const encryptor = new JSEncrypt()
            encryptor.setPrivateKey(privateKey) // 设置私钥
            return encryptor.decrypt(txt) // 对数据进行解密
        };
    }
}
Vue.use(utils);
  • nuxt.config.js
 plugins: [
    '@/plugins/element-ui',
    { src: '@/plugins/utils', ssr: false },// axios.js文件关闭服务端渲染
    { src: '@/plugins/axios', ssr: false } // axios.js文件关闭服务端渲染
  ],
  • 使用
this.$decrypt(pwd)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小曲曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值