记录一下初学nuxt.js的知识点📕
介绍
官网:https://zh.nuxtjs.org/guide
特性:
基于 Vue.js
自动代码分层
服务端渲染
强大的路由功能,支持异步数据
静态文件服务
ES6/ES7 语法支持
打包和压缩 JS 和 CSS
HTML头部标签管理
本地开发支持热加载
集成ESLint
支持各种样式预处理器: SASS、LESS、 Stylus等等
安装 1 vue init nuxt-community/starter-template <project-name>
ps: 如果没有安装 vue-cli
,需先通过 npm i -g vue-cli
来安装
安装依赖包
1 2 cd <project-name> npm install
启动项目
应用运行在:http://localhost:3000
,后面讲如何修改默认端口。
目录结构说明 1 2 3 4 5 6 7 8 9 10 ├── assets //用于组织未编译的静态资源如 LESS、SASS 或 JavaScript。 ├── components //用于组织应用的 Vue.js 组件。 ├── layputs //用于组织应用的布局组件。 ├── middleware //用于存放应用的中间件。 ├── pages //用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配置。 ├── plugins //用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。 ├── static //用于存放应用的静态文件。 ├── store //用于组织应用的 Vuex 状态树 文件。 ├── nuxt.config.js //用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。 └── package.json //用于描述应用的依赖关系和对外暴露的脚本接口。
路由
Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
假设 pages 的目录结构如下:
1 2 3 4 5 pages/ --| user/ -----| index.vue -----| one.vue --| index.vue
那么,Nuxt.js 自动生成的路由配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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' } ] }
视图
模板
你可以定制化 Nuxt.js 默认的应用模板。
定制化默认的 html 模板,只需要在应用根目录下创建一个 app.html 的文件。
默认模板为:
1 2 3 4 5 6 7 8 9 <!DOCTYPE html> <html {{ HTML_ATTRS }}> <head> {{ HEAD }} </head> <body {{ BODY_ATTRS }}> {{ APP }} </body> </html>
布局
1 2 3 <template> <nuxt/> </template>
layouts 根目录下的所有文件都属于个性化布局文件,可以在页面组件中利用 layout 属性来引用。
请确保在布局文件里面增加 <nuxt/>
组件用于显示页面非布局内容。
for example: layouts/default.vue
1 2 3 4 5 6 <template> <div> <div>这里是导航内容</div> <nuxt/> </div> </template>
在 pages/index.vue 里,可以指定页面组件使用该布局
1 2 3 4 5 <script> export default { layout: 'blog' } </script>
页面
页面组件实际上是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项(对应 Nuxt.js 提供的功能特性)以便你能快速开发通用应用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <template> <h1 class="red">Hello {{ name }}!</h1> </template> <script> export default { asyncData (context) { // called every time before loading the component return { name: 'World' } }, fetch () { // The fetch method is used to fill the store before rendering the page }, head () { // Set Meta Tags for this Page }, // and more functionality to discover ... } </script> <style> .red { color: red; } </style>
插件
使用 element UI
首先增加文件 plugins/element-ui.js
1 2 3 4 import Vue from 'vue' import Element from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(Element, { size: 'small' })
在 nuxt.config.js 中配置
1 2 3 plugins: [ '~plugins/element-ui' ]
只在浏览器里使用的插件
nuxt.config.js1 2 3 4 5 module.exports = { plugins: [ { src: '~plugins/element-ui', ssr: false } ] }
异步数据
asyncData
在渲染组件之前异步获取数据。
asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData方法来获取数据并返回给当前组件。
1 2 3 4 5 6 7 8 export default { async asyncData (context) { let data = await axios.get('http://www.xxx); return { title: data.title } } }
fetch
用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。
如果页面组件设置了 fetch 方法,它会在组件每次加载前被调用(在服务端或切换至目标路由之前)。
fetch 方法的第一个参数是页面组件的上下文对象 context,我们可以用 fetch 方法来获取数据填充应用的状态树。为了让获取过程可以异步,你需要返回一个 Promise,Nuxt.js 会等这个 promise 完成后再渲染组件。
1 2 3 4 5 6 export default { async fetch({store, params}) { let data = await axios.get('http://www.xxx') store.commit('setValues', data); } }
配置项 nuxt.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 module.exports = { head: { title: 'douban', meta: [ { charset: 'utf-8' },{ name: 'viewport', content: 'width=device-width,initial-scale=1' },{ hid: 'description', name: 'description', content: 'Meta description' } ], //ali iconfont link: [ { 'rel': 'stylesheet', 'href': '//at.alicdn.com/t/font_562725_orktergz2etawcdi.css' } ] }, css: [ { src: '~assets/css/reset.scss', lang: 'scss' },{ src: '~assets/css/style.scss', lang: 'scss' } ], loading: { color: '#00b600', height: '2px', failedColor: 'red' }, plugins: [ '~plugins/filters', '~plugins/element-ui' ], build: { vendor: ['axios'] }, router: { linkActiveClass: 'active-link', } }
常见问题
修改端口号
package.json
1 2 3 4 5 6 7 8 9 "config": { "nuxt": { "host": "0.0.0.0", "port": "4000" } }, "scripts": { "dev": "nuxt" }
使用外部资源
在 nuxt.config.js 中配置你想引用的资源文件:
1 2 3 4 5 6 7 8 9 10 module.exports = { head: { link: [ { 'rel': 'stylesheet', 'href': '//at.alicdn.com/t/font_562725_orktergz2etawcdi.css' } ] } }
局部配置 可在 pages 目录内的 .vue 文件中引用外部资源,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 <template> <h1>使用 jQuery 和 Roboto 字体的关于页</h1> </template> <script> export default { head: { script: [ { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' } ] } } </script>
meta 标签重复
为了避免子组件中的meta标签不能正确覆盖父组件中相同的标签而产生重复的现象,建议利用 hid 键为meta标签配一个唯一的标识编号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 head: { title: 'starter', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: 'This is the generic description.' } ], }