论坛开发
需求
基础功能(注册、登录、发帖、评论、收藏、点赞等)搭建,需做SEO优化
技术栈
基于Vue实现服务端渲染(SSR),使网站有更好的SEO;选型:nuxt、element-ui
划重点:
Q1 安装
官网推荐安装、创建项目一体:npx create-nuxt-app <my-project>,但是安装报错。
解决:
npm install create-nuxt-app
create-nuxt-app <my-project>
Q2 vuex持久化
1.使用vuex-persistedstate、js-cookie构造插件,不稳定,时而不可用(持久化不起作用);
解决:
使用js-cookie + nuxtServerInit(/store/index.js的actions方法)
login后,将需要持久化的参数写入cookie,在nuxtServerInit中进行取出参数,使用mutations中的方法写入state
Q3 axios-headers
axios-headers中增加token认证
1.直接在axios插件中设置token,登录后需要刷新才能设置成功;
解决:
使用中间件(middleware)可行,中间件在页面渲染前执行。 增加axios.js中间件,判断server、client分别取token,并设定context.$axios.setToken(token, 'Bearer')//会设置Authorization
/middleware/axios.js
export default function({$axios,req}){
let token = null;
if(process.server){
if(req.headers.cookie){
let tokenStr = req.headers.cookie.split(';').find(c=>c.startWith('token=));
token = tokenStr.split('=')[1];
}
}else{
token = localStorage.getItem('token');
}
$axios.setToken(token, 'Bearer ') //Bearer token... 此处根据需要加前缀或不加
}
/pages/...xx.vue
//引入中间件
export default{
middleware:[ "axios" ]
}
Q4 编辑器使用
发帖/评论使用编辑器:选用vue-quill-editor
1.页面直接引入vue-quill-editor、quill-image-super-solution-module,刷新页面报错(如:document is not defined);
原因参考:blog.csdn.net/weixin_3831… (引入第三方vue插件时,即直接使用Import xxx from 'xxx',这种引入方式时,要注意,在第一次刷新页面时也会在服务端进行import,所以会导致大部分vue插件直接报错,解决办法就是:1.要么按照官方文档加载插件的方式进行操作,要么就在mounted钩子中使用动态加载,即let a = require('xxx'))
解决: 在plugins目录下增加插件,在此插件中引入,注册;之后在nuxt.config.js中配置
/plugins/vue-quill-editor.js
import Vue from 'vue'
import Quill from 'quill'
import VueQuillEditor from 'vue-quill-editor'
import {ImageExtend} from 'quill-image-super-solution-module'
Quill.register('modules/ImageExtend', ImageExtend)
Vue.use(VueQuillEditor)
/nuxt.config.js
css: ['~/assets/css/index.css',
'element-ui/lib/theme-chalk/index.css',
'quill/dist/quill.snow.css',
'quill/dist/quill.bubble.css',
'quill/dist/quill.core.css'
],
plugins:[
{ src:'@/plugins/vue-quill-editor.js', ssr: false } // 只在客户端渲染
]
/pages/.../xxx.vue
//vue文件中可直接如下使用,此时不用再引入组件(引入组件还是会报上述错误)
//注意class为quill-eitor!!!
<div class="quill-editor"
:content="posContent"
@change="onEditorChange($event)"
@ready="onEditorReady($event)"
v-quill:myQuillEditor="editorOption">
</div>
//修改帖子:onEditorReady(){this.$emit('input',this.postContent)}可用作回显
//引入照片上传监听处理函数
beforemount(){
const { QuillWatch } = require('quill-image-super-solution-module')
this.editorOption={
theme: "snow",
placeholder: "请输入...", // 修改placeholder
modules:{
ImageExtend:{
name: 'file', // upload的参数key
size: 1, //限制1M大小
accept: "image/jpg, image/png, image/gif, image/jpeg, image/bmp, image/x-icon", // 允许的图片格式
editForm(formData){ // 若有增加upload参数的需要,此处可添加到formData
formData.append('type',0)
},
action: '', // upload的api地址
... // 更多可查看https://github.com/EthanYan6/quill-image-super-solution-module
},
toolbar:{
container:[
['bold', 'italic', 'underline', 'strike'], ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'script': 'sub' }, { 'script': 'super' }], [{ 'indent': '-1' }, { 'indent': '+1' }], [{ 'direction': 'rtl' }], [{ 'size': ['small', false, 'large', 'huge'] }], [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'font': [] }], [{ 'color': [] }, { 'background': [] }], [{ 'align': [] }], ['clean'], ['link', 'image', 'video']
],
handlers:{
image: function(val){
QuillWatch.emit(this.quill.id)
}
}
}
}
}
}
editor相关配置可直接参考github,或示例: github.surmon.me/vue-quill-e…
Q5 部署注意事项
项目部署
- 准备环境:
nodejs(服务端渲染需要node环境)、pm2(node进程管理工具)、nginx(配置端口转发,nuxt项目默认启动是3000端口)
*pm2(若是内网服务器,可先在本地全局安装pm2,然后将pm2包上传到服务器,放在(你的nodejs包)/bin/node_modules/路径下,命令文件pm2放在nodejs/bin/路径下)
- 启动项目:
pm2 start .../你的项目/node_modules/nuxt/bin/nuxt.js --name package.json中的name //一定要加--name 项目名!!!,否则访问不到项目
BUG:上述启动方式,类似本地npm run dev(nuxt)并不是启动打包后的文件,并且会将dist文件删除掉。由于我是把整个项目放到了服务器,所以没发现这个问题。
解决: 修改启动命令为pm2 start npm --name package.json中的name -- run start
有关启动命令介绍,参考www.w3cschool.cn/nuxtjs/nuxt…
Q6 端口修改无效
在package.json中加config指定端口,本地启动有效,但对部署在服务器上无效 X 有效,是启动方式的问题,见Q5
Q7 _loading/sse报错
部署后,有个sse推送一直报错 GET http://XXX/_loading/sse net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK) **stackoverflow.com/questions/5…
解决:
启动项目方式的问题,见Q5
Q8 环境配置
step1.新建env.js文件
module.exports = {
dev: {
MODE: 'dev',
ENV_API: 'http://xxx'
},
sit: {
MODE: 'sit',
ENV_API: 'http://xxx'
}
}
step2.nuxt.config.js中引入
const env = require('./env')
//配置:
publicRuntimeConfig: {
axios: {
baseURL: env[process.env.MODE].ENV_API
}
},
axios: {
baseURL: env[process.env.MODE].ENV_API
},
env: {
baserUrl: env[process.env.MODE].ENV_API //.vue中有需要可使用process.env.baseUrl来获取api
}
step3.配置package.json
"scripts": {
"dev": "cross-env MODE=dev nuxt",
"sit": "cross-env MODE=sit nuxt",
"build": "cross-env MODE=dev nuxt build",
"sit:build": "cross-env MODE=sit nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
"lint": "npm run lint:js"
},
记录有误操作:
使用vuex-persistedstate、js-cookie持久化,不稳定,时而有用时而无用,如下:
import createPersistedState from 'vuex-persistedstate';
import * as Cookies from "js-cookie";
let cookieStorage = {
getItem: function(key) {
return Cookies.getJSON(key);
},
setItem: function(key, value) {
return Cookies.set(key, value, { expires: 3, secure: false });
},
removeItem: function(key) {
return Cookies.remove(key);
}
};
export default (context) => {
console.log('plugin', context)
createPersistedState({
storage: cookieStorage,
getState: cookieStorage.getItem,
setState: cookieStorage.setItem
})(context.store);
};