多人共享博客

上一个项目:仿 CNODE 社区 刚完成,感觉有点意犹未尽,对于 登录 这一块老师并没有展开,我先是用了 localStorage 自己瞎搞,跑通之后想了下,vuex 不是专门做全局状态管理的么?那么用 vuex 做登录是最合适不过的呀。于是又搜了些别人用 vuex 做登录状态管理的案例,算是搞明白了。

现在选择了若愚老师的这个项目,主要是巩固一下对 vue 的认识,同时对 vuex 做个更详细的了解。本项目做一款多人共享博客,包含首页、用户文章列表、登录、注册、个人管理、编辑、发布等功能。

测试账号: hunger10086

测试密码: 123456

实现功能:用户的登录、注册、注销

首页多人博客展示

用户博文展示

我的页面博文展示及管理

博文的创建、编辑、删除、发布

使用 Vue.js 技术栈:vue-cli / vue2 / axios / vue-router /vuex / es6 / webpack / element-ui

博客主要记录项目完成过程中学习到的知识点,其他的就一笔带过了。

项目初始化

在 vue 项目中使用 less:

如果要在某个组件中引入 less 文件,则在 style 中写入 @import '../assets/base.less'; 即可(记得 npm 装上 less 和 less-loader 哦)

ElementUI 的使用

ElementUI 的有很详细的安装使用文档

主要步骤:

1.安装 cnpm i element-ui

2.引入

import ElementUI from 'element-ui';

import 'element-ui/lib/theme-chalk/index.css';

3.挂载到 Vue Vue.use(ElementUI)

然后就可以在组件中使用 element-ui 了。

数据请求接口封装

另外,若愚老师前期还对 axios 底层请求做了进一步的定制和封装,其中一些技巧很值得学习。

1.先把 axios 请求封装成了输入参数更简洁明了、报错信息更「人性化」的 Promise 对象。

// /helpers/request.jsaxios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

axios.defaults.baseURL = 'http://blog-server.hunger-valley.com'

axios.defaults.withCredentials = true

export default function request(url, type = 'GET', data = {}) {

return new Promise((resolve, reject) => {

let option = {

url,

method: type

}

if(type.toLowerCase() === 'get') {

option.params = data

}else {

option.data = data

}

axios(option).then(res => {

console.log(res.data)

if(res.data.status === 'ok') {

resolve(res.data)

}else{

Message.error(res.data.msg)

reject(res.data)

}

}).catch(err => {

Message.error('网络异常')

reject({ msg: '网络异常' })

})

})

}

2.再把获取数据的 API 进行封装,使其更易用:

import request from '@/helpers/request'

const URL = {

REGISTER: '/auth/register',

LOGIN: '/auth/login',

LOGOUT: '/auth/logout',

GET_INFO: '/auth'

}

export default {

// 注册 register({username, password}) {

return request(URL.REGISTER, 'POST', { username, password })

},

// 登录 login({username, password}) {

return request(URL.LOGIN, 'POST', { username, password })

},

// 登出 logout() {

return request(URL.LOGOUT)

},

// 获取信息 getInfo() {

return request(URL.GET_INFO)

}

}

这样子处理的话,登录请求就可以不使用 axios('http://blog-server.hunger-valley.com/auth/login','POST',{username,password}) 那么繁琐了,直接 auth.login({username,password}) 就完事了~

grid

使用 grid 进行布局。

关于 grid 布局之前有了解过,grid 通过在页面上划分 columns 和 rows ,然后把内容分别放进不同区域来建立布局,也写过 demo,但真正在项目中使用还是第一次。关于 grid 的教程可以参考这里

如在项目中的使用:

#app {

display: grid;

// 分成三列,左右列宽度分别是页面的12%,中间内容宽度自适应

grid-template-columns: 12% auto 12%;

// 分成三行,上下行高度自适应,中间内容占满剩余宽度

grid-template-rows: auto 1fr auto;

// 划分区域

grid-template-areas: "header header header"

". main . "

"footer footer footer";

#header{

grid-area: header;

padding-left: 12%;

padding-right: 12%;

}

#main{

grid-area: main;

}

#footer{

grid-area: footer;

padding-left: 12%;

padding-right: 12%;

}

}

async/await

在完成项目的过程中接触到了 async/await :

async/await 是异步编程的一种解决方案。

async 声明一个函数为异步函数,这个函数返回的是一个 Promise 对象;

await 用于等待一个 async 函数的返回值(注意到 await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。)

以项目中用户注册为例:

// 声明 register 为一个异步函数,他会返回一个 Promise 对象async register({commit},{username,password}){

// 用户注册成功后后会返回的一个 Promise 对象,其中包含了用户的信息,let res 就是异步 auth.register 获取的结果 let res = await auth.register({username,password})

commit('setUser',{user:res.data})

commit('setLogin',{isLogin:true})

// 把 res.data 返回出去,使用 register() 后就可以用 then 来处理这个结果 return res.data

},

对于 async/await,我参考了 边城 在 segmentfault 中的这边文章。

Vuex

如何在项目中使用 vuex 管理状态?(以登录为例)1.创建store,定义 state/getters/mutations/actions由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

在这里针对不同的内容状态管理划分到不同的文件,保持可读性:

store

|

│ index.js // 引入子模块

└─modules

auth.js // 负责用户注册、登录状态

blog.js // 负责用户获取、发布、修改博客等

把负责用户注册登录的 state 写在了 auth.js:

// auth.jsimport auth from '@/api/auth'

const state = {

// 先定义一个默认的用户状态 user:null,

//登录状态 isLogin:false

}

const getters = {

// 获取 state 数据 user:state => state.user,

isLogin:state => state.isLogin

}

const mutations = {

// 更新用户数据 setUser(state,payload){

state.user = payload.user

},

// 更新用户登录状态 setLogin(state,payload){

state.isLogin = payload.isLogin

}

}

const actions = {

...

// 检测用户是否登录 async checkLogin({commit,state}){

// 先从本地store的state去看用户是否登录,如果登录了 就返回true if(state.isLogin) return true

let res = await auth.getInfo()

commit('setLogin',{isLogin:res.isLogin})

// 如果本地没有这个状态,就发ajax请求去服务器,服务器会返回一个isLogin的响应,根据这个值来确定是否登录 if(!res.isLogin) return false

commit('setUser',{user:res.data})

// 最后的 return true 是为了在实例中then拿到这个true,方便做下一步处理 return true

},

// 用户登录 {commit} 是默认参数,相当于 context.commit,使用了 ES6 的参数结构 login({commit},{username,password}){

// 调用底层接口,返回的是一个 Promise 对象 return auth.login({username,password})

.then(res => {

// 把通过 axios 获取回来的用户数据提交 mutation,更新到 state: commit -> setUser -> state commit('setUser',{user:res.data})

commit('setLogin',{isLogin:true})

})

},

...

}

export default {

state,

getters,

mutations,

actions

}2.在 /store/index.js 把模块引入进来:

// index.jsimport Vue from 'vue'

import Vuex from 'vuex'

import auth from './modules/auth'

Vue.use(Vuex)

export default new Vuex.Store({

modules:{

auth,

}

})3.在相关组件中映射属性,commit 更新

在 Login.vue 中,我们要做的事情就是:点击按钮后,调用 auth.js 中的 login() 方法,完成登录,更新 state 中的数据,并给需要的组件更新状态(如 header.vue)

首先映射 login 方法到此组件,这样此组件就可以通过 this.login 来调用这个 auth.js 中的方法了:

//Login.vueimport {mapActions} from 'vuex'

export default {

name:'Login',

methods:{

...mapActions([

'login'

]),

},

}

接着设置点击事件,点击按钮会执行 onLogin,调用 this.login ,发送 axios 请求 auth.login({username,password}),成功注册后 commit mutation,更新 state 数据,跳转到首页:

立即登录

//Login.vue

methods:{

...mapActions([

'login'

]),

onLogin(){

this.login({username:this.username,password:this.password})

.then(()=>{

console.log(`${this.username},${this.password}`)

this.$router.push({path:'/'})

})

}

},4.在相关组件中关联 state 数据,实现状态切换

在 Header 中,登录和未登录,他的样式在两种状态下是不一样的:

未登录的时候,header 会显示提示登录和注册的按钮;登录之后,header 会显示用户头像及其他操作选项。

而这两种状态的切换,就要依靠我们的 state 了,首先引入映射 {mapGetters,mapActions},在页面还未渲染的时候检查 state 中用户登录状态,用户已登录,则返回 isLogin = true ,获取用户信息,渲染到页面上;用户未登录,则返回 isLogin = false。

// Header.vue

import {mapGetters,mapActions} from 'vuex'

export default {

name:'Header',

// 把 store 中 getter 属性映射到此组件

computed:{

...mapGetters([

'isLogin',

'user'

])

},

//在页面没有渲染之前检查用户是否登录

created(){

this.checkLogin()

},

methods:{

// 把 auth.js 中的 checkLogin 方法映射到此组件

...mapActions([

'checkLogin'

]),

},

这就是 vuex 在在项目中管理登录状态了。

完善路由

项目中有一些页面,比如添加文章、编辑文章等等,都需要先确认用户是否登录才能操作,否则将会自动跳转到登录页。

路由元信息做的就是这样一件事情,我们给某段路由添加一个 meta 字段 meta:{ requiresAuth:true },这段路由路由匹配到的所有路由记录会暴露为 $route 对象 (还有在导航守卫中的路由对象) 的 $route.matched 数组。通过遍历 $route.matched 来检查路由记录中的 meta 字段,对访问的路径做一个状态检查,从而确定是否允许访问。

const router = new Router({

routes: [

...

{

path: '/Create',

component: () =>import ('@/pages/Create/Create'),

// 路由添加 meta 字段 meta:{ requiresAuth:true }

},

...

]

})

router.beforeEach((to, from, next) => {

if (to.matched.some(record => record.meta.requiresAuth)) {

// 如果 store.dispatch('checkLogin') 返回的结果 isLogin 为 false,则说明用户没有登录,就会跳转到 /login store.dispatch('checkLogin').then(isLogin=>{

if (!isLogin) {

next({

path: '/login',

query: { redirect: to.fullPath }

})

} else {

next()

}

})

} else {

next() // 确保一定要调用 next() }

})

懒加载

小技巧 - 按需加载,节约性能:按需加载的适用场景,比如说「访问某个路由的时候再去加载对应的组件」,用户不一定会访问所有的路由,所以没必要把所有路由对应的组件都先在开始的加载完;更典型的例子是「某些用户他们的权限只能访问某些页面」,所以没必要把他们没权限访问的页面的代码也加载。

// beforeimport Index from '@/pages/Index/Index'

const router = new Router({

routes: [

{

path: '/',

component: Index

},

...

]

})

// afterconst router = new Router({

routes: [

{

path: '/',

component: () =>import ('@/pages/Index/Index')

},

...

]

})

marked

使用 marked.js 对 markdown 内容进行转换:

文章详情页(Detail)中,通过服务器返回的文章内容是 markdown 格式的,先用 marked.js 库处理一下,再使用 v-html 渲染到页面中。

1.安装 cnpm install marked

2.在组件中引入 import marked from 'marked'

3.把内容进行转换:

computed:{

markdown(){

return marked(this.rawContent) //this.rawContent 是从服务器获取的文章正文 }

},

4.在页面中引入:

vue-devtools

最后介绍一款小插件,可以在使用 vue 开发的时候更好地调试和 debug。vue-devtools是一款基于chrome游览器的插件,用于调试vue应用,这可以极大地提高我们的调试效率。当我们添加完vue-devtools扩展程序之后,我们在调试vue应用的时候,chrome开发者工具中会看一个vue的一栏,点击之后就可以看见当前页面vue对象的一些信息。

vue 请求多个api_Vue 创建多人共享博客相关推荐

  1. 多人开源博客系统再搜集

    Posted on October 22, 2006 by kunstao 现在很多人在找多用户blog,我列出的大部分都说自己支持多用户,但实际上多用户有两种,一种是多人共同维护一个blog,另一种 ...

  2. 利用githubpages创建你的个人博客

    最近好多人都开始创建自己的博客网站写博客了, 有钱的买域名买主机好好的折腾一番. 没钱的就使用githubpages搭建自己的博客, 使用githubpages只能放静态网页, 不过这难不倒那些开了挂 ...

  3. 创建了自己的博客~巨开心吖

    探新 今天我参观了大可爱尹的博客,受到启发,创建了自己的博客,以后我也要把自己学会的东西记录在这里,便于自己回顾,或许还可以和有缘人一起探讨分享彼此的体会~想想就十分期待吖~~~~~~~~~~

  4. 为何建议技术人写写博客呢?

    每天早上七点三十,准时推送干货 Photo by XPS on Unsplash 前言 每逢佳节倍思亲,今天是中秋佳节,也是国庆,你是在回家的路上还是已经到家了呢?还是在苦逼的加班呢!今天不谈技术,我 ...

  5. 【Vue+SpringBoot】超详细!一周开发一个SpringBoot + Vue+MybatisPlus+Shiro+JWT+Redis前后端分离个人博客项目!!!【项目完结】

    项目目录 资源准备 前后端分离项目 技术栈 Java后端接口开发 1.前言 2.新建Springboot项目 3.整合mybatis plus 3.统一结果封装 4.整合shiro+jwt,并会话共享 ...

  6. vue全家桶+koa2+mongoDB打造全栈社区博客

    背景 一直以来都想自己编写一个自己的社区博客,后来在网上找了一下,最后决定参考慕课网的一个社区项目,决定改用vue2.6+AntdForVue+koa2+mongoose实现一套社区博客. 简介 这是 ...

  7. springboot+vue练手级项目,真实的在线博客系统

    文章目录 spring boot 练手实战项目说明 基础知识 面试准备 1. 工程搭建 1.1 新建maven工程 1.1.2遇到的bug 1.2 配置 1.3 启动类 2. 首页-文章列表 2.1 ...

  8. Vue、Node全栈项目~面向小白的博客系统~

    个人博客系统 前言 ❝ 代码质量问题轻点喷(去年才学的前端),有啥建议欢迎联系我,联系方式见最下方,感谢! 页面有啥bug也可以反馈给我,感谢! 这是一套包含前后端代码的个人博客系统,欢迎各位提出建议 ...

  9. 如何使用GitHub创建一个自己的博客并且上传

    如何使用GitHub创建个人博客并且上传 一.git是什么 1.1 git简介 1.2 git作用 1.3 安装Git 1.4 如何开始使用Git 1.5 Git常用命令介绍 1.5.1 初始化本地仓 ...

最新文章

  1. iOS 相册相机应用2
  2. java: String的==与equals
  3. 浮点加减运算之0舍1入法与恒置1法
  4. Android仿QQ5.0侧滑菜单ResideMenu的使用和源码分析
  5. android 中文 api (72) —— BluetoothSocket[蓝牙]
  6. html设置垂直高度,html – 具有垂直文本的100%高度块
  7. Win 10 Revit 2019 安装过程,亲自踩的一遍坑,有你想要的细节
  8. LWIP初体验-修改ST官方demo
  9. 简述oracle函数的功能,Oracle 最常用功能函数经典汇总 (zz)
  10. 遗传算法是一种进化算法_一种算法的少量更改可以减少种族主义的借贷
  11. win7ie11调用java失败,Win7 更新IE11 一直失败,请求
  12. android系统解压zip文件,Android解压缩zip文件
  13. 韩昊 20190919-5 代码规范,结对
  14. 随机生成中文名、性别、手机号、住址、email的java代码
  15. 1037: 求一元二次方程的根(带虚根)
  16. 自动配置和 thymeleaf模板引擎
  17. Freebase调研(持续更新中)
  18. 电商积分体系存在的问题
  19. 全靠这份Java知识点PDF大全,先睹为快
  20. android 虚拟技术打开,雷电安卓模拟器VT虚拟化打开方法教程

热门文章

  1. php连接redis报错,PHP使用phpredis链接redis错误
  2. 无需任何启动盘,在windows系统上一键安装linux(ubuntu)双系统的方法!
  3. 数据挖掘导论读书笔记6关联分析的高级概念
  4. 突破NP屏蔽,实现按键模拟!
  5. 源码分析netty服务器创建过程vs java nio服务器创建
  6. Windows8下如何使用命令行--转载
  7. 【风控场景】互利网上数字金融典型场景: 网购运费险
  8. 【采用】【风险管理】金融业务风控相关框架(宝藏)
  9. 跟我学大数据分析:多维度数据分析报告
  10. Libra深度解析!