关于nuxt.js:Nuxt3实战系列之集成ElementPlusUI

Nuxt框架因为做了一些封装解决,曾经将入口文件齐全暗藏了,因而对于一些老手小白来说,怎么在Nuxt中引入一些第三方库就成了个麻烦事。ElementPlus UI 自身反对服务端渲染,本文将次要概述如何在Nuxt3中集成ElementPlus。 如何引入?1.先装置Element Plus # 抉择一个你喜爱的包管理器# NPM$ npm install element-plus --save# Yarn$ yarn add element-plus# pnpm$ pnpm install element-plus2.装置Nuxt官网专门针对引入Element Plus 开发的模块 # 抉择适合的包管理器,npm/yarn/pnpmpnpm i @element-plus/nuxt -D3.在nuxt.config.ts中配置modules参数 export default defineNuxtConfig({ modules: [ '@element-plus/nuxt' ], elementPlus: { /** Options */ }})至此,曾经引入胜利,且所有Element Plus 组件也都能够间接主动导入。 应用进阶1. 如何做全局配置@element-plus/nuxt 中提供了一些配置参数,咱们只须要在nuxt.config.ts中定义elementPlus参数即可,比方配置主题 export default defineNuxtConfig({ modules: [ '@element-plus/nuxt' ], elementPlus: { themes: ['dart'] }})所有的配置参数能够点击查看官网文档 2.如何全局引入element ui 图标?Element Plus UI 的图标并未在nuxt3中做主动导入,所以应用的时候,须要手动从@element-plus/icons-vue中导入, 如下: <script lang="ts" setup>import { Document } from '@element-plus/icons-vue'</script><template> <el-icon><Document /></el-icon></template>然而如果咱们很多中央都要用到图标,且有时候须要应用动静引入的时候,这样手动import就比拟麻烦了,那么如何全局引入图标呢?在Nuxt3中,咱们能够创立一个plugin来实现。笔者的做法是在plugins目录中创立一个global.ts文件,用于全局引入一些组件。 ...

March 2, 2023 · 1 min · jiezi

关于nuxt.js:Assertion-failed-threadidkey-0x7777

应用npm run build时报了这个谬误:Assertion failed: (thread_id_key != 0x7777), function find_thread_id_key, file ../src/coroutine.cc, line 134.error Command failed with signal "SIGABRT".我编译的是一个nuxt.js的我的项目,这个我的项目有个依赖 "fibers": "^5.0.0", 下面的谬误呈现起因是因为node-fibers在 nodejs >=16.x 的版本曾经被弃用了。 查看本地node版本 node/16.16.0 果然是这个问题。 切换至低于16的版本,npm run build 失常。

November 8, 2022 · 1 min · jiezi

关于nuxt.js:nuxt项目部署后报错

问题如图运行nuxt我的项目的时候提醒找不到模块,然而模块文件中有,求解

August 22, 2022 · 1 min · jiezi

关于nuxt.js:nuxt项目本地启动标签页个数问题

问题:nuxt 我的项目本地启动 npm run dev,本地localhost多开几个标签页,会呈现卡死或始终转圈的状况,如果敞开其中一个tab标签,卡死的tab标签页就会立刻加载实现,控制台看不到任何错误信息。   问题剖析:浏览器对同一个主机有连接数限度。  解决办法:(1)Chrome浏览器目前是没有解决办法的;(2)Firefox浏览器能够批改,在浏览器输出 about:config,在文本框输出 network.http.max-persistent-connections-per-server,默认最大连接数是6,比方改成60保留。测试OK    参考起源:https://github.com/nuxt/nuxt.js/issues/8190

August 18, 2022 · 1 min · jiezi

关于nuxt.js:nuxt-路由拦截

1,配置1.1,在plugin 下创立 userAuth文件 export default (context) => { if(process.client){ const token = sessionStorage.getItem('token'); context.app.router.beforeEach( (to, from, next) => { if( !token && to.path !== '/login' ){ next('/login'); }else if(to.path !== '/login'){ next(); }else { next(); } }) }};留神1)路由以后门路和跳转门路不要反复,不然会呈现 死循环,超出堆栈问题。Maximum call stack size exceeded。2)莫名其妙呈现的如下报错,然而清理缓存之后就隐没了。[SSE] Connecting to /_loading/sse...3)process.client 是判断以后是处于服务端,还是客户端。因为,sessionStorage 是window 对象,在服务端获取不到。 2,调用在nuxt.config.js中调用 plugins: [ '@/plugins/userAuth' ],另外:应用中间件进行路由拦挡应用中间件会有一个问题,间接如输出指标地址,例如:https://192.1.1.1/home会胜利进入,只有跳转到别的地址的时候,才会拦挡,跳转登录页。所以,并不举荐应用 export default function ({ route, redirect }) { if (process.client) { const token = sessionStorage.getItem('token'); if (!token && route.path !== '/login') { redirect('/login'); } }}参考:nuxt中的process.static/process.server/process.client ...

January 12, 2022 · 1 min · jiezi

关于nuxt.js:nuxt纯前端导出文本

这里介绍一个纯前端导出的插件 file-saver。通过这个插件,能够导出 txt , 导出 canvas的 png 图片。GihHub地址:FileSaver.js 1,装置npm install file-saver --savebower install file-saveryarn add file-saver2,应用2.1 在plugins/file-save.js 创立全局办法。 import { saveAs } from "file-saver";export default (ctx, inject) => { inject("saveAs", saveAs);};2.2 在具体方法里调用 saveFile(){ let textContent = ""; for (let i = 0; i < 10; i++) { textContent += `你好${i + 1} \r\n`; } const blob = new Blob([textContent], { type: "application/json" }); this.$saveAs(blob, '导出.txt'); },导出后果 祝大家新年快乐~~

December 31, 2021 · 1 min · jiezi

关于nuxt.js:nuxt-使用-markdown组件

简略介绍一下,在nuxt里 援用 vue-markdown 组件。 组件Git 地址:https://github.com/miaolz123/... 1,装置NPM $ npm install --save vue-markdownYarn $ yarn add vue-markdown --save2,应用2.1,新建 vue-markdown 文件 在 plugins 下,新建 vueMarkdown 文件,引入装置的组件 import Vue from 'vue';import VueMarkdown from 'vue-markdown';Vue.component("VueMarkdown", VueMarkdown);2.2, 在nuxt.config.js 里调用 vueMarkdown 文件 plugins: [ '~/plugins/vueMarkdown' ],2.3,在须要的页面调用 <template> <div> <el-input v-model="source" type="textarea"></el-input> <vue-markdown id="markdown" :source="source"></vue-markdown> </div></template>成果如下图所示:在文本域里编写 markdown 格局的文本,组件就会主动解析并进行展现。如果,想要批改其中的款式,须要定位具体的地位。我是采纳 /deep/ 的形式进行定位。 #markdown /deep/ p { color: rgb(17, 180, 139)}

December 5, 2021 · 1 min · jiezi

关于nuxt.js:nuxt-使用-Vue-JSON-Schema-Form

当咱们须要对一些 结构复杂,或内容较多的JSON 进行批改配置的时候,极易容易出错。于是,就想着是否能通过表单模式进行批改,保留。最初,发现了几个JSON 编辑器。1,Vue JSON Schema Form 2,Vue-Json-Edit 3,json-editor 这里采纳的是,第一个 Vue JSON Schema Form 插件。上面,就介绍一下,在nuxt 中,如何应用。 1,装置该命令是 装置 vue2 + elementUI 版本的。其余版本的装置命令能够查阅官网。npm install --save @lljj/vue-json-schema-form 2,应用2.1 在 plugins 下新增 json-schema.js 文件,调用组件 import Vue from "vue";import VueForm from "@lljj/vue-json-schema-form";Vue.component("VueForm", VueForm);2.2,在所需的中央,应用 VueForm 组件 <template> <div> <VueForm v-model="formData" :schema="config.schema" :form-props="{ layoutColumn: 2, }" @on-submit="handlerSubmit" @on-cancel="handleCancel" > </VueForm> </div></template><script>import config from "@/config/config_form_schema";export default { data() { return { config, formData: {}, }; }, methods: { handleCancel(){ // 勾销操作。 }, handlerSubmit() { // 提交操作。 console.log('formData后果:',this.formData) }, },};</script>当须要解决简单JSON文件时,能够采纳导入的形式,赋值给schema schema 的格局编写,可参考:配置 schema 和 JSON Schema 标准 ...

November 19, 2021 · 1 min · jiezi

关于nuxt.js:nuxt拆分自定义接口

之前的文章有讲到 nuxt 封装API,并进行简略的调用。在理论的开发中,接口会越来越多,如果持续放到一个文件下,就会拥挤不堪,所以,能够依据功能模块,将接口拆分一下,在api 文件里别离引入不同功能模块的申请地址。具体操作如下: 1,创立API文件1,在我的项目根目录下,创立一个API文件 |--src|--api |--module1.js |--module2.js2,编写 module1.js 文件 export default ($axios) => ({ get() { return $axios.$get("/v1/XXX") }, put(data) { return $axios.$put("/v1/XXX",data) }, . . .})2,批改plugins/api.js 文件// 数据接口import module1Repository from "../api/module1"import module2Repository from "../api/module2"export default function ({ app, $axios, error }, inject) { const API = {} const api = $axios.create({ baseURL: process.env.BASE_URL, // url = base url + request url timeout: 5000, // request timeout }) // 设置response 拦挡 // api.interceptors.response.use( // // 接口谬误状态解决,也就是说无响应时的解决 // // response => { // // // 拦挡响应,做对立解决 // // if (response.status) { // // switch (response.status) { // // case 409: console.log('呜呜呜呜'); break; // // } // // } // // return response // // }, // error => { // console.log('哎呀,粗错啦', error.response) // // 返回接口返回的错误信息 // return Promise.reject(error) // } // ) API.module1API = module1Repository(api) API.module2API = module2Repository(api) app.api = API inject("api", API)}3,应用1,在 asyncData 中应用 ...

November 5, 2021 · 1 min · jiezi

关于nuxt.js:nuxt-使用-jsonserver-搭建后台

json-server是一款基于Node.js的服务器,为前端开发人员能够提供一个高仿真的RESTFul后盾服务(数据原型),最让人欢喜的是,整个服务的搭建过程不须要编写任何代码,最快只须要1分钟。配合上mock ,就能够随机生成后端数据了。 1,装置npm install -g json-serve原本是打算应用 yarn add -g json-server 或 yarn add json-server 装置,但最初都不能失常应用。于是采纳了npm 装置。 2,应用2.1 编写数据文件。为了测试临时先将数据存到了 src/static/jsonData/mockTest.js // 用mockjs模仿生成数据const Mock = require('mockjs');module.exports = () => { // 应用 Mock const data = Mock.mock({ "list|10": [ { "id|+1": 1, email: "@EMAIL", }, ], }); // 返回的data会作为json-server的数据 return data;};应用mock 随机生成10个数据。 2.2 启动json-server 服务留神:须要进入到数据文件的层级,执行以下命令 json-server --watch --host 0.0.0.0 --port 3001 mockTest.js设置 --host 0.0.0.0 就能够应用本机IP拜访。如下图所示,示意,启动胜利。通过本机IP就能够拜访数据了 至此,就能够像失常接管API 一样,在前端接收数据了。

October 28, 2021 · 1 min · jiezi

关于nuxt.js:nuxt-mock-axios-创建随机数据

这里简略介绍一下,nuxt 下mock + axios 的装置、应用。 mock可能生成随机数据,拦挡 Ajax 申请。对于纯前端来说,mock 配合express,就能够本人搭建后盾了。也能够参考一下 vue-element-admin 对于mock 的应用,以及一些大佬踩过的坑。 mock1,装置npm install mockjs 2,增加mock 代码// plugins/mock.jsimport Mock from "mockjs"Mock.mock(/user\.json/, { "list|1-10": [ { "id|+1": 1, email: "@EMAIL", }, ],})3,nuxt.config.js配置 plugins: [ '@/plugins/mock' ],4,mock数据调用 methods: { async getTempGameList() { const mockData = await this.$axios.$get("user.json") console.log("mockData", mockData) },}数据后果: 留神:mock的申请数据无奈在nuxt 提供的 asyncData 里调用。这里是在 methods 里调用的。 @nuxtjs/axios对于 @nuxtjs/axios 的装置,详见之前的文章:nuxt---axios封装+环境变量配置 在获取数据的时候呈现如下问题: TypeError: request.upload.addEventListener is not a function网上说:导致这一问题的根本原因是 Mockjs 中, 封装了原生的 XMLHttpRequest 为 MockXMLHttpRequest.解决思路是, 把原生 XMLHttpRequest 的 upload 属性赋给 MockXMLHttpRequest 的原型对象.在 node_modules/mockjs/dist/mock.js 退出以下代码 ...

October 28, 2021 · 1 min · jiezi

关于nuxt.js:nuxt部分组件详解

这篇文章整顿一下,nuxt中 pages/layout/components/plugins 的相干应用 。之前曾经手上应用过了,这次具体的看一下官网文档,加深了解。目录构造 |--src |--components ---编写重复使用组件。 |--layout ---编写全局款式。 |--pages ---编写具体页面。 |--plugins ---编写须要的插件。components该components目录蕴含您的 Vue.js 组件。组件形成了页面的不同局部,能够重复使用并导入到页面、布局甚至其余组件中。通过在 nuxt.config.js 文件中进行如下配置,能够间接应用组件,无需导入 export default { components: true}|-- components/ |-- TheHeader.vue |-- TheFooter.vue<template> <div> <TheHeader /> <Nuxt /> <TheFooter /> </div></template>援用时,须要与文件名雷同。当components 层级较多时的援用办法: |--components |--base |--foo |--CustomButton.vue组件名称将基于其本人的门路目录和文件名。因而,该组件将是 <BaseFooCustomButton />获取数据components 获取数据的形式是: Nuxt中的 fetch() 。无奈应用asyncData,因为asyncData办法会在组件(限于页面组件)每次加载之前被调用。 <script> export default { async fetch({ store, params }) { let { data } = await axios.get('http://my-api/stars') store.commit('setStars', data) } }</script>留神:无奈在外部应用this获取组件实例,fetch是在组件初始化之前被调用 layout编写全局布局,例如,侧边栏,导航栏。 |-- layout |-- default.vuedefault.vue 文件,会默认利用到所有未指定布局的页面。援用导航栏,页脚组件: ...

October 20, 2021 · 2 min · jiezi

关于nuxt.js:nuxt国际化之路由部分

上篇有讲到国际化的根本配置,并不是很全,这篇讲一下,国际化切换的路由变动状况。 正确应用:1.文件构造: |--pages |--textA |--_lang |--_text |--index.vue2.nuxt-link 应用 <nuxt-link :to="{ name: 'textA-lang-text', params: { lang: $store.state.locale ,text: '111'} }" class="uk-link-reset"></nuxt-link>$store.state.locale 获取store存储的语言记录产生的路由:localhost:3000/textA/en/111 其余状况1,当_lang文件在最里面,且有可间接承受参数的文件。 |--pages |--_lang |--index.vue |--_textA |--index.vue |--index.vue<nuxt-link :to="{ name: 'lang-textA', params: { lang: $store.state.locale ,textA: '111'} }" class="uk-link-reset"></nuxt-link>看一下,具体的路由变动 app.i18n.path = (link) => { if (app.i18n.locale === app.i18n.fallbackLocale) { return `/${link}` } return `/${app.i18n.locale}/${link}` }当切换到默认语言时,预计路由后果:http://192.168.XX.XXX:3000/111 (_lang下的index文件)理论路由后果:http://192.168.XX.XXX:3000/111 (_textA下的index文件)当抉择默认语言时,路由挂载的参数,第一个lang 会被省略,不会进入_lang 文件,第二个参数会匹配pages下承受参数的文件,也就是_textA 文件。 2,当_lang文件在最里面,且无承受参数的文件。 |--pages |--_lang |--index.vue |--textB |--index.vue |--index.vue、当切换到默认语言时,预计路由后果:http://192.168.XX.XXX:3000/111 (_lang下的index文件)理论路由后果:no found当抉择默认语言时,路由挂载的参数,第一个lang 会被省略,不会进入_lang 文件,第二个参数会匹配pages下承受参数的文件,然而目前没有承受参数的文件,也没有参数同名的 111 这个文件,所以间接报错。 ...

October 19, 2021 · 1 min · jiezi

关于nuxt.js:nuxt-国际化本地保存

因为我的项目须要,在这里记录一下对于nuxt 国际化应用,并增加 刷新页面语言不重置性能。参考nuxt 官网提供的国际化利用:nuxt 官网参考代码 1,文件构造|--locales ------寄存不同语言的json 文件。 |--en.json |--fr.json|--middleware ------nuxt 的中间件,解决路由 |--i18n.js|--pages ------具体页面,国际化的页面须要在_lang 下,例如:pages/en/about |--_lang |--about.vue|--plugins ------实现语言切换的中央。 |--i18n.js|--store ------应用vuex 存储。 |--i18n.jsjs|--nuxt.config.js ------国际化相干配置2,装置npm install vue-i18n --save3,应用3.1 调用,初始渲染国际化的内容要蕴含在 { { $t( ) } } 里 <h1 class="titleFont">select you language</h1> {{ $t('links.about') }}links.about 是语言的json 文件里的字段内容。初始渲染为 app.i18n.fallbackLocale 的值。app.i18n.fallbackLocale 在 plugins-i18n.js 里配置。 3.2,语言切换HTML <div class="languageInfo" @click="changeLanguage('zh')"> <img src="../assets/img/language/China.png" alt="" width="35px" height="35px"> <span class="languageFont">简体中文</span></div>js changeLanguage(language){ this.$i18n.locale = language; Cookies.set('lang', language);}具体实现切换的办法是, this.$i18n.locale = language;通过 cookie 保留 已抉择的语言。因为,在切换语言,并手动刷新页面之后,语言会重置为默认值。无奈记录以后抉择的语言。所以要进行本地保留。不应用 localStorage 的起因是,在plugins---i18n.js里调用 localStorage.getItem() 时会呈现 'localStorage' is not defined 的问题。在SSR中,created生命周期在服务端执行,node环境中没有localStorage所以会报错,将须要应用localStorage的代码放到浏览器应用的生命周期(mounted)中。 ...

October 13, 2021 · 2 min · jiezi

关于nuxt.js:PM2守护方式启动nuxt项目

1,批改package.json{ "name": "ii222", "version": "1.0.0", "private": true, "scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt build && nuxt start", "generate": "nuxt generate" }, // 以下省略}2进入到我的项目目录执行如下命令pm2 start ./node_modules/nuxt/bin/nuxt.js罕用的PM2命令pm2 list # 列表 PM2 启动的所有的应用程序pm2 stop 0 # 进行 id为 0的指定应用程序pm2 restart 0 # 重启id为0 的应用程序pm2 delete 0 # 删除指定利用 id 0pm2 start app.js # 启动app.js应用程序pm2 start app.js --name="demo" # 启动应用程序并命名为 "demo"pm2 start app.js --watch # 当文件变动时主动重启利用pm2 start script.sh # 启动 bash 脚本pm2 show [app-name] # 显示应用程序的所有信息pm2 logs # 显示所有应用程序的日志pm2 logs [app-name] # 显示指定应用程序的日志pm2 stop all # 进行所有的应用程序pm2 restart all # 重启所有利用pm2 delete all # 敞开并删除所有利用pm2 startup # 创立开机自启动命令pm2 save # 保留以后利用列表

September 6, 2021 · 1 min · jiezi

关于nuxt.js:Nuxt出现Server-error的解决方案

1、前提当咱们在应用nuxt ssr部署上线的时候,如果在asyncData也就是服务端申请的办法中呈现报错,那么会导致线上环境呈现server error的报错页面。对于普通用户来说体验感极差,不利于我的项目的稳定性。 2、如何解决?这个能够分为两局部: 1、从代码方面动手上线前严格测试代码的可行性。确保十拿九稳,尤其是接口返回的冗余、业务逻辑的解决、代码书写的正确性、返回值是否存在等等。 2、扭转Server error 报错页面交互。默认的页面报错给人的感觉就是服务不可用,让用户有一种不信赖的感觉。潜在的危险就是导致用户的散失。所以能够以一种敌对的交互方式,让用户看到报错不在那么着急。 3、实现形式Nuxt官网提供了简略的解决办法。在asyncData中如果呈现谬误抛出的话就会跳转到指定页面。然而此办法只实用于前端报错,如果是服务端呈现谬误还是会呈现Server error。 所以有了本文的办法 1、在Pages的同级目录下建一个app的文件夹,在app中新建views文件夹。2、在views中创立一个error.html用来显示呈现Server error报错后的展现。 3、html的款式能够依据网站理论状况让UI做一个特定状况的展现页。 那么下次在呈现Server error的时候,浏览器就不是显示一个零碎报错,而是显示本人设定的指定页面。

September 3, 2021 · 1 min · jiezi

关于nuxt.js:nuxt启动报错-Error-getaddrinfo-ENOTFOUND-0

nuxt 我的项目启动,执行npm run dev 报错 Error: getaddrinfo ENOTFOUND 0 起因: nuxt.config.js 中 serve 配置项 host,把 '0' 换成 '0.0.0' server: { // host: '0', // 这种写法 mac上没问题,windows会报错 host: '0.0.0.0', // 改成这种写法就好了 timing: false },再次启动,胜利

September 2, 2021 · 1 min · jiezi

关于nuxt.js:全栈导航网站挂掉我是如何排查问题

问题我忽然发现,网站刷新的时候打不开了,如果是路由跳转进去,是失常的 然而网站经常链接会被他人珍藏,或者间接分享关上,间接打不开必定不好 问题剖析:此网站我是采纳的nuxt.js开发的,个别这种谬误类型,通过网络申请的数据,而后在对象下的某属性失落,造成谬误类型排查通过查看,是在父级页面申请的数据,传到子组件数据失落 page.js 页面<template> <div class="aritcle-detail"> <Header /> <div class="wp clearfix"> <Detail :detail="detail"></Detail> </div> <Footer /> </div></template><script>import { apiNavthemeDetail } from '@/api/navtheme'import Detail from '@/web/article/Detail'export default { components:{ Detail }, async asyncData({ $axios, app, store, params,route }) { console.log('router',params.id); const res = await apiNavthemeDetail({ id: params.id }); return { detail: res.data, params } }, mounted() { setTimeout(() => { console.log('params', this.params) console.log('detail', this.detail) }, 3000) }}</script>Detail子组件<template> <div class="detail"> <div class="detail-left"> <div class="info"> <div class="header"> <h1>{{detail.title}}</h1> <div class="meta"> <span> {{detail.member.it_name}}次 </span> </div> </div> <div class="user"> <div class="user-left"> <div class="img"> <img :src="detail.member.userhead" alt /> </div> <div class="name"> <b>{{detail.member.username}}</b> <span class="user-title">{{detail.member.description}}</span> </div> </div> </div> <div class="content article-md"> <no-ssr> <mavon-editor class="detail-md itnavs-markdown" :value="detail['content']" :subfield="false" :defaultOpen="'preview'" :toolbarsFlag="false" :editable="false" /> </no-ssr> </div> </div> <div class="community"> <img src="@/assets/images/qzdh.jpg" alt /> </div> </div> </div></template><script>import Rightuser from './Rightuser'import Casually from './Casually'export default { components: { Rightuser, Casually }, props: ['detail'],}</script>查看服务器日志nuxt.js 是node过程,启动的是用pm2,如有不懂,清查看我之前写的【文章】 ...

August 14, 2021 · 2 min · jiezi

关于nuxt.js:Nuxt学习笔记

常识脉络 Nuxt.js 根底简介Nuxt.js 是一个基于 Vue.js 的第三方开源服务端渲染利用框架它能够帮咱们轻松的实现同构利用通过对客户端 / 服务端基础架构的形象组织,Nuxt.js 次要关注的是利用的 UI 渲染咱们的指标是创立一个灵便的利用框架,你能够基于它初始化新我的项目的根底构造代码,或者在已有 Node.js 我的项目中应用 Nuxt.jsNuxt.js 预设了利用 Vue.js 开发服务端渲染的利用所须要的各种配置,相似于脚手架生成了我的项目的根本框架提供了一种命令叫: nuxt generate ,为基于 Vue.js 的利用提供生成对应的动态站 点的性能,是向开发集成各种微服务(Microservices)的 Web 利用迈开的新一 步作为框架,Nuxt.js 为 客户端 / 服务端 这种典型的利用架构模式提供了许多有用的个性,例如异步数据 加载、中间件反对、布局反对等十分实用的性能 Nuxt 框架是如何运作的Nuxt.js 集成了以下组件 / 框架,用于开发残缺而弱小的 Web 利用: Vue.jsVue RouterVuexVue Server Renderer压缩并 gzip 后,总代码大小为:57kb (如果应用了 Vuex 个性的话为 60kb)。 另外,Nuxt.js 应用 Webpack 和 vue-loader 、 babel-loader 来解决代码的自动化构建工作(如打包、代码分层、压缩等等)。 NuxtJS 个性基于 Vue.jsVue、Vue Router、Vuex、Vue SSR 主动代码分层服务端渲染弱小的路由性能,反对异步数据动态文件服务ES2015+ 语法反对打包和压缩 JS 和 CSSHTML 头部标签治理本地开发反对热加载集成 ESLint反对各种款式预处理器: SASS、LESS、 Stylus 等等反对 HTTP/2 推送 ...

June 22, 2021 · 6 min · jiezi

关于nuxt.js:nuxtjs开发问题收集

1.nuxt generate打包,动静路由不合适用这种形式打包,应该用npm run build2.filter格式化工夫:replaceAll报没有此办法,replace能够3.vue 播放视频: :src不起作用,须要this.$refs.videoDeRef.src = this.nowItem.videoUrl动静设置门路,this.$refs.videoDeRef.play()动静触发播放视频4.window.abc、Vue.prototype.abc,全局变量

May 28, 2021 · 1 min · jiezi

关于nuxt.js:nuxtjs-项目问题记录

1.应用swiper:因为我的项目须要自动播放,swiper6自动播放始终有效,后发现须要改成swiper5。版本别离为:"swiper": "^5.4.5","vue-awesome-swiper": "^4.1.1"。nuxt.config.js:nuxt-swiper-plugin.js:配置属性:2.要实现的双向联动成果,点击左侧滑动到对应地位,滑动到某个地位,左侧对应模块选中:遇到的问题:始终为0。通过这种形式:获取的值也为0。后发现:这种形式能够获取到值,然而在mounted中能够获取到,后续获取也始终为0。实现代码: handleScroll() { // 滑动监听 let top = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop // 滚动条偏移量 let scrollTop = top - this.topSet if (scrollTop >= this.topList[0] && scrollTop < this.topList[1]) { this.navIndex = 0 } else if (scrollTop >= this.topList[1] && scrollTop < this.topList[2]) { this.navIndex = 1 } else if (scrollTop >= this.topList[2]) { this.navIndex = 2 } else if (scrollTop < this.topList[0]) { this.navIndex = -1 } if (top > 50) { this.tellSign = true } else { this.tellSign = false }},jumpPage(index) { let PageId = this.topList[index]; window.scrollTo({ 'top': PageId, 'behavior': 'smooth' })},

May 8, 2021 · 1 min · jiezi

关于nuxt.js:用nuxtjs-做vue项目的ssr遇到的相关问题

1.app.vue中的router-view,能够通过layout文件夹下的default.vue中<nuxt/>标签替换,default.vue页面能够写一些界面独特款式。2.layout文件夹下的error.vue能够写找不到对应页面时的提醒内容以及逻辑3.本次我用less写的css款式,后期没有增加layout文件夹上面的内容,单纯的把所有的页面写完了,通过浏览器勾掉或者增加款式时,款式就崩掉(即该div会失去增加的className,勾掉从新勾选或者增加而后删除复原成原样也不起作用,从新刷新又会有该className),后续将对应布局抽取放入default.vue中,调试就不再呈现这种状况,临时还未找到起因4.想在default.vue中监听路由变动,必须加immediate: true能力监听到,否则不触发办法

April 28, 2021 · 1 min · jiezi

关于nuxt.js:nuxt-如何使用

小记 环境 nuxt.js + typescript + ant-design-vue文章分类:next入门、nuxt如何应用class语法、vue2+ts开发nuxt我的项目 文件1:pages/expriment.vue <template> <div> hello World ! <nzDemandLayer /> </div></template><script lang="ts">import { Component, Vue, State, Action, } from "nuxt-property-decorator";import { DatePicker } from "ant-design-vue";import nzHeader from "~/components/nz-header";import nzDemandLayer from "~/components/nz-demand-layer";@Component({ components: { nzDemandLayer, nzHeader },})export default class Expriment extends Vue { onChange(date:any, dateString:any) { console.log(date, dateString); }}</script>文件2:components/nz-header.vue   <template> <div id="topaaa"> header </div></template><script lang="ts">import { Component, Vue, State, Action, } from "nuxt-property-decorator";export default class Header extends Vue {}</script><style> @import './navigation.css';</style>能够看到,我只是在 expriment 页面里注册了组件就导致了 ant-design 的DatePicker组件不可用。 ...

November 27, 2020 · 1 min · jiezi

关于nuxt.js:基于NuxtjsVue聊天实例nuxt仿微信探探聊天界面

1、我的项目简介Nuxt.js是目前比拟热门的服务端渲染SSR框架。凭借其更好的SEO、更快的内容达到工夫(*首屏渲染速度快*) 加之基于Vue.js技术开发,更易于上手,取得了很多技术开发者的青眼。nuxt_chatroom我的项目是基于nuxt+vue+vuex+vant等技术开发的仿微信|Tinder界面聊天实例。实现了卡片式翻动、音讯发送/表情gif、图片/视频预览、红包/朋友圈等性能。 成果片段啧啧,成果还能够吧,上面就来解说下实现过程。 2、技术框架应用技术:nuxt.js+vue.js+vuexUI组件库:vant-ui (有赞挪动端vue.js组件库)字体图标:阿里iconfont图标库弹窗组件:vpopup(基于vue自定义弹框)本地存储:cookie-universal-nuxt: ^2.1.4 大家如果对Nuxt.js不相熟的话,能够先去官网看看材料。其实只有你会vue,上手就非常简单的。https://zh.nuxtjs.org/https://github.com/nuxt/nuxt.js 3、我的项目目录构造想理解更多Nuxt.js目录构造及应用阐明,能够去参看上面链接。https://zh.nuxtjs.org/guide/d... 4、对于自定义组件我的项目中 顶部Navbar、Tabbar及弹窗 均是自定义组件实现的,这里不作过多解说,感兴趣的能够去看看上面的分享文章。Nuxt/Vue仿咸鱼Tabbar凸起成果|vue自定义导航栏Vue自定义弹框组件|仿android/ios弹窗成果 5、仿Tinder|探探卡牌翻动遇见页面原型参考了社交App探探的卡片滑动成果。整体分为 顶部导航、滑动区、底部标签栏 等三个局部。这里不过多介绍,感兴趣的能够去看上面的这篇分享文章。Vue|Nuxt.js仿探探卡片式左右拖拽|vue仿Tinder 6、nuxt默认布局nuxt我的项目中,layouts目录下的default.vue页面为默认的布局页面。 <!-- 布局模板 --><template> <div class="nuxt__container flexbox flex-col"> <header-bar /> <div class="nuxt__scrollview scrolling flex1"><nuxt /></div> <tab-bar /> </div></template>留神:在nuxt我的项目中是通过<nuxt />来显示主体内容的,而vue中则是应用<router-view />。 nuxt.config.js配置文件nuxt.js的默认配置文件,能够配置 meta、路由信息、css/js及插件引入、webpack等配置。https://zh.nuxtjs.org/guide/configuration/ export default { // 端口配置(可选) server: { port: 3000, host: '192.168.122.100' }, /* ** 页面头部meta信息配置 */ head: { title: process.env.npm_package_name || '', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1, user-scalable=no' }, { hid: 'keywords', name: 'keywords', content: 'Vue.js | Nuxt.js | Nuxt仿微信'}, { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } ], link: [ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, { rel: 'stylesheet', href: '/js/wcPop/skin/wcPop.css' }, ], script: [ { src: '/js/fontSize.js' }, { src: '/js/wcPop/wcPop.js' }, ] }, /* ** 全局css配置 */ css: [ '~/assets/css/reset.css', '~/assets/css/layout.css', '~/assets/fonts/iconfont.css', ], /* ** 全局插件列表 */ plugins: [ '~/plugins/vue-global.js', // 通过这种形式引入本地js也能够(需设置ssr:false) // {src: '~/assets/js/fontSize.js', ssr: false} ], // ...}nuxt.config.js中的meta是全局配置的,如果独自页面配置,参考如下: ...

October 16, 2020 · 2 min · jiezi

关于nuxt.js:基于Nuxt实现Token过期自动刷新

性能概述我的项目应用前后的拆散的开发模式,后端应用Spring Security实现基于Jwt的用户认证模式,数据交互应用Json格局。前端应用Nuxt框架实现服务端渲染(SSR)性能,应用Vuex实现登录状态存储,应用@nuxtjs/axios插件加载数据。用户登录后就会始终处于登录状态,除非用户被动登出或间断7天未拜访网站才会要求从新登录。 后端大体流程用户通过浏览器输出账号密码进行登录后盾java程序认证胜利后通过Http Header 返回 accessToken、refreshToken、tokenRefreshed(boolean)accessToken 有效期2小时,次要用于拜访须要认证受权的接口(如果有效期太长,有期限其用户权限等信息发生变化后无奈及时反映到token中)refreshToken 有效期7天,其惟一的作用就是再accessToken过期后,用户能够在不必从新登录的状况下换取新的accessTokentookenRefreshed 告知客户端Token是否已刷新,如果为true客户端必须存储新的Token后盾每次收到Jwt的认证申请时都会判断accessToken是否快过期(此时的accessToken还未过期,还是无效的,如果过期了就会发送认证失败的Response给客户端)。如果快过期了,将主动创立新的accessToken、refreshToken放入Http Header中,随本次申请的后果一起返回给客户端前端计划在介绍前端计划前,先简略说下用户拜访须要权限认证的两种不同状况: 1、用户间接在浏览器地址栏中输出链接或点击一个一般 <a> 标签的链接。2、用户点击<nuxt-link>形式构建的链接 第一种状况的 Http 申请由浏览器主动构建,首先发送到部署Nuxt的Node服务器上(SSR的Server端),而后再Server端构建Nuxt及Vuex相干对象,此时是获取不到保留再客户端(浏览器)中Token信息的。浏览器在未收到响应之前,浏览器中没有任何Nuxt或Vuex相干的实例对象(不能进行任何JS操作)。此时如果想携带保留在客户端的Token信息,只能通过Cookie实现(浏览器在发送Http申请时会主动带上客户端的Cookie信息) 第二种状况的路由跳转是在客户端进行的,真正发送HTTP申请个别都是在程序中通过Axios构建,而后再发送到部署Nuxt的Node服务端。因而,在发送申请前能够不便获取到Vuex、Localstorage、Cookie等任何地位保留的Token信息,而后增加到Request中发送到Server端。 这两种状况的次要区别在于,如何携带认证所需的Token。这两种状况是上面两种计划都要思考的,因为第二种状况限度少,次要思考第一种状况中的限度。 计划一 应用 Nuxt 提供的middleware性能实现中间件(middleware)容许定义一个自定义函数运行在一个页面或一组页面渲染之前,因而,能够在每次拜访页背后都先判断accessToken是否已过期,如果已过期,则刷新token。 middleware 的具体用法可参考官网文档。 用户在浏览器中执行登录认证后,通过Axios的Response拦截器将获取到的 accessToken、refreshToken, 存储在Vuex中。应用vuex-persistedstate将Vuex中的Token信息长久化到Cookie中,且只能存在Cookie中。否则无奈解决下面第一种状况中的限度。创立一个refreshToken.js的 middleware 配置在须要Token认证的页面(能够全局配置,也能够独自配置某些页面)在Nuxt的页面组件中提供的syncData或fetch办法中执行加载数据的申请外围代码如下: 第一步:创立refreshToken中间件,并配置 // refreshToken.jsimport { decode } from 'js-base64';import {isEmpty} from "@/plugins/common-util";// 间隔token过期工夫提前2分钟刷新token,避免客户端与服务端时间差const DISTANCE_EXP_TIME = 2 * 60;export default async function ({store, app, req}){ //1、获取cookie或vuex中的accessToken let accessToken = ''; if(process.server){ //这种就是间接再浏览器中输出url的,再服务端进行刷新token的状况 if(isEmpty(req.headers.Authorization)){ let cookie = req.headers.cookie if(cookie != null && cookie !== '' && cookie){ cookie = cookie.split('=') if(cookie.length === 2){ let cookieValue = JSON.parse(decodeURIComponent(cookie[1])) accessToken = cookieValue.user.accessTokenStr; } } } }else { //这种客户端渲染的状况浏览器中有残缺的VUE VUEX之类的js对象,能够间接获取 accessToken = store.state.user.accessTokenStr } //2、判断是否须要刷新token if(needRefreshToken(accessToken)){ //3、刷新token let bundle = await app.$userSecurity.refreshToken() // 此处和axios插件中任选一个中央更新token即可 //store.commit('user/setToken', bundle); }else { console.log('--->> 不须要刷新token') }}// 判断accessToken是否须要刷新function needRefreshToken(accessToken){ if(accessToken){ let payload = accessToken.split('.')[1] payload = decode(payload) payload = JSON.parse(payload) let exp = payload.exp let time = Math.round(new Date().getTime()/1000) if((exp - time) <= DISTANCE_EXP_TIME){ return true } } return false}// nuxt.config.js中全局配置 refreshToke 中间件,// 全局配置后每个页面组件渲染前都会执行 refreshToken中间件router: { middleware: 'refreshToken'}第二步:再@nuxtjs/axios插件的Response拦截器中解决HttpResponse中携带的新token ...

September 27, 2020 · 3 min · jiezi

提高首页访问速度-and-记录一次Nuxt天坑

起因将整个博客用 Nuxt 重构完成之后我发现首页访问速度还是不尽人意,白屏时间确实大大缩短,但是背景出现到最近文章出现这中间还是有比较长的一段时间, 也就是说第一次网络请求比较慢,那有没有办法解决呢,首先我就想到使用 「CDN」。 CDN 加速CDN 的全称为内容分发网络,通俗的来说就是把网站内容给复制到全国各个地方的节点上去,用户访问就从最近的节点拿,于是用腾讯云将我的网站添加进了腾讯云的 CDN 。但是访问速度并没有肉眼可见的提升,这是为什么呢,我进行了一番思考。 制约我网站首页加载速度的已经不是首页白屏了,而是第一次请求最近文章,即使使用了 CDN 提升了打开网站的速度,但是浏览器得到网页之后请求最近文章还是受制于我的服务器,既然这样的话能不能把最近文章在服务器端渲染好然后再一起浏览器,两次请求就变为了一次,相当于首页就变成了静态页面,CDN 也能够缓存到最近文章数据。 二话不说开始翻文档,果然主打服务端渲染的 Nuxt 扩展了 Vue.js,增加了一个叫 「asyncData」 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。 使用 asyncData 方法通俗来讲就是这个方法里的函数会在服务器里面的时候就被调用,而不是在用户浏览器中才被调用。这样就达到了上文所说的那种效果,第一次返回网页就已经包括了最近文章数据,代码如下 async asyncData({ $axios }) { try { let { data } = await $axios.post("/recent"); //有误 return { list: data.data }; } catch (e) { console.log(e); } },按照道理来说现在首页访问速度应该快如闪电了吧,行云流水的部署,却发现首页根本没有加载出来数据,看控制台也没有报错,咋回事?没用吗,这个请求放在 methods 是完全没问题的啊。于是开始了漫长的排错之旅。 Axios 在 asyncData 方法中使用问题试着用 try 捕捉了一下错误,发现这段代码是在服务端就被运行了,所以打印和报错信息都在后端显示,怪不得浏览器中一切安好。打印报错信息又被请求体中返回的网站源码覆盖看不到报错信息,找遍了百度也没有类似的解决方案,又上 Google 搜索 axios 在 asyncData 中的报错,倒是有几个,解决方法是重新定义一份 Axios 配置文件,试过之后还是无济于事。 ...

October 8, 2019 · 1 min · jiezi

Nuxtjs服务端渲染实践搭建一个blog

关于SSR的简介SSR,即服务端渲染,这其实是旧事重提的一个概念,我们常见的服务端渲染,一般见于后端语言生成的一段前端脚本,如:php后端生成html+jsscript内容传递给浏览器展现,nodejs在后端生成页面模板供浏览器呈现,java生成jsp等等。 Vuejs、Reactjs、AngularJs这些js框架,原本都是开发web单页应用(SPA)的,单页应用的好处就是只需要初次加载完所有静态资源便可在本地运行,此后页面渲染都只在本地发生,只有获取后端数据才需要发起新的请求到后端服务器;且因为单页应用是纯js编写,运行较为流畅,体验也稍好,故而和本地原生应用结合很紧密,有些对页面响应流畅度要求不是特别苛刻的页面,用js写便可,大大降低了app开发成本。 然而单页应用并不支持良好的SEO,因为对于搜索引擎的爬虫而言,抓取的单页应用页面源码基本上没有什么变化,所以会认为这个应用只有一个页面,试想一下,一个博客网站,如果所有文章被搜索引擎认为只有一个页面,那么你辛辛苦苦写的大多数文章都不会被收录在里面的。 SSR首先解决的就是这个问题,让人既能使用Vuejs、Reactjs来进行开发,又能保证有良好的SEO,且技术路线基本都是属于前端开发栈序列,语言语法没有多大变化,而搭载在Nodejs服务器上的服务端渲染又可以有效提高并发性能,一举多得,何乐而不为? ps:当然,目前某些比较先进的搜索引擎爬虫已经支持抓取单页应用页面了,比如谷歌。但并不意味着SSR就没用了,针对于资源安全性要求比较高的场景,搭载在服务器上的SSR有着天然的优势。关于Nuxtjs这里是官方介绍,Nuxtjs是诞生于社区的一套SSR解决方案,是一个比较完备的Vuejs服务端渲染框架,包含了异步数据加载、中间件支持、布局支持等功能。 关于nuxtjs,你必须要掌握以下几点知识: vuejs、vue-router、vuex等nodejs编程webpack构建前端工程babel-loader如果想使用进程管理工具,推荐使用pm2管理nodejs进程,安装方式为:npm install -g pm2搭建一个blog准备好工具推荐下载 这里iview将作为一个插件在nuxtjs项目中使用。 注意几个配置:nux.config.js module.exports = { /* ** Headers of the page */ head: { title: '{{ name }}', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: '{{escape description }}' } ], link: [ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } ] }, plugins: [ {src: '~plugins/iview', ssr: true} ], /* ** Customize the progress bar color */ loading: { color: '#3B8070' }, /* ** Build configuration */ build: { /* ** Run ESLint on save */ extend (config, { isDev, isClient }) { if (isDev && isClient) { config.module.rules.push({ enforce: 'pre', test: /\.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules)/ }) } } }}plugins文件夹下,加入iview.js ...

July 11, 2019 · 6 min · jiezi

基于Vue-SEO的四种方案

前言:众所周知,Vue SPA单页面应用对SEO不友好,当然也有相应的解决方案,下面列出几种最近研究和使用过的SEO方案,SRR和静态化基于Nuxt来说。 1.SSR服务器渲染;2.静态化;3.预渲染prerender-spa-plugin;4.使用Phantomjs针对爬虫做处理。1.SSR服务器渲染关于服务器渲染:Vue官网介绍,对Vue版本有要求,对服务器也有一定要求,需要支持nodejs环境。 使用SSR权衡之处: 开发条件所限,浏览器特定的代码,只能在某些生命周期钩子函数 (lifecycle hook) 中使用;一些外部扩展库 (external library) 可能需要特殊处理,才能在服务器渲染应用程序中运行;环境和部署要求更高,需要Node.js server 运行环境;高流量的情况下,请准备相应的服务器负载,并明智地采用缓存策略。优势: 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面;更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。不足:(开发中遇到的坑)1.一套代码两套执行环境,会引起各种问题,比如服务端没有window、document对象,处理方式是增加判断,如果是客户端才执行: if(process.browser){ console.log(window);}引用npm包,带有dom操作的,例如:wowjs,不能用import的方式,改用: if (process.browser) { var { WOW } = require('wowjs'); require('wowjs/css/libs/animate.css'); }2.Nuxt asyncData方法,初始化页面前先得到数据,但仅限于页面组件调用: // 并发加载多个接口: async asyncData ({ app, query }) { let [resA, resB, resC] = await Promise.all([ app.$axios.get('/api/a'), app.$axios.get('/api/b'), app.$axios.get('/api/c'), ]) return { dataA: resA.data, dataB: resB.data, dataC: resC.data, } }在asyncData中获取参数: 1.获取动态路由参数,如:/list/:id' ==> '/list/123接收:async asyncData ({ app, query }) { console.log(app.context.params.id) //123}2.获取url?获取参数,如:/list?id=123接收:async asyncData ({ app, query }) { console.log(query.id) //123}3.如果你使用v-if语法,部署到线上大概也会遇到这个错误: ...

June 30, 2019 · 2 min · jiezi

记录使用Nuxt开发服务端渲染项目时遇到的问题难点整理不定时更新

因为公司官网SEO优化问题,必须要用服务端渲染,prerender-spa-plugin预渲染插件不能满足需求。在此记录整理,Nuxt开发服务端渲染项目时遇到的问题难点(不定时更新)1、掘金上有一些很不错的Nuxt教程文章,推荐几篇:https://juejin.im/post/58ff96...https://juejin.im/post/5bd3fb...https://juejin.im/post/5cc81e...https://www.jianshu.com/p/840... 2、在使用window对象时,页面有时会报错window is not defined,解决方法: //用process.client判断是否客户端,包着window对象的代码就行if (process.client) {}3、vue-cli创建的项目,即客户端渲染,在详情页类型的文章页面中,如果右侧列表有同类型的文章,那么在点击跳转路由时,需要用到beforeRouteUpdate,判断from来源是不是本路由,是的话则把详情id更新为to路由对象里的id即可,参考Vue Router官方文档:https://router.vuejs.org/zh/g... //我的代码是这样beforeRouteUpdate(to, from, next){ next(); // console.log(to, from, next) if(from.path.indexOf('NewsDetails') != -1){ this.newsId = to.params.newsId; //更新新闻资讯详情数据 this.getNewsDetailsData(); }},而Nuxt服务端渲染的项目,我做到这个功能点时,发现不需要写beforeRouteUpdate路由钩子,处理判断,页面也能正常跳转展示正确的数据。

June 26, 2019 · 1 min · jiezi

绳命在于折腾我用-Nuxtjs-重构了博客

其实自己的博客上线没多久,之前闲时会写些乱七八糟的玩意儿,一来当作总结和备忘,二来分享一些个人经验,也是种很有趣的经历。然后几个月前,想着自己手里有个注册但闲置很久的域名,又正好有台服务器,就干脆折腾个博客。 不就是个博客嘛?能有多难?也没多想就用了之前使用过的 Hexo 撸了起来,只花了一晚上就弄上线了。不过上线一时爽,维护火葬场。之后花上它上面的时间要远多于此,因为 hexo 如果想要充分的自定义模板或者功能,还是很麻烦的,特别是因为模板用的 pug 以及写样式用的 stylus 都是自己不擅长且不太喜欢的语言。几番折腾下来总不得劲,终于心一横,不如重构吧。 重构时要比当初选择 hexo 时要谨慎多了,对比了下自己了解的一些工具,最终选择了 Nuxt.js。 为什么是 Nuxt.js?最主要的原因就是自己用 Vue 很久了,学 Nuxt 的成本也就小得多。Nuxt 可以让我用最熟悉的姿势来写代码,同时又能解决博客在静态化、SEO 等方面的一些要求,它的布局、自动路由、插件、中间件等特性让我大有相见恨晚的感觉。 其实在作决定之前也试过 Vuepress,但 Vuepress 的出发点是文档类的站,并不太适合写博客。虽然 1.0 版中加入了博客的支持,但目前仍在 alpha 阶段,体验不太好,更新进度又不理想,等到正式稳定可用的版本出来,估计黄花菜也凉了。 此外也考虑过用 hugo,甚至想过用 Laravel 来弄。但 hugo 基于 Go,自己完全不懂,而用 Laravel 写博客似乎大材小用了,毕竟我只需要一个静态的小站,也不会给服务器增加多少压力。 具体实施创建 nuxt 项目并进行基础配置首先当然是创建项目,根据 Nuxt 文档使用 yarn create nuxt-app 命令创建一个新项目,根据需要配置好 eslint、typescript 等。 确定目录结构(路由)、文章文件名命名规范 因为之前用 hexo 部署的也是纯静态的站,只要之前所部署的旧文件不删除,那么使用原来的链接仍然能访问旧版的文章。所以也不用太纠结重构后路由的变化。当然这并不意味着不需要进行规划。 为此,我新建了一个 posts 目录,用于保存 markdown 文件,文件夹内建与 markdown 文件同名的文件夹用来存文章中用到的图片等。 -| posts/----| hello-中国/----| hello-中国.md这里要注意一下的是,文件名将一些特殊字符和空格替换成了连词符,而实际访问用的路由是将文件名拼音化。为什么不直接用拼音化文件名或者英文呢?主要是方便日后管理。然后在 pages 目录下创建 psots/_slug.vue 页面。这样文章就可以用 https://tianyong90.com/psots/... 这样形式来访问了。 ...

May 26, 2019 · 2 min · jiezi

HTML-转-PDF-图文报表实践

导出 PDF 图文报表实践 方法一: jsPDF使用 jsPDF 时,需要注意的是其默认单位为 mm,需要在 new jsPDF() 时传入配置 const doc = new jsPDF({ unit: 'px', format: 'a4'})这个方法废了。这个鬼东西多行文本和多个图片,简直要人命! 方法二: wkhtmltopdf Vue SSR使用 Vue.js ,需要 SSR 支持,否则页面为空白 使用 Nuxt.js 作为服务端渲染框架,这里记录一下遇到的问题和解决方案 1. 使用 Element UI,启动就报错 HTMLElement is not definedElement UI 版本问题,使用最新的 2.8.x 会出现问题,则需要降版本并在 package.json 中配置版本策略,仅更新小版本范围 "element-ui": "~2.4.11",参考资料:https://github.com/ElemeFE/element/issues/15261 2. JS的兼容问题在使用 wkhtmltopdf 时,提示报错:Warning: http://localhost:3000/_nuxt/vendors.app.js:1941 SyntaxError: Parse error,估计是 ES6 的语法在wkhtmltopdf 的运行环境当中不支持,导致出现了这些错误提示。 官方Nuxt.js 2.6.X 版本其实给了 babel 的配置,默认会自动根据浏览器的运行环境做代码兼容,并不需要以下的这些设置(下面只是自己的实践过程,供参考),请直接使用第3点的解决方法。 ...

May 22, 2019 · 2 min · jiezi

服务端预渲染之Nuxt - (爬坑篇)

Nuxt是解决SEO的比较常用的解决方案,随着Nuxt也有很多坑,每当突破一个小技术点的时候,都有很大的成就感,在这段时间里着实让我痛并快乐着。在这里根据个人学习情况,所踩过的坑做了一个汇总和总结。Nuxt开发跨域项目可以使用Nginx来反向代理,将外来的请求(这里也注意下将Linux的防火墙放行相应端口)转发的内部Nuxt默认的3000端口上,最简单的配置文件如下:nuxtjs.config.js{ modules: [ ‘@nuxtjs/axios’, ‘@nuxtjs/proxy’ ], proxy: [ [ ‘/api’, { target: ‘http://localhost:3001’, // api主机 pathRewrite: { ‘^/api’ : ‘/’ } } ] ]}@nuxtjs/proxy需要手动单独安装。Nuxt Store 使用在Nuxt中使用Vuex跟传统在Vue中使用Vuex还不太一样,首先Nuxt已经集成了Vuex,不需要我们进行二次安装,直接引用就好,在默认Nuxt的框架模板下有一个Store的文件夹,就是我们用来存放Vuex的地方。Nuxt官方也提供了相关文档,可以简单的过一下,但是官方文档我看来比较潦草。根据官方文档在store文件下面创建两个.js文件,分别是index.js和todo.js。并在pages文件夹下面创建index.vue。store - index.jsexport const state = () => ({ counter: 0})export const mutations = { increment (state) { state.counter++ }}store - todo.jsexport const state = () => ({ list: []})export const mutations = { add (state, text) { state.list.push({ text: text, done: false }) }, remove (state, { todo }) { state.list.splice(state.list.indexOf(todo), 1) }, toggle (state, todo) { todo.done = !todo.done }}pages - index.vue<template> <section class=“container”> <div> <h2 @click="$store.commit(‘increment’)">{{counter}}</h2> <ul> <li v-for="(item,index) of list" :key=“index”>{{item.text}}</li> </ul> </div> </section></template><script>import Logo from ‘/components/Logo.vue’import {mapState} from “vuex”;export default { components: { Logo }, computed:{ …mapState([“counter”]), …mapState(“todos”,{ list:state => state.list }) }, created(){ for(let i =0;i<10;i++){ this.$store.commit(“todos/add”,i); } console.log(this.list) }}</script>在Nuxt中可以直接使用this.$store,并且是默认启用命名空间的。再看一下computed中的代码,在使用mapState的时候,counter属性是直接获取出来的,然而todos属性则是通过命名空间才获取到的。这又是怎么回事?Nuxt把store中的index.js文件中所有的state、mutations、actions、getters都作为其公共属性挂载到了,store实例上,然而其他的文件则是使用的是命名空间,其对应的命名空间的名字就是其文件名。运行项目的时候可以在.nuxt文件夹内找到store.js看下是怎么完成的。简单的解释一下代码作用,以及做什么用的。.nuxt - store.js// 引入vueimport Vue from ‘vue’// 引入vueximport Vuex from ‘vuex’// 作为中间件Vue.use(Vuex)// 保存console 函数const log = console// vuex的属性const VUEX_PROPERTIES = [‘state’, ‘getters’, ‘actions’, ‘mutations’]// store属性容器let store = {}// 没有返回值的自执行函数void (function updateModules() { // 初始化根数据,也就是上面所说的index文件做为共有数据 store = normalizeRoot(require(’@/store/index.js’), ‘store/index.js’) // 如果store是函数,提示异常,停止执行 if (typeof store === ‘function’) { // 警告:经典模式的商店是不赞成的,并将删除在Nuxt 3。 return log.warn(‘Classic mode for store is deprecated and will be removed in Nuxt 3.’) } // 执行存储模块 // store - 模块化 store.modules = store.modules || {} // 解决存储模块方法 // 引入todos.js 文件,即数据 // ’todos.js’ 文件名 resolveStoreModules(require(’@/store/todos.js’), ’todos.js’) // 如果环境支持热重载 if (process.client && module.hot) { // 无论何时更新Vuex模块 module.hot.accept([ ‘@/store/index.js’, ‘@/store/todos.js’, ], () => { // 更新的根。模块的最新定义。 updateModules() // 在store中触发热更新。 window.$nuxt.$store.hotUpdate(store) }) }})()// 创建store实例// - 如果 store 是 function 则使用 store// - 否则创建一个新的实例export const createStore = store instanceof Function ? store : () => { // 返回实例 return new Vuex.Store(Object.assign({ strict: (process.env.NODE_ENV !== ‘production’) }, store))}// 解决存储模块方法// moduleData - 导出数据// filename - 文件名function resolveStoreModules(moduleData, filename) { // 获取导出数据,为了解决es6 (export default)导出 moduleData = moduleData.default || moduleData // 远程store src +扩展(./foo/index.js -> foo/index) const namespace = filename.replace(/.(js|mjs|ts)$/, ‘’) // 空间名称 const namespaces = namespace.split(’/’) // 模块名称(state,getters等) let moduleName = namespaces[namespaces.length - 1] // 文件路径 const filePath = store/${filename} // 如果 moduleName === ‘state’ // - 执行 normalizeState - 正常状态 // - 执行 normalizeModule - 标准化模块 moduleData = moduleName === ‘state’ ? normalizeState(moduleData, filePath) : normalizeModule(moduleData, filePath) // 如果是 (state,getters等)执行 if (VUEX_PROPERTIES.includes(moduleName)) { // module名称 const property = moduleName // 存储模块 // 获取存储模块 const storeModule = getStoreModule(store, namespaces, { isProperty: true }) // 合并属性 mergeProperty(storeModule, moduleData, property) // 取消后续代码执行 return } // 特殊处理index.js // 模块名称等于index const isIndexModule = (moduleName === ‘index’) // 如果等于 if (isIndexModule) { // 名称空间弹出最后一个 namespaces.pop() // 获取模块名称 moduleName = namespaces[namespaces.length - 1] } // 获取存储模块 const storeModule = getStoreModule(store, namespaces) // 遍历 VUEX_PROPERTIES for (const property of VUEX_PROPERTIES) { // 合并属性 // storeModule - 存储模块 // moduleData[property] - 存储模块中的某个属性数据 // property - 模块名称 mergeProperty(storeModule, moduleData[property], property) } // 如果moduleData.namespaced === false if (moduleData.namespaced === false) { // 删除命名空间 delete storeModule.namespaced }}// 初始化根数据// moduleData - 导出数据// filePath - 文件路径function normalizeRoot(moduleData, filePath) { // 获取导出数据,为了解决es6 (export default)导出 moduleData = moduleData.default || moduleData // 如果导入的数据中存在commit方法,则抛出异常 // - 应该导出一个返回Vuex实例的方法。 if (moduleData.commit) { throw new Error([nuxt] ${filePath} should export a method that returns a Vuex instance.) } // 如果 moduleData 不是函数,则使用空队形进行合并处理 if (typeof moduleData !== ‘function’) { // 避免键入错误:设置在覆盖顶级键时只有getter的属性 moduleData = Object.assign({}, moduleData) } // 对模块化进行处理后返回 return normalizeModule(moduleData, filePath)}// 正常状态// - 模块数据// - 文件路径function normalizeState(moduleData, filePath) { // 如果 moduleData 不是function if (typeof moduleData !== ‘function’) { // 警告提示 // ${filePath}应该导出一个返回对象的方法 log.warn(${filePath} should export a method that returns an object) // 合并 state const state = Object.assign({}, moduleData) // 以函数形式导出state return () => state } // 对模块化进行处理 return normalizeModule(moduleData, filePath)}// 对模块化进行处理// moduleData - 导出数据// filePath - 文件路径function normalizeModule(moduleData, filePath) { // 如果module数据的state存在并且不是function警告提示 if (moduleData.state && typeof moduleData.state !== ‘function’) { // “state”应该是返回${filePath}中的对象的方法 log.warn('state' should be a method that returns an object in ${filePath}) // 合并state const state = Object.assign({}, moduleData.state) // 覆盖原有state使用函数返回 moduleData = Object.assign({}, moduleData, { state: () => state }) } // 返回初始化数据 return moduleData}// 获取store的Model// - storeModule store数据模型// - namespaces 命名空间名称数组// - 是否使用命名空间 默认值 为falsefunction getStoreModule(storeModule, namespaces, { isProperty = false } = {}) { // 如果 namespaces 不存在,启动命名空间,命名空间名称长度1 if (!namespaces.length || (isProperty && namespaces.length === 1)) { // 返回model return storeModule } // 获取命名空间名称 const namespace = namespaces.shift() // 保存命名空间中的数据 storeModule.modules[namespace] = storeModule.modules[namespace] || {} // 启用命名空间 storeModule.modules[namespace].namespaced = true // 添加命名数据 storeModule.modules[namespace].modules = storeModule.modules[namespace].modules || {} // 递归 return getStoreModule(storeModule.modules[namespace], namespaces, { isProperty })}// 合并属性// storeModule - 存储模块// moduleData - 存储模属性数据// property - 模块名称function mergeProperty(storeModule, moduleData, property) { // 如果 moduleData 不存在推出程序 if (!moduleData) return // 如果 模块名称 是 state if (property === ‘state’) { // 把state数据分到模块空间内 storeModule.state = moduleData || storeModule.state } else { // 其他模块 // 合并到对应的模块空间内 storeModule[property] = Object.assign({}, storeModule[property], moduleData) }}以上就是编译后的store文件,大致的意思就是对store文件进行遍历处理,根据不同的文件使用不同的解决方案,使用命名空间挂载model。页面loadingNuxt有提供加载Loading组件,一下是配置。nuxtjs.config.jsmodule.exports = { loading: { color: ‘#3B8070’ }}Nuxt提供的loading不能满足项目需求,可能有的项目不需要这样加载动画,so,就需要自己手动配置一个。添加一个loading组件 (官方示例如下,详情可看官方文档)引用该组件。nuxtjs.config.jsmodule.exports = { loading: ‘~components/loading.vue’}一个小插曲在Nuxt中,~与@都指向的是根目录。components/loading.vue<template lang=“html”> <div class=“loading-page” v-if=“loading”> <p>Loading…</p> </div></template><script>export default { data: () => ({ loading: false }), methods: { start () { this.loading = true }, finish () { this.loading = false } }}</script>第三方组件库项目开发过程中,难免会用到组件库,与在Vue中使用的时候是太一样的,需要添加一些依赖才能正常使用。plugins - element-ui.jsimport Vue from ‘vue’;import Element from ’element-ui’;import locale from ’element-ui/lib/locale/lang/en’;export default () => { Vue.use(Element, { locale })};nuxtjs.config.jsmodule.exports = { css: [ ’element-ui/lib/theme-chalk/index.css’ ], plugins: [ ‘@/plugins/element-ui’, ‘@/plugins/router’ ]};使用中间件中间件Nuxt没有给出具体的使用文档,而是放入了一个编辑器。这一点我感觉到了一丝丝的 差异。为什么要这样。。。简单的研究了一下,弄明白了大概。在middleware中创建想要的中间件。这里借用一下官网的例子。middleware - visits.jsexport default function ({ store, route, redirect }) { store.commit(‘ADD_VISIT’, route.path)}向上面这样就创建好了一个中间件,但是应该怎么使用呢?在使用的时候有两种方式,一种是全局使用,另一种是在页面中单独使用,文件名会作为其中间件的名称。++全局使用++nuxtjs.config.jsexport default { router: { middleware: [‘visits’] }}页面中单独使用export default { middleware: ‘auth’}官网中在页面中的asyncData中有一段这样的代码。export default { asyncData({ store, route, userAgent }) { return { userAgent } }}持续更新。。。总结Nuxt的学习曲线非常小,就像Vue框架一样,已经是一个开箱即用的状态,我们可以直接跨过配置直接开发。对配置有兴趣的可以在Vue官方文档找到SSR渲染文档。 ...

April 20, 2019 · 5 min · jiezi

解决liunx系统,项目nuxt2.0运行npm run dev / start报错问题

npm run dev 运行nuxt2.0项目时,报错:查看了下core-js3.0.0安装包,发现里面modules的名称修改为es.,而不是es6. ERROR Failed to compile with 45 errors friendly-errors 16:02:13These dependencies were not found: friendly-errors 16:02:13 friendly-errors 16:02:13* core-js/modules/es6.array.find in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.array.find-index in ./node_modules/_babel-loader@8.0.5@babel-loader/li b??ref--2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader-options!./pages/ind ex.vue?vue&type=script&lang=js&* core-js/modules/es6.array.iterator in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.date.to-string in ./.nuxt/utils.js, ./node_modules/_babel-loader@8.0.5 @babel-loader/lib??ref–2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader-opt ions!./components/upload.vue?vue&type=script&lang=js& and 1 other* core-js/modules/es6.function.name in ./.nuxt/client.js, ./node_modules/_babel-loader@8.0.5 @babel-loader/lib??ref–2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader-opt ions!./components/upload.vue?vue&type=script&lang=js& and 1 other* core-js/modules/es6.number.constructor in ./node_modules/_babel-loader@8.0.5@babel-loader/ lib??ref--2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader-options!./compone nts/upload.vue?vue&type=script&lang=js&* core-js/modules/es6.object.assign in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.object.keys in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.object.to-string in ./.nuxt/client.js, ./node_modules/_babel-loader@8. 0.5@babel-loader/lib??ref–2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader- options!./components/upload.vue?vue&type=script&lang=js& and 3 others* core-js/modules/es6.promise in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.regexp.constructor in ./.nuxt/utils.js friendly-errors 16:02:13* core-js/modules/es6.regexp.match in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.regexp.replace in ./.nuxt/utils.js, ./node_modules/_babel-loader@8.0.5 @babel-loader/lib??ref–2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader-opt ions!./pages/login.vue?vue&type=script&lang=js& and 1 other* core-js/modules/es6.regexp.search in ./.nuxt/utils.js friendly-errors 16:02:13* core-js/modules/es6.regexp.split in ./.nuxt/utils.js friendly-errors 16:02:13* core-js/modules/es6.regexp.to-string in ./.nuxt/utils.js, ./node_modules/_babel-loader@8.0 .5@babel-loader/lib??ref–2-0!./node_modules/_vue-loader@15.7.0@vue-loader/lib??vue-loader-o ptions!./components/upload.vue?vue&type=script&lang=js& and 1 other* core-js/modules/es6.string.includes in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.cli ent.js and 1 other* core-js/modules/es6.string.iterator in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es6.string.link in ./plugins/marked.js friendly-errors 16:02:13* core-js/modules/es6.string.repeat in ./.nuxt/utils.js friendly-errors 16:02:13* core-js/modules/es6.string.starts-with in ./.nuxt/utils.js friendly-errors 16:02:13* core-js/modules/es6.symbol in ./.nuxt/axios.js, ./.nuxt/components/nuxt-link.client.js* core-js/modules/es7.array.includes in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.clie nt.js and 1 other* core-js/modules/es7.promise.finally in ./.nuxt/client.js friendly-errors 16:02:13* core-js/modules/es7.symbol.async-iterator in ./.nuxt/axios.js, ./.nuxt/components/nuxt-lin k.client.js* core-js/modules/web.dom.iterable in ./.nuxt/axios.js, ./.nuxt/components/nuxt-link.client. js friendly-errors 16:02:13To install them, you can run: npm install –save core-js/modules/es6.array.find core-js/modu les/es6.array.find-index core-js/modules/es6.array.iterator core-js/modules/es6.date.to-stri ng core-js/modules/es6.function.name core-js/modules/es6.number.constructor core-js/modules/ es6.object.assign core-js/modules/es6.object.keys core-js/modules/es6.object.to-string core- js/modules/es6.promise core-js/modules/es6.regexp.constructor core-js/modules/es6.regexp.mat ch core-js/modules/es6.regexp.replace core-js/modules/es6.regexp.search core-js/modules/es6. regexp.split core-js/modules/es6.regexp.to-string core-js/modules/es6.string.includes core-j s/modules/es6.string.iterator core-js/modules/es6.string.link core-js/modules/es6.string.rep eat core-js/modules/es6.string.starts-with core-js/modules/es6.symbol core-js/modules/es7.ar ray.includes core-js/modules/es7.promise.finally core-js/modules/es7.symbol.async-iterator c ore-js/modules/web.dom.iterableℹ Waiting for file changes 需要降回2.6.2版本才能正常运行npm install –save core-js@latest2.6.2 ...

March 25, 2019 · 2 min · jiezi

最终还是选择了Nuxt.js搭建个人网站

前言:目前我的网站是用的ghost博客系统搭建的,首先说一下为甚要放弃ghost放弃ghost原因自己特别喜欢的主题很少,自己去看文档写主题的成本太高(目前用的就是自己写的主题,最近觉得有点丑,meetqy-themes)想要在网站上面做扩展很难,学到一个新的东西或者技术,想要实现在网站上面很难之前我用的好像是ghost1.几的版本,后台编辑文章看着还可以,但是升级到现在的版本,后台编辑文章很丑(个人觉得)页面的拓展不容易。为什么选择Nuxt.js在选择Nuxt.js之前还是对比了很多的框架,先说一下没有选择其他的原因吧,最主要的两个:vuepress小伙伴们推荐过vuepress,并且看官网,开源博客也被列入了Todo里面,很心动,但是最终在搭建demo的时候,vuepress run dev启动总是报错,什么 res.setHeader is not function,github上面的方法都试了一次还是没有解决。最后遗憾的放弃了hexohexo放弃的主要原因就是,在自定义主题模板的时候,好像默认用的是swig,可以换成ejs和其他的。不能用hbs,放弃了最终选择Nuxt.jsnuxt.js服务器渲染的,seo很好做前端模板使用的vue,学习起来成本很低最重要的是,可扩展度很好,想怎么写怎么写。支持生成静态文件放弃ghost的理由,nuxt.js都能解决今天就开始从零开始使用Nuxt.js重新搭建自己的个人网站,后面会更新搭建的过程,以及遇到的坑。

March 25, 2019 · 1 min · jiezi

nuxt.js@2.x 项目打包时清除console、debugger、warnings

nuxt@2.4.31、安装UglifyJsPluginyarn add UglifyJsPlugin -D ornpm install UglifyJsPlugin -D 2、编辑nuxt.configconst UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’)build: { extend(config, ctx) { if(!ctx.isDev&&ctx.isClient){ config.plugins.push( new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, drop_console: true, drop_debugger:true }, }, sourceMap: true, cache: true, parallel: true }) ) } }}

March 7, 2019 · 1 min · jiezi

Travis CI 部署遇到的问题

最近研究nuxt服务端渲染的时候,看到nuxt的几种部署方式,因为nuxt打包的静态文件可以直接放在GitHub上面,然后 TravisCI跟GitHub又很亲切,就选择了TravisCI部署。然后就走上了研究TravisCI的不归路。Travis CI 部署到GitHub项目gh-pages分支上,打开页面发现引用资源404?在研究nuxt的这一篇文章 《如何部署至GitHub Pages?》的时候,所有操作都按照文章提示来,发现怎么部署都失败,然后仔细看自己页面资源引用的路径,并没有实现文章中的router base 的路径配置。router: { base: ‘/<repository-name>/’}然后自己反复上传验证,终于发现问题。在官网给出的TravisCI配置中:language: node_jsnode_js: - “8"cache: directories: - “node_modules"branches: only: - masterinstall: - npm install - npm run generate # 这个需要改为npm run generate:gh-pagesscript: - echo “Skipping tests"deploy: provider: pages skip-cleanup: true github-token: $GITHUB_ACCESS_TOKEN # Set in travis-ci.org dashboard, marked secure https://docs.travis-ci.com/user/deployment/pages/#Setting-the-GitHub-token target-branch: gh-pages local-dir: dist on: branch: master需要把install中的 npm run generate 改为npm run generate:gh-pages,这样就可以走gh-page分支的打包了。不知道是不是还有别的解决方法,刚接触也不是特别了解。Travis CI 如何部署服务器?可以参考这篇文章Travis CI 自动化部署博客Travis CI 部署服务器如何实现免密登录?搞完GitHub Pages静态部署,然后就想部署服务端,毕竟接触nuxt的目的就是实现服务端渲染。然后找了一个比较坑的文章… 每次Travis部署后,都要求输入一个密码。卡在了免密登录的地方卡了很久很久… 在此多谢 @X1nFLY 的帮忙,很耐心的帮我解决了问题。其实免密登录跟trvais并没有什么关系,原理就是私钥公钥的加密解密(有兴趣可以自行去搜索),只要你本地 ssh连接实现免密登录,那Travis部署也可以的。需要在终端输入:ssh-copy-id username@your-server-ipssh-copy-id 将本机的公钥复制到远程机器的authorized_keys文件中,ssh-copy-id也能让你有到远程机器的home, ~./ssh , 和 /.ssh/authorized_keys的权利,这时候只要你终端输入:ssh username@your-server-ip再次连接就不用再输入密码啦Travis CI 部署怎么启动 nuxt服务,node服务?下面到了最关键的时刻,部署成功后after_success:怎么处理?对于一个前端(没怎么接触过后台)来说,确实一脸懵逼,要操作 一些常用Linux命令。下面我就总结几个我碰到的:部署nuxt静态资源到服务器。因为nuxt静态资源是打包到 /dist 文件夹下的,所以我们只需要把/dist文件夹 拷贝到服务端对应的文件夹即可。after_success:- rsync -az –delete ./dist/* root@123.123.123.123:/data/html/nuxt # copy dist文件夹下的所有文件部署nuxt服务端渲染应用到服务器。打包对应文件夹是.nuxt 文件,但是需要服务端启动服务,所以需要安装各种依赖以及启动配置。所以需要将 .nuxt nuxt.config.js package.json static 文件或文件夹都拷贝到服务器上,并对其安装依赖,启动服务。after_success:- rsync -az –delete .nuxt nuxt.config.js package.json root@47.99.102.212:/data/ssr- ssh root@123.123.123.123 ‘cd /data/ssr/ && npm install && npm run start’部署node应用服务器。after_success:- ssh root@123.123.123.123 ‘cd /data/node/ && git pull && npm install && npm run prd’ ...

February 22, 2019 · 1 min · jiezi

nuxt+koa+ant-design-vue+mongoose开发的微信公众号文章管理

github欢迎star https://github.com/aoping/nux…关键词服务端渲染 微信公众号开发 nuxt koa ant-design mongoose功能介绍后台登录 注册 公众号增删改查 文章增删改查公众号自动回复 网页授权 自定义分享 设置菜单等界面展示首页登录注册页公众号管理页文章管理页移动端

February 22, 2019 · 1 min · jiezi

Nuxt.js 的一个常见错误警告

在 Nuxt.js 的使用过程中会遇到这样一种错误:[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.简单翻译成中文是:客户端呈现的虚拟DOM树与服务器呈现的内容不匹配。 这可能是由不正确的HTML标记引起的,例如在<p>中嵌套块级元素或缺少<tbody>。经调查发现原因可能有多种,故写些文字记录下来,以后发现别的再补上????。可能原因 1 - 不符合HTML规范就像警告信息中说的那样 - 由不正确的HTML标记引起的,例如在<p>中嵌套块级元素或缺少<tbody>。对于这种情况,检查下是否有这样的模板内容是否有不遵守HTML规范的写法,改正就好了,问题不大。如果是某个引入的插件导致的,自己没办法改,只能选择用<no-ssr>不让它在服务端渲染或者忽略警告。可能原因 2 - 服务端和客户端数据不一致有时候按照原因1找了很久也没能解决问题,但有其他一些怪异表现 - 列表渲染不正常:例如刚渲染完列表数量正常,加载完后数量就错了,或有数据消失了。我遇到的这种情况是我的代码不规范,更改了数据内部的结构,例如下面的代码:props: { sources: Array},computed: { formattedSources() { return this.sources.reduce((res, source) => { const urls = source.url.split(’\n’).filter(r => !!r) source.url = urls[0] res.push(source) urls.slice(1).forEach(url => { res.push({ title: url, url }) }) return res }, []) }}这段代码中source.url = urls[0]这里我改动了props里的sources内部数据,导致Nuxt.js输出数据到页面,然后在浏览器端重新加载渲染时已近和服务端渲染时的数据不一致,出现了这个错误警告。那么解决方法也有了,不要篡原数据。另外,在computed中篡改数据本来就是错误的写法????。 ...

February 19, 2019 · 1 min · jiezi

Nuxt.js 数据双向绑定

假定我们有一个需求,一开始通过mounted()将一个字符串渲染在页面上,但是我们经过操作后修改了数据并且需要将得到的结果重新异步渲染到页面中去,而不是跳转刷新页面来重新渲染首先模板中data()中定义数据,并且要将定义的数据显示出来<template> <div> <span @click=“click”>{{ text }}</span> </div></template><script> export default { data(){ return { text: ‘’, newText: ‘1’ } }, async mounted(){ let {status,data:{text}} = await self.$axios.post(’/getText’); this.text = text; } }</script>然后我们通过methods里的函数来获取后台的数据methods:{ async click(){ let {status,data:{text}} = await self.$axios.post(’/updateText’,{ text, newText }) this.text = text; } }服务端的接口如下router.get(’/getText’, async (ctx) => { let text= await Text.find(); ctx.body = { text }}router.post(’/updateText’, async (ctx) => { const {text,newText} = ctx.request.body; let oldVal = text; let newVal = newText; let ncomment = await Comment.updateOne(oldVal,newVal); let text= await Text.find(); ctx.body={ text }})这里有个重点!获取页面传过来的参数时必须使用结构赋值的方法获取,不然获取到的为一个Object,查询将会出错!双向绑定在这里的体现是:一开始通过mounted()将数据渲染到模板中,然后调用函数通过服务端的updateText接口改变数据,在updateText接口中更新完数据后,执行一遍查询,将查询结果返回到触发的函数中。并在该函数中修改data()中text的值达到数据双向绑定的效果 ...

February 16, 2019 · 1 min · jiezi

解决 宝塔 使用pm2部署nuxt2.0时,图片、css显示不出来的问题

在配置修改中,删除那几行代码即可

January 26, 2019 · 1 min · jiezi

nuxt一些知识点(待补充)

一、封装请求和发送请求1.封装axiosimport axios from ‘axios’const host = ‘http://localhost:3000’import Qs from ‘qs’var Net = { //请求问题接口 getqueslist(cp_id, c_id, type, page) { return new Promise(function(resolve, reject) { axios .get(${host}/api/question/list, { params: { cp_id, c_id, type, page } }) .then(function(res) { res.data.code == 0 ? resolve(res) : reject(‘错误:’, res.status) }) }) }, collect(user_id, q_id) { return axios.post( ${host}/api/favourite/add, Qs.stringify({ user_id, q_id }) ) },}export default Net2.组件调用接口import Net from ‘@/pages/api/net’export default { async asyncData() { let res1 = await Net.getanswerList() let res2 = await Net.getcard() let res3 = await Net.getSort() res3.data.data.splice(4, res3.data.data.length - 4) return { answerList: res1.data.data, cardList: res2.data.data[0].banner_list, sortList: res3.data.data } }}二、nuxt使用swiper<template> <div> <div class=“answerpeople”> <div class=“peoplediv” v-if=“answerList.length>0” v-swiper:mySwiper=“swiperOption”> <div class=“swiper-wrapper”> <div :key=“index” class=“swiperdiv swiper-slide” v-for="(item,index) of answerList"> <img :src=“item.headImg” alt> <p>{{item.nickname}}正在疯狂刷题中</p> </div> </div> </div> </div> </div></template><script>import Vue from ‘vue’import ‘swiper/dist/css/swiper.css’if (process.browser) { const VueAwesomeSwiper = require(‘vue-awesome-swiper/dist/ssr’) Vue.use(VueAwesomeSwiper)}export default { props: { answerList: { type: Array, required: true } }, data() { return { swiperOption: { direction: ‘vertical’, slidesPerView: 3, loop: true, observeParents: true, observer: true, autoplay: { disableOnInteraction: false, delay: 1000 } } } }}</script><style lang=“stylus” scoped>.answerpeople margin-top 0.8rem /* 30/37.5 / padding 0rem 0.533333rem / 20/37.5 / margin-bottom 2.4rem / 90/37.5 / font-size 13px .peoplediv background-image url(‘http://xd-video-pc-img.oss-cn-beijing.aliyuncs.com/xearn.png') background-repeat no-repeat background-size 100% height 3.653333rem / 137/37.5 / overflow hidden border-radius 8px .swiperdiv display flex height 0.8rem / 30/37.5 / !important padding 0.133333rem / 5/37.5 / 0rem background-color rgba(255, 255, 255, 0.73) border-radius 15px margin-bottom 5px img width 0.8rem / 30/37.5 / height 0.8rem / 30/37.5 */ border-radius 100% margin-right 5px p align-self center</style> ...

January 26, 2019 · 2 min · jiezi

nuxt中使用路由守卫

1.在plugins文件下创建一个route.jsimport { getCookie, setCookie } from ‘@/pages/logreg/api/cookie’import axios from ‘axios’export default ({ app, store }) => { app.router.beforeEach((to, from, next) => { let isClient = process.client if (isClient) { let currentUrl = location.href if (currentUrl.indexOf(‘access_token=’) !== -1) { let wechattoken = currentUrl.split(‘access_token=’)[1] wechattoken = wechattoken.split(’&’)[0] setCookie(’token’, wechattoken, 5) } let token = getCookie(’token’) if (token) { store.state.user.userinfo.token = token axios .get(‘https://api.ass.net/pub/api/user_info', { params: { token } }) .then(res => { res = res.data if (res.code == 0) { res = res.data res.headImg = res.headImg.replace(‘http:’, ‘https:’) store.state.user.userinfo = Object.assign( {}, store.state.user.userinfo, res ) } }) .catch(error => console.log(error)) } } next() })}2.在nuxt.config.js里面配置 plugins: [ { src: ‘@/plugins/route’, ssr: true } ], ...

January 26, 2019 · 1 min · jiezi

vue移动端引用第三方组件-lytab(学习笔记)

网络上有个大神自己写了一个移动端可滑动(惯性滑动&回弹)Vue导航栏组件 ly-tab然后我想把它用到我的项目中去,发现会有这个报错:SyntaxError: Unexpected token import我也不知道是哪个步骤操作不正确。我就把它的源码从node_modules文件中复制出来,放在components文件下node_modulescomponents在需要使用的组件中局部引用import LyTab from ‘@/components/Scroll’后来我发现还是报SyntaxError: Unexpected token import接着尝试把路径换成下面的就不会报错了import LyTab from ‘@/components/Scroll/src/index.vue’==========================================运用======================================<ly-tab :items=“sortList” :options=“options” class=“parent” v-model=“selected”></ly-tab>items是传递给子组件的数组options是lytab的配置export default { components: { LyTab }, data() { return { sortList: [], //父分类 i: 0, selected: 0, options: { activeColor: ‘#78d5f7’, labelKey: ’name’ // 在sortList数组中选择想要渲染的key名 } } }}后面我需要去获取点击父分类的index值从而筛选子分类,所以我需要在源码的基础添加index.vue子组件<template> <div class=“ly-tab”> <ly-tabbar v-bind=“options” v-model=“selectedId”> <ly-tab-item :key=“index” v-for="(item, index) in items"> <span slot=“icon” v-if=“options.fixBottom && item.icon”> <i :class=“item.icon”></i> </span> <span @click=“getindex(index)">{{ item[labelKey] }}</span> </ly-tab-item> </ly-tabbar> </div></template>新增getindex函数获取点击的index然后传递给父组件父组件接收<ly-tab :items=“sortList” :options=“options” @parent=“parent” class=“parent” v-model=“selected”></ly-tab><div class=“child” v-if=“sortList[i].subCategoryList.length>0”> <ul> <nuxt-link :key=“index” :to="{path: ‘/quesbank/sort’, query: {cp_id: item.pid, c_id: item.id}}” v-for="(item,index) of sortList[i].subCategoryList" > <li :class="$route.query.c_id===item.id?‘activechild’:’’" v-if=“item.name!==’’” >{{item.name}}</li> </nuxt-link> </ul></div>export default { components: { LyTab }, data() { return { sortList: [], //父分类 i: 0, selected: 0, options: { activeColor: ‘#78d5f7’, labelKey: ’name’ } } }, mounted() { if (this.$route.query.cp_id) { this.selected = Number(this.$route.query.cp_id) } }, //asyncData在服务端渲染 async asyncData() { let res = await Net.getSort() let result = res.data.data result.unshift({ name: ‘全部’, id: 0, subCategoryList: [] }) for (let i = 0; i < result.length; i++) { if (result[i].subCategoryList) { for (let j = 0; j < result[i].subCategoryList.length; j++) { result[0].subCategoryList.push(result[i].subCategoryList[j]) } } } result[0].subCategoryList.unshift({ name: ‘全部’, id: 0, pid: 0 }) return { sortList: result } }, methods: { //获取index进行子分类的筛选 parent(index) { this.i = index } }}</script>写的很乱,是自己平时项目中的小总结 ...

January 22, 2019 · 1 min · jiezi

vue 服务器端渲染 nuxt.js初探

开头还是来一段废话: 年关将近,给大家拜个早年,愿大家年会都能抽大奖,来年行大运。废话不多说,直接进正文项目环境:前端vue项目, 需要将新增的几个路由页面做seo处理。在调研 插件 prerender-spa-plugin后,发现无法满足 vuex 以及 plugins 等要求时,果断选用了 nuxt.js做服务器渲染。下面是在项目中整理的 文档 和 问题nuxt.js 是一个基于 Vue.js 的通用应用框架它预设了利用 Vue.js 开发 服务端渲染(SSR, Server Side Render) 的应用所需要的各种配置,同时也可以一键生成静态站点。值得一提的是,nuxt是基于node.js的,后端如果是其他语言时,是否考虑到再加一层node.js的合理性链接地址: https://zh.nuxtjs.org/guide/installation利用npx脚手架创建项目链接地址: https://zh.nuxtjs.org/guide/installation会提供以下选项 1. 在集成的服务器端框架之间进行选择: Express / Koa … 2. 选择您喜欢的UI框架: Bootstrap / Element UI … 3. 选择你想要的Nuxt模式 (Universal or SPA) 普通类型 / 单页应用 4. 添加 axios module 以轻松地将HTTP请求发送到您的应用程序中。 5. 添加 EsLint 以在保存时代码规范和错误检查您的代码。 6. 添加 Prettier 以在保存时格式化/美化您的代码。注意: 1. 如果项目自带分支等git信息时, 需要将npx生产的目录里面隐藏的git 文件删除 因为npx生成文件时,默认为master 分支,类似于 gitmodule 子分支性质 2. 其中第3点,选择 Universal 时 才会默认输出静态页,也就是能够seo的,当选择spa时,则无法seo 可修改 nuxt.config.js 中的配置项 mode: ‘Universal’ 来定义类型 启动项目命令: npm run dev 默认命令这时会报错,说未指定ip 什么的,需配置项: nuxt.config.js 中 server: { // port: ‘3000’, // 定义 输出端口 ,默认为3000 host:‘0.0.0.0’ // 定义 输出 ip }, 注意: 在server 目录中国的index.js中 会读取 nuxt.config.js 中的配置项,当不存在时会赋值默认值 const { host = process.env.HOST || ‘127.0.0.1’, port = process.env.PORT || 3000 // 默认配置条件下,修改此处无效 仍旧为3000端口 } = nuxt.options.server 页面上的注意点有: css 都默认加载到 页面上了; 处理方式有2种 1. 在 nuxt.config.js 文件 header 配置 link 外链这些公共样式 (下面有具体说明) 2. 在 nuxt.config.js 文件 build 配置 中 自定义文件路径 以及hash值 (下面有具体说明) 项目目录结构1. 资源目录 (assets) 用于组织未编译的静态资源如 LESS、SASS 或 JavaScript。2. 组件目录 (components) 用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目录下 Vue.js 组件, 即这些组件不会像页面组件那样有 asyncData 方法的特性。3. 布局目录 (layouts) 该目录名为Nuxt.js保留的,不可更改。 用于组织应用的布局组件。 4. 中间件目录 (middleware) 目录用于存放应用的中间件 文件名的名称将成为中间件名称(middleware/auth.js将成为 auth 中间件)。 一个中间件接收 context 作为第一个参数: 具体参考: https://zh.nuxtjs.org/guide/routing#中间件5. 页面目录 (page) 该目录名为Nuxt.js保留的,不可更改。 用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配置。 nuxt 会根据文件夹名称以及目录结构动态生产 router, 无需额外配置。6. 静态文件目录 (static) 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。 一般用于 放置公共css,以及 js 文件, 但是如果不想这些css和js走根目录的话, 需要将这些css放置到 assets中,然后在 nuxt.config.js中 配置 build 选项 下面会具体说明7. Store 目录 用于组织应用的 Vuex 状态树 文件 注意: 普通的spa 项目中抛出一个实例对象即可, store为 export default new Vuex.Store({ actions, getters, }) 这里则需要抛出一个 实例函数对象 const store = () => { return new Vuex.Store({ state, getters, mutations, actions }) } export default store8. nuxt.config.js 用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置9. package.json 省略… 别名 ~ 或 @ // src目录 ~~ 或 @@ // 根目录 默认情况下,src目录和根目录相同 页面间路由的跳转 要在页面之间使用路由,建议使用<nuxt-link> 标签。 js 中仍然可以使用 $router.push 等方法 路由跳转时的页面间过渡效果 Nuxt.js 默认使用的过渡效果名称为 page 需要在 assets/目录下创建 main.css 添加全局样式 .page-enter-active, .page-leave-active { transition: opacity .5s; } .page-enter, .page-leave-active { opacity: 0; } 然后添加到 nuxt.config.js 文件中: module.exports = { css: [ ‘assets/main.css’ ], loading: { color: ‘#2152F3’ }, } 更多过渡效果: https://zh.nuxtjs.org/guide/routing#过渡动效 头部信息 (Meta 标签 ,全局样式) nuxt.config.js 里定义应用所需的所有默认 meta 标签 head: { meta: [ { charset: ‘utf-8’ }, { name: ‘viewport’, content: ‘width=device-width, initial-scale=1’ } { hid: ‘description’, name: ‘description’, content: ’’ } ], link: [ // 这里可以引用全局的样式,但是会默认走根目录 { rel: ‘stylesheet’, href: ‘https://fonts.googleapis.com/css?family=Roboto’ } { rel: ‘stylesheet’, href: ‘~/static/common.js’ } // 文件一般都放在static目录下 ] } 具体参考:https://zh.nuxtjs.org/api/configuration-head异步数据 (asyncData方法,限于page页面组件,components中不适用) 这里包括 asyncData钩子 / fetch 钩子 / 。。。 【fetch】 用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据 【asyncData】 主要用于请求ajax 填充data中的数据 每次加载之前被调用。它可以在服务端或路由更新之前被调用。 asyncData ({ params }) { return axios.get(https://my-api/posts/${params.id}) .then((res) => { // 赋值给页面 data中的数据 return { title: res.data.title } }) } 或者变换为同步请求 async asyncData() { let formData = {} let ajaxData = await axios({ method: “post”, url: url, data: qs.stringify(formData), retryDelay : 1000, withCredentials : true, responseType : ‘json’, timeout : 60000, ‘Content-Type’ : ‘application/x-www-form-urlencoded’ }) } 注意添加 catch 注意: 这个异步请求函数, 第一次执行环境为node环境中,也就是服务器端,后续刷新页面则执行环境为client 客户端 本地开发时,如果在客户端直接请求完整路径时会经常遇到跨域问题,所以需要在 asyncData 中区分环境变量 process.env.VUE_ENV 区分 是server 还是 client 然后根据不同的环境配置不同的 url , 并且在 client时, 需要做服务器端代理请求,需要给url增加一层代理标识 例如:client环境中 url = ‘/api’ + ‘/get-user-info’; nuxt.config.js 中 /* ** 处理代理跨域问题 */ axios: { proxy: true, prefix: ‘/api’, // 增加请求标识 credentials: true, }, proxy: { ‘/api’: { // 代理地址 target: (process.env.NODE_ENV == ‘production’) ?‘http://test.’ : ‘http://www.’ , changeOrigin: true, pathRewrite: { ‘^/api’: ’’ // 将标识 替换为 ‘’ }, }, } 错误处理 : context中提供了一个 error(params) 方法,你可以通过调用该方法来显示错误信息页面。 params.statusCode 可用于指定服务端返回的请求状态码。 asyncData ({ params, error }) { return axios.get(https://my-api/posts/${params.id}) .then((res) => { return { title: res.data.title } }) .catch((e) => { error({ statusCode: 404, message: ‘Post not found’ }) }) } 第三方插件的使用 例如:element-ui 需要在 plugins/ 中 添加 element-ui.js import Vue from ‘vue’ import Element from ’element-ui/lib/element-ui.common’ import locale from ’element-ui/lib/locale/lang/en’ export default () => { Vue.use(Element, { locale }) } 在 uuxt.config.js 中 plugins: [ “/plugins/element-ui”, // {src : ‘/plugins/ga.js’ , ssr : false} 是否做ssr处理, false时为在客户端才加载 ], 这样全局就可以使用了 注意: 在使用第三方插件时需要注意 插件内部很多地方都会用到window对象,在服务端会报错,所以需要将ssr设置为false 在生产环境中, 有一些插件,在多个页面中引用,这样会造成多次加载打包的现象 所以: 在 build配置项中增加配置 build: { vendor:[‘axios’, ‘qs’], // 防止多次打包 } page 函数钩子生命周期 以及window 对象 经常会在 第三方组件或者调用的时候 遇到window对象报错问题 asyncData() { console.log(window) // 服务端报错 console.log(this) // undefined }, fetch() { console.log(window) // 服务端报错 }, created () { console.log(window) // undefined }, mounted () { console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} } css js 文件打包文件夹处理 在 uuxt.config.js 中 , 只需配置生产环境中 build: { extractCSS: { allChunks: true }, // css 独立打包 link 的形式加载 publicPath: ‘/sample/assets/’, //sample/essays 打包的默认路径为 ‘_nuxt’ 或者可以指定cdn 域名 filenames:{ // css 和 js img 打包时指定文件夹 app: ({ isDev }) => isDev ? ‘[name].js’ : ‘[chunkhash].js’, chunk: ({ isDev }) => isDev ? ‘[name].js’ : ‘[chunkhash].js’, css: ({ isDev }) => isDev ? ‘[name].js’ : ‘[contenthash].css’, img: ({ isDev }) => isDev ? ‘[path][name].[ext]’ : ‘[hash:7].[ext]’ } }, 输出 css link 路径: /sample/essays/[contenthash].css 注意: 静态资源文件路径名 不能和页面路由名称相同 publicPath 默认配置 ‘/’ 无效 部署 先 npm run build 打包 client文件和 server 文件 然后 npm runb start 启动服务器 pm2 管理 pm2 start npm –name “my-nuxt” – run start 部署时 需要注意 如果是 从其他地方重定向 到 nuxt 环境中的页面是, 需要额外配置一个 css / js 重定向路由,并且需要注意 header头部信息,防止出现 css 文件返回头部信息为 Content-Type text/plain 目前项目中只运用到这么多,后续项目迁移时遇到更多的问题会做补充,如果大家遇到过其他的坑点可以在下面评论中总结出来以及解决方案文章较长,谢谢大家赏脸!感谢各位! ...

January 22, 2019 · 4 min · jiezi

vue延迟加载、懒加载(比如加载vueCropper)

服务端渲染的时候,有些组件加载时候,浏览器会报错window is not defined 或者 document is not defined比如我们在使用前端的裁剪插件 vue-cropper时,刷新时或者使用nuxt框架服务端渲染时会报这样的错!这时候我们考虑到使用懒加载,就是延迟加载:1.引入组件const vueCropper = resolve => resolve(require(‘vue-cropper’))2.使用这样刷新操作,或者使用nuxt等服务端渲染框架就没有问题了!

January 15, 2019 · 1 min · jiezi

vue服务端渲染——Nuxt.js全面配置

Nuxt.js 全面配置nuxt-config: 持续更新中其他系列★ vue-cli3 全面配置<span id=“top”>目录</span>√ 初始化项目√ 环境变量配置√ 打包分析√ 提供全局 scss 变量√ 按需引入 element-ui√ 配置 hard-source-webpack-plugin√ 去除多余 css√ Brotli 压缩<span id=“init”>☞ 初始化项目</span>npx create-nuxt-app <项目名>或npx create-nuxt-app <项目名>▲ 回顶部<span id=“env”>☞ 环境变量配置</span> 可以配置在客户端和服务端共享的环境变量module.exports = { env: { baseUrl: process.env.BASE_URL || ‘http://localhost:3000’ }} 通过以下两种方式来使用 baseUrl 变量通过 process.env.baseUrl通过 context.baseUrl,请参考context api▲ 回顶部<span id=“analyze”>☞ 打包分析</span> package.json 中添加 analyze 命令"analyze": “nuxt build –analyze” 修改 nuxt.config.jsexport default { build: { analyza: { analyzeMode: ‘static’ } }}▲ 回顶部<span id=“scss”>☞ 提供全局 scss 变量</span>方法一:npm i -S @nuxtjs/style-resourcesnpm i -D sass-loader node-sass 修改 nuxt.config.jsexport default { modules: [ ‘@nuxtjs/style-resources’, ], styleResources: { scss: ‘/assets/scss/variable.scss’ }}方法二:npm i -D nuxt-sass-resources-loader sass-loader node-sass 修改 nuxt.config.jsexport default { modules: [ [’nuxt-sass-resources-loader’, [’/assets/scss/variable.scss’]] ], styleResources: { scss: ‘~/assets/scss/variable.scss’ }}▲ 回顶部<span id=“elementui”>☞ 按需引入 element-ui</span>npm i -D babel-plugin-component// oryarn add -D babel-plugin-component 修改 nuxt.config.jsmodule.exports = { plugins: [’@/plugins/element-ui’], build: { babel: { plugins: [ [ ‘component’, { libraryName: ’element-ui’, styleLibraryName: ’theme-chalk’ } ] ] } },} 修改 plugins/element-ui.jsimport Vue from ‘vue’import { Button, Loading, Notification, Message, MessageBox} from ’element-ui’import lang from ’element-ui/lib/locale/lang/zh-CN’import locale from ’element-ui/lib/locale’// configure languagelocale.use(lang)// setVue.use(Loading.directive)Vue.prototype.$loading = Loading.serviceVue.prototype.$msgbox = MessageBoxVue.prototype.$alert = MessageBox.alertVue.prototype.$confirm = MessageBox.confirmVue.prototype.$prompt = MessageBox.promptVue.prototype.$notify = NotificationVue.prototype.$message = Message// import componentsVue.use(Button);// or// Vue.component(Button.name, Button)▲ 回顶部<span id=“hard”>☞ 配置 hard-source-webpack-plugin</span>npm i -D hard-source-webpack-plugin 修改 nuxt.config.jsmodule.exports = { build: { extractCSS: true, extend(config, ctx) { if (ctx.isDev) { config.plugins.push( new HardSourceWebpackPlugin({ cacheDirectory: ‘.cache/hard-source/[confighash]’ }) ) } } }}▲ 回顶部<span id=“removecss”>☞ 去除多余 css</span>npm i –D glob-all purgecss-webpack-plugin 若安装失败,请先用管理员身份安装以下全局依赖npm install –global windows-build-tools或yarn global add windows-build-tools 修改 nuxt.config.jsconst PurgecssPlugin = require(‘purgecss-webpack-plugin’)const glob = require(‘glob-all’)const path = require(‘path’)const resolve = dir => path.resolve(__dirname, dir);module.exports = { build: { extractCSS: true, extend(config, ctx) { if (!ctx.isDev) { config.plugins.push( new PurgecssPlugin({ paths: glob.sync([ resolve(’./pages//*.vue’), resolve(’./layouts//.vue’), resolve(’./components/**/.vue’) ]), extractors: [ { extractor: class Extractor { static extract(content) { const validSection = content.replace( /<style([\s\S]*?)</style>+/gim, "" ); return validSection.match(/[A-Za-z0-9-_:/]+/g) || []; } }, extensions: [‘vue’] } ], whitelist: [‘html’, ‘body’, ’nuxt-progress’] }) ) } } }}▲ 回顶部<span id=“brotli”>☞ Brotli 压缩</span>npm i shrink-ray-current 若安装失败,请先用管理员身份安装以下全局依赖npm install –global windows-build-tools或yarn global add windows-build-tools 修改 nuxt.config.jsexport default { render: { http2: { push: true }, compressor: shrinkRay() }}▲ 回顶部 ...

January 15, 2019 · 2 min · jiezi

解决Linux下使用pm2运行nuxt2.0,IP+端口访问不了

使用pm2运行nuxt2.0pm2 start –name ‘blog-nuxt’ npm – run start运行了nuxt的程序,然后使用IP+端口,发现访问不了。然后查看了日志,看运行是否成功宝塔查看日志查看对应进程名字blog-nuxt的日志发现运行是没问题的,但使用IP+端口就是访问不了解决方法:一: 可以使用nginx代理127.0.0.1:3000端口,进行访问.在这里不多说nginx反向代理,可以自行百度二:修改nuxt启动文件【推荐】把server/index.js,里的host修改成0.0.0.0,默认是127.0.0.1。然后在Linux重新打包运行。最后是0.0.0.0:3000,发现IP+端口是可以访问的

January 8, 2019 · 1 min · jiezi

Vue服务端渲染框架Nuxt的那些事

Vue服务端渲染框架Nuxt的那些事最近公司在重构项目,为了有利于SEO,需要使用到服务端渲染,在查阅了一番资料后选择了Nuxt.js,Nuxt.js 是一个基于 Vue.js 的通用应用框架,详情可以看官网,这里主要记录下在使用过程中遇到的问题及解决方案。 技术栈:Vue + Vue-Router + Vuex + Element-Ui + Nuxt + Axios项目构建 Nuxt.js 官方提供了脚手架「 确保安装了npx(npx在NPM版本5.2.0默认安装了)」 npx create-nuxt-app <项目名> 按照提示选择适合自己项目的配置即可 然后 npm run dev。遇到的问题 一、router自定义 发现现在很多的框架都有一套自己的路由生成规则(基于vue-router)然后在对应的目录下创建目录,即会自己生成对应的路由,如果对url的路径没有要求的这样也是可以的,如果想要自定义路由的话,就需要添加些配置。具体如下: extendRoutes (routes, resolve) { routes.push({ name: ‘father’, /** 自定义路由的name / path: ‘/father’, / 自定义路由的path / component: resolve(__dirname, ‘pages/father/index.vue’), / 组件路径 / children: [{ / 子路由配置 (其它相同) / name: ‘son’, path: ‘/son’, component: resolve(__dirname, ‘pages/son/index.vue’) }, { name: ‘daughter’, path: ‘/daughter’, component: resolve(__dirname, ‘pages/daughter/index.vue’) }] }) }对应的参考官方Nuxt.js自定义路由自定义请求头(基于axios请求的base_url修改)需求描述:公司的有正式环境和特使环境对应不同的服务器,所以需要在请求的时候添加对应的请求头,具体配置可以参考如下代码:package.json配置: “scripts”: { “dev”: “cross-env NODE_ENV=development PORT=3333 nuxt”, / 本地环境:这里给环境变量NODE_ENV指定了对应的development的值和指定了运行端口 / “build”: “cross-env NODE_ENV=online nuxt build”, / 打包:指定了环境变量的值为online / “start”: “HOST=0.0.0.0 PORT=3333 nuxt start”, / 打包:指定了环境变量的值为online 端口为3333 HOST为0.0.0.0 百度了一下, 0.0.0.0代表本机的所有ip地址,即同网段其他机器也可以访问的, 默认的127.0.0.1由于和本地ip绑定了,所以只有绑定到本机地址的服务能被同网段其他机器访问**/ “generate”: “nuxt generate”, “lint”: “eslint –ext .js,.vue –ignore-path .gitignore .”, “precommit”: “npm run lint” },axios.js配置: /** 自定义请求base_url /if (process.env.NODE_ENV === ’test’) { axios.defaults.baseURL = ‘http://test’} else if(process.env.NODE_ENV === ‘online’) { axios.defaults.baseURL = ‘http://online’} else { axios.defaults.baseURL = ‘http://127.0.0.1’}这里使用的NODE_ENV由于在nuxt.js默认就存在,所以不需要定义这个变量,如果需要声明一个不存在的环境变量,需要在nuxt.config.js里面添加如下配置/ 下面声明了一个PATH_TYPE变量,其余的不需要改变,只需要将对应的NODE_ENV改成PATH_TYPE即可 /env: { PATH_TYPE: process.env.PATH_TYPE}一定要看备注:要运行上面的示例,你需要运行npm install –save-dev cross-env 安装 cross-env。如果你在非Windows环境下开发,你可以不用安装cross-env,这时需要把 start 脚本中的cross-env去掉。 官方文档:1.主机和端口配置 2.dev属性修改打包webpack配置 nuxt.js框架默认使用过了一套配置,但是看了编译出来的源码后发现css文件全部在源码里,感觉不是很利于收缩引擎的SEO,所以自定义了打包配置,代码如下: optimization: { runtimeChunk: { name: ‘manifest’ }, splitChunks: { chunks: ‘all’, cacheGroups: { libs: { name: ‘chunk-libs’, chunks: ‘initial’, priority: -10, reuseExistingChunk: false, test: /node_modules/(.*).js/ }, styles: { name: ‘chunk-styles’, test: /.(scss|css)$/, chunks: ‘all’, minChunks: 1, reuseExistingChunk: true, enforce: true } } } }, extractCSS: true, / 将css单独打包成一个文件,默认的是全部加载到有事业 **/参考文档: 1.Nuxt.js将CSS提取到一个单独的CSS文件 2.构建配置End:杭州前端一枚:如有疑惑欢迎留言咨询或者474268433@qq.com ???????? ...

December 21, 2018 · 1 min · jiezi

Nuxt.js按需引入 emement-ui

babel-plugin-component安装依赖npm i -D babel-plugin-component// oryarn add -D babel-plugin-component修改nuxt.config.jsmodule.exports = { build: { babel: { plugins: [ [ ‘component’, { libraryName: ’element-ui’, styleLibraryName: ’theme-chalk’ } ] ] } },}修改plugins/element-ui.jsimport Vue from ‘vue’import { Pagination, Dialog, Autocomplete, Dropdown, DropdownMenu, DropdownItem, Menu, Submenu, MenuItem, MenuItemGroup, Input, InputNumber, Radio, RadioGroup, RadioButton, Checkbox, CheckboxButton, CheckboxGroup, Switch, Select, Option, OptionGroup, Button, ButtonGroup, Table, TableColumn, DatePicker, TimeSelect, TimePicker, Popover, Tooltip, Breadcrumb, BreadcrumbItem, Form, FormItem, Tabs, TabPane, Tag, Tree, Alert, Slider, Icon, Row, Col, Upload, Progress, Spinner, Badge, Card, Rate, Steps, Step, Carousel, Scrollbar, CarouselItem, Collapse, CollapseItem, Cascader, ColorPicker, Transfer, Container, Header, Aside, Main, Footer, Loading, Notification, Message, MessageBox} from ’element-ui’import lang from ’element-ui/lib/locale/lang/zh-CN’import locale from ’element-ui/lib/locale’// configure languagelocale.use(lang)// setVue.use(Loading.directive)Vue.prototype.$loading = Loading.serviceVue.prototype.$msgbox = MessageBoxVue.prototype.$alert = MessageBox.alertVue.prototype.$confirm = MessageBox.confirmVue.prototype.$prompt = MessageBox.promptVue.prototype.$notify = NotificationVue.prototype.$message = Message// import componentsVue.component(Pagination.name, Pagination)Vue.component(Dialog.name, Dialog)Vue.component(Autocomplete.name, Autocomplete)Vue.component(Dropdown.name, Dropdown)Vue.component(DropdownMenu.name, DropdownMenu)Vue.component(DropdownItem.name, DropdownItem)Vue.component(Menu.name, Menu)Vue.component(Submenu.name, Submenu)Vue.component(MenuItem.name, MenuItem)Vue.component(MenuItemGroup.name, MenuItemGroup)Vue.component(Input.name, Input)Vue.component(InputNumber.name, InputNumber)Vue.component(Radio.name, Radio)Vue.component(RadioGroup.name, RadioGroup)Vue.component(RadioButton.name, RadioButton)Vue.component(Checkbox.name, Checkbox)Vue.component(CheckboxButton.name, CheckboxButton)Vue.component(CheckboxGroup.name, CheckboxGroup)Vue.component(Switch.name, Switch)Vue.component(Select.name, Select)Vue.component(Option.name, Option)Vue.component(OptionGroup.name, OptionGroup)Vue.component(Button.name, Button)Vue.component(ButtonGroup.name, ButtonGroup)Vue.component(Table.name, Table)Vue.component(TableColumn.name, TableColumn)Vue.component(DatePicker.name, DatePicker)Vue.component(TimeSelect.name, TimeSelect)Vue.component(TimePicker.name, TimePicker)Vue.component(Popover.name, Popover)Vue.component(Tooltip.name, Tooltip)Vue.component(Breadcrumb.name, Breadcrumb)Vue.component(BreadcrumbItem.name, BreadcrumbItem)Vue.component(Form.name, Form)Vue.component(FormItem.name, FormItem)Vue.component(Tabs.name, Tabs)Vue.component(TabPane.name, TabPane)Vue.component(Tag.name, Tag)Vue.component(Tree.name, Tree)Vue.component(Alert.name, Alert)Vue.component(Slider.name, Slider)Vue.component(Icon.name, Icon)Vue.component(Row.name, Row)Vue.component(Col.name, Col)Vue.component(Upload.name, Upload)Vue.component(Progress.name, Progress)Vue.component(Spinner.name, Spinner)Vue.component(Badge.name, Badge)Vue.component(Card.name, Card)Vue.component(Rate.name, Rate)Vue.component(Steps.name, Steps)Vue.component(Step.name, Step)Vue.component(Carousel.name, Carousel)Vue.component(Scrollbar.name, Scrollbar)Vue.component(CarouselItem.name, CarouselItem)Vue.component(Collapse.name, Collapse)Vue.component(CollapseItem.name, CollapseItem)Vue.component(Cascader.name, Cascader)Vue.component(ColorPicker.name, ColorPicker)Vue.component(Transfer.name, Transfer)Vue.component(Container.name, Container)Vue.component(Header.name, Header)Vue.component(Aside.name, Aside)Vue.component(Main.name, Main)Vue.component(Footer.name, Footer)☞☞☞更多nuxt文章:揭秘vue系列☜☜☜ ...

December 18, 2018 · 1 min · jiezi

解析Nuxt.js Vue服务端渲染摸索

本篇文章主要介绍了详解Nuxt.js Vue服务端渲染摸索,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。Nuxt.js 十分简单易用。一个简单的项目只需将 nuxt 添加为依赖组件即可。Vue因其简单易懂的API、高效的数据绑定和灵活的组件系统,受到很多前端开发人员的青睐。国内很多公司都在使用vue进行项目开发,我们正在使用的简书,便是基于Vue来构建的。我们知道,SPA前端渲染存在两大痛点:(1)SEO。搜索引擎爬虫难以抓取客户端渲染的页面meta信息和其他SEO相关信息,使网站无法在搜索引擎中被用户搜索到。(2)用户体验。大型webApp打包之后的js会很庞大,于是就有了按模块加载,像require.js一样,异步请求。webpack盛行,就变成了代码分割。即便如此,受制于用户设备,页面初次渲染还是有可能很慢,白屏等待时间太长,对日益挑剔的用户群体来说,无法接受。因此,对于那些展示宣传型页面,如官网,必须进行服务端渲染(SSR)。安装 nuxt.js$ vue init nuxt-community/starter-template <你项目的名字>// 后面 安装依赖你懂的// 安装koa版本$ vue init nuxt/koa <你的项目名字>运行npm run dev应用现在运行在 http://localhost:3000注意:Nuxt.js 会监听 pages 目录中的文件变更并自动重启, 当添加新页面时没有必要手工重启应用。路由nuxt 是根据pages 目录结构生成路由配置异步数据asyncData注意必须要页面组件才能调用asyncData(就是components下是不能调用,必须路由的页面才行)异步数据beforeCreate,created注意:在任何vue组件的生命周期内,只有beforeCreate和created这两个钩子会在浏览器端和服务端均被调用;其他的钩子都只会在浏览器端调用。使用插件mint-ui首先我们需要在plugins文件夹中添加插件文件 mint-ui.jsimport Vue from “vue”;import Mint from “mint-ui”;//欢迎加入前端全栈开发交流圈一起学习交流:864305860 Vue.use(Mint);在nuxt.config.js中配置plugins字段/** * 配置第三方插件 */ plugins: [{ src: “~plugins/mint-ui”, ssr: true }], //欢迎加入前端全栈开发交流圈一起学习交流:864305860//同时nuxt还支持区分只在浏览器中运行和只在服务端运行的插件 //只在浏览器运行:配置nuxt.config.js中plugins字段,将引入的插件属性设置为ssr: false//只在服务端运行:直接在webpack打包server.bundle.js文件中,将process.SERVER_BUILD设置为true即可layout布局1.nuxt.js实现了一个新的概念,layout布局,我们可以通过layout布 局方便的实现页面的多个布局之间方便的切换。本项目中实现了三种常用的布局,即:1)两栏布局,左栏固定,右栏动态宽度;2、错误页提示,页面中间一个提示框的布局方案;3、纯白页面布局。具体开发的页面中,如果使用默认布局,则不需指定页面的布局,nuxt框架会自动对没有指定布局的页面和default布局进行关联。如果需要指定布局,则在layout字段中对布局进行指定。如图在login页面中对full布局进行了指定。结语感谢您的观看,如有不足之处,欢迎批评指正。

December 14, 2018 · 1 min · jiezi

一个开源vue网站博客,nuxt开源网站,前后端分离项目

unNue.com开媛笔记,基于nuxt ssr首屏服务器端渲染 。用于分享、记录、交流和学习,希望可以帮助到小伙伴们。同时网站在不断更新,创造属于猿(媛)的世界 -$Bao Yalong ..Let’s Go! https://unnue.com简述前端 Github地址语言:Javascript主框架:Nuxt状态管理:Vuex路由:vue-router网络请求:axios编辑器:markdown-it代码高亮:highlight.js日期处理:moment头像:gravatar第三方登录:QQ服务端 ~~ 即将开源语言:Typescript主框架:Nestjs数据库:Mysql数据库ORM:typeorm静态资源:七牛云CDN:七牛云后台管理 ~~ 暂未开源语言:Javascript前端框架:Vue后台管理UI:Element服务器系统:CentOS运行环境:Nodejs反向代理:Nginx进程管理:Pm2项目管理:Git关于服务器的部署查阅这篇文章 CentOS从零开始部署Nodejs项目预览前台后台管理最终效果: https://unnue.com

December 13, 2018 · 1 min · jiezi