Nuxt.js 是一个基于 Vue.js(2.0) 的服务端渲染应用框架,它可以帮我们轻松的实现同构应用。
1 2 3 4 npm i create-nuxt-app -g create-nuxt-app my-nuxt-democd my-nuxt-demo npm run dev
1 2 3 4 5 6 7 8 9 10 11 12 13 14 create-nuxt-app v4.0 .0 ✨ Generating Nuxt.js project in my-nuxt-demo ? Project name: my-nuxt-demo ? Programming language: JavaScript ? Package manager: Npm ? UI framework: None ? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection) ? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection) ? Testing framework: None ? Rendering mode: Universal (SSR / SSG) ? Deployment target: Server (Node.js hosting) ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection) ? What is your GitHub username? sacgog ? Version control system: None
nuxt的项目结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 └─my-nuxt-demo ├─.nuxt ├─assets ├─components ├─layouts ├─middleware ├─node_modules ├─pages ├─plugins ├─static └─store ├─.editorconfig ├─.eslintrc.js ├─.gitignore ├─nuxt.config.js ├─package -lock.json ├─package .json ├─README.md
路由 nuxt根据pages文件夹创建路由
例如:
/test/index.vue
创建 https://www.acgog.com/test
/test/a.vue
创建 https://www.acgog.com/test/a
/test/_id.vue
创建 https://www.acgog.com/test/{id}
PS:参数页面文件名必须按格式 _参数名
路由跳转 1 2 3 4 5 <nuxt-link :to ="{name:'article-id',params:{id:item.id}}" > {{item.title}} <span > 发布日期:{{item.time}} </span > </nuxt-link >
js带参数跳转
1 2 3 4 this .$router .push ({ name : 'list-id' , params :{id :1 }, })
接收页面方法
使用element ui 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cnpm i element-ui -S-dimport Vue from 'vue' import ElementUI from 'element-ui' Vue.use(ElementUI) css: [ 'element-ui/lib/theme-chalk/index.css' ], plugins: [ {src: '~/plugins/ElementUI' , ssr: true } ], build: { vendor: ['element-ui' ] }
axios 注意这里的写法,是@nuxtjs/axios
而不是直接axios
,否则你下面配置的时候会提示找不到axios
1 cnpm install @nuxtjs/axios
unxtjs
的ajax
,你先别往你那个异步上去思考,其实这里面所有的ajax
最后都会形成页面。你别想着,我一点按钮,调用一个方法,然后再ajax
去加载数据。因为我们最后全部都会生成静态,所以任何的获取数据的操作,最后都会变成页面的跳转。
所以,官方给了一套写法,你必须按照这个去写, 并且这里的ajax
会再页面渲染之前就执行。这个东西跟生命周期这些都是平级的。
1 2 3 4 5 6 7 8 9 10 11 asyncData (context ) { return context.$axios .get ('index/query' ) .then (res => { console .log (res.data .result [0 ].logo ); return {txt :res.data .result [0 ].logo }; }) },
然后打开nuxt.config.js
开始修改,先把代理这块写好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 modules : [ '@nuxtjs/axios' ],axios : { proxy : true , prefix : '/api' , credentials : true },proxy : { '/api' : { target : 'http://localhost:3002/' , pathRewrite : { '^/api' : '/' , changeOrigin : true }, } },
然后下面,加上axios,防止二次打包
1 2 3 4 5 6 7 8 9 build : { vendor : ['element-ui' ,'axios' ], postcss : { preset : { features : { customProperties : false } } },
如何同时发起多个请求
1 2 3 4 5 6 7 8 9 async asyncData ({$axios} ){ let index = await $axios.get ("index/query" ); let list = await $axios.get ("index/query/list" ); return { index : index.data .result [0 ], list : list.data .result } },
如果通过接收route
的参数,发送带参数的请求
1 2 3 4 5 6 7 8 async asyncData ({params,$axios}) { let data = await $axios.get (`article/query?id=${params.id} ` ); return { data : data.data .result [0 ] } }
vuex nuxt
加载vuex
非常简单。甚至都无需我们去修改任何的配置文件,因为nuxt中已经自带了vuex
:我们只需要再store
文件夹中新建一个index.js
输入下面的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import Vue from 'vue' import Vuex from 'vuex' Vue .use (Vuex )const store = ( ) => new Vuex .Store ({ state : { counter : 0 }, mutations : { increment (state) { state.counter ++ } } })export default store
然后页面中调用就完事了。
1 <button @click ="$store.commit('increment')" > {{ $store.state.counter }}</button >
其他插件 其实其他插件的使用方法跟elementui
的一样 假如我们想使用 vue-notifications
显示应用的通知信息,我们需要在程序运行前配置好这个插件。 首先增加文件 plugins/vue-notifications.js
:
1 2 3 import Vue from 'vue' import VueNotifications from 'vue-notifications' Vue .use (VueNotifications )
然后, 在 nuxt.config.js
内配置 plugins
如下:
1 2 3 module .exports = { plugins : ['~/plugins/vue-notifications' ] }
jquery 1 2 cnpm install jquery@3.1 .0 -S-d
然后nuxt.config中加入这一段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 build : { vendor : ['jquery' ], plugins : [ new webpack.ProvidePlugin ({ '$' : 'jquery' }) ], postcss : { preset : { features : { customProperties : false } } }, extend (config, ctx ) {} }
less nuxt
中并不包含less
解析工具
1 cnpm install less less-loader -S-d
安装完毕以后,跟vuecli中使用的方法一样。
1 <style lang ="less" > <style >
模板 打开layouts这个文件夹,里面都是你在pages中可以引入的模板,你也可以自己创建一个模板。
1 2 3 4 5 6 7 8 9 10 11 12 <template > <div > <div > top</div > <nuxt > <div > bottom</div > </div > </template > <script > export default { } </script >
每一个pages中的vue文件都有一个layout属性,把我们要用的模板填进去。(模版文件名)
全局组件 plugins文件夹目录建一个component.js文件
1 2 3 import Vue from 'vue' import 组件 from '@/components/组件.vue' Vue .component ("xxx" ,组件);
打开 nuxt.config.js
1 2 3 4 5 module .exports = { plugins :[ '@/plugins/component.js' , ] }
其他操作 修改head nuxt本身支持一个head方法,放到跟生命周期同级即可。
1 2 3 4 5 6 7 8 9 10 head () { return { title : this .title , meta : [{ hid : 'description' , name : 'description' , content : 'content' , }] } }
加载图片
页面中加载
1 2 <img src ="~/assets/image.png" >
css中加载
1 2 3 .{ background:url("~assets/banner.svg") }
nuxt generate generate:构建应用程序并生成每个路径作为HTML文件(用于静态托管)
使用generate打包后每个对应的页面都会生成一个html,你在打包的时候不能关闭后台,他会请求后台数据生成首屏的数据
这样打包有一个弊端,当你首屏的数据发生更改的时候,对不起,他还是显示的是之前的数据,要想改变的话,需要重新打包发布才行。
所以,如果你的首屏是动态的就不建议使用这种打包方式了。
有人看到每个页面都生成了HTML页面,以为不再请求后台(我最开始就是这样认为的),实际上不是的,他的首屏数据之前渲染好了,但是其它数据还是从后台获取,比如翻页,第二页数据是从新请求后台的,你再次返回第一页也是再次请求的。
获取数据 官方:不能在组件中使用异步。
但是你可以在父级使用异步,在通过组件传值的方法传给你的组件。
首页拿到数据以后,先给自己的data暂存一下,然后在通过created周期,通过commit发送给vuex即可,或者通过props发送给组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 asyncData (context ) { return context.$axios .get ('index/query' ) .then (res => { return {index :res.data .result [0 ]}; }) },created :function ( ){ this .$store .commit ('getIndex' ,this .index ) },methods : { async fetchSomething ( ) { const ip = await this .$axios .$get('http://icanhazip.com' ) this .ip = ip } }
store
1 2 3 4 5 6 7 8 9 { actions: { async getIP ({ commit } ) { const ip = await this .$axios.$get ('http://icanhazip.com' ) commit('SET_IP' , ip) } } }
axios配置 nuxt.config.js
拦截
nuxt.config.js
1 2 3 4 5 export default { plugins: [ '~/plugins/axios' ] }
创建plugins/axios.js
1 2 3 4 5 6 7 8 9 10 11 12 export default function ({ $axios, redirect }) { $axios.onRequest(config => { console.log('Making request to ' + config.url) }) $axios.onError(error => { const code = parseInt(error.response && error.response.status) if (code === 400 ) { redirect('/400' ) } }) }
setToken
1 2 3 4 5 6 7 8 9 10 11 12 13 14 this .$axios.setToken('123' )this .$axios.setToken('456' )this .$axios.setToken('123' , 'Bearer' )this .$axios.setToken('123' , 'Bearer' , ['post' , 'delete' ])this .$axios.setToken(false )
重写axios /plugin/api.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export default function ({ $axios }, inject ) { const api = $axios.create ({ headers : { common : { Accept : 'text/plain, */*' } } }) api.setBaseURL ('https://my_api.com' ) inject ('api' , api) }
nuxt.config.js
1 2 3 export default { plugins : ['~/plugins/api.js' ] }
然后您的组件可以使用新的Axios实例:
1 2 3 4 5 6 7 8 export default { fetch ( ) { this .$api .get (...) }, asyncData ({ $api } ) { $api.get (...) } }
全局样式 nuxt.config.js
1 2 3 4 5 6 7 8 css : [ '@/assets/css/xxx.less' ]build : { extractCSS : { allChunks : true }, },
环境区分 1 npm install --save-dev cross-env
根目录创建env.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 module .exports = { DEV : { NODE_ENV : 'DEV' , API_URL : 'http://18.163.xxx.xxx:8080' , IMKEY : '11xxdd34234290546#xxxxxx' }, TEST : { NODE_ENV : 'TEST' , API_URL : 'http://18.163.xxx.xxx:8080' , IMKEY : '11xxdd34234290546#xxxxxx' }, PRO : { NODE_ENV : 'PRO' , API_URL : 'https://xxxxxx.com' , IMKEY : '1234567800111#xxxxxv' }, }
uxt.config.js
1 2 3 4 import env from './env.js' env[process.env .NODE_ENV ].NODE_ENV env[process.env .NODE_ENV ].API_URL env[process.env .NODE_ENV ].IMKEY
端口 package.json
1 2 3 4 5 6 7 8 { "config" :{ "nuxt" :{ "host" :"0.0.0.0" , "port" :"3001" } } }
部署 部署前远程服务器需要安装node
,pm2
,nginx
放置到服务器上的代码只需要4个目录和文件
.nuxt 这是打包构建好的所有依赖文件及源文件等等
static 静态资源包,因为上面打包构建时,不会被打进去的
nuxt.config.js 配置文件
package.json 比较重要。当”start”: “cross-env NODE_ENV=production node server/index.js”,时需要把它更改为:”start”: “nuxt start”
宝塔
网站
node项目
稳定版
启动:start
端口:3000 默认
问题 错误提示:”You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.“
1 2 3 4 build: { postcss: null, }