月度归档四月 2018

前后端分离实践

AbingGo No Comments

项目源码

主要技术栈:vue + vue-router +  axios + koa2

 

遇到的问题:

一.前后端分离解决端口冲突。

可直接采用proxy的方式,将所有api的接口都转到 target 。

clinet中新建 proxy.js

//proxy.js
module.exports = {
    proxyList: {
        '/api': {
            target: 'http://localhost:3001',
            changeOrigin: true
        }
    }
}

二.基于前后端分离的身份认证方式——JWT(Json web token)

 

1.基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

具体流程如下:

1、用户使用用户名密码来请求服务器
2、服务器进行验证用户的信息 服务器通过验证发送给用户一个token。
3、 客户端存储token,并在每次请求时附送上这个token值 服务端验证token值,并返回数据。
4、这个token必须要在每次请求时传递给服务端,它应该保存在请求头里。

 

import axios from 'axios'
import util from '../util'

// http request 拦截器
axios.interceptors.request.use(
    config => {
        let token = util.getCookie('token')
        if (token) {
            // 判断是否存在token,如果存在的话,则每个http header都加上token
            config.headers.Authorization = `Bearer ${token}`
        }
        return config
    },
    err => {
        return Promise.reject(err)
    }
)

export const api = axios

 

使用 router.beforeEach 注册一个全局前置守卫:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import User from '@/components/User'
import Login from '@/components/LoginRegister'
import Util from '@/util'

Vue.use(Router)

const router = new Router({
    routes: [
        {
            path: '/',
            name: 'Home',
            component: Home,
            meta: {
                verification: true
            }
        },
        {
            path: '/login',
            name: 'Login',
            component: Login
        },
        {
            path: '/user',
            name: 'User',
            component: User
        }
    ]
})

router.beforeEach((to, from, next) => {
    if (to.meta.verification && !Util.getCookie('token')) {
        next({
            path: '/login',
            query: {
                redirect: to.fullPath
            }
        })
    } else {
        next()
    }
})

export default router

 

css实现一个字多种颜色

AbingGo No Comments

  • 通过dom重叠的方式,视觉上看着像是一个字多种颜色。话不多说,直接贴代码。

 

JS Bin on jsbin.com

  • 通过before、after伪元素,具体::before和::after伪元素的用法请参考我的另一篇文章CSS3 before after

一个字多种颜色 on jsbin.com

 

 

 

css3 before after

AbingGo One comment

一、介绍

 

  • 伪类,采用单冒号写法,即 ‘:’。常见的有:hover, :link, :active, :target, :not(), :focus。
  • 伪元素,采用双冒号写法,即 ‘::’。常见的有::before, ::after, ::first-letter, ::first-line, ::selection。

注意:css2中,伪元素before和after写为:before, :after

本文主要介绍 伪元素::before和::after。伪元素的意思就是元素不是在DOM中生成的,而是在浏览器渲染引擎渲染CSS的时候渲染上去的, 所以不能通过常规的js去操作它。before 和 after其实就是附着在元素前后的伪元素。默认情况下,伪类元素的display是默认值inline,可以通过设置display:block等来改变。

通过::before, ::after等我们可以实现多种效果,比如实现图标、一个字多种颜色、多边形、一个标签设置多张背景图片等效果。具体使用方法请看下面。

 

二、content属性

 

  • 用于在 CSS 渲染中向元素逻辑上的头部或尾部添加内容。
  • content必须有值,至少是空。
p::after {
    content: ""
}
p::before{
    content: "↗";
    color: #000;
    display: block;
    width: 100px;
    height: 100px;
}

 

  • 通过attr()调用当前元素的属性,可以是自定义属性。
<a href="http://abinggo.com"> AbingGo </a>
a::after{
    content: "(" attr(href) ")";
}
<p data-src="AbingGo"></p>
p::after{
    content: attr(data-src); 
}

 

  • url() / uri() – 用于引用媒体文件。
a::before {
    content: url("http://www.abinggo.com/a.jpg");
}

 

  • 调用计数器,可以不使用列表元素实现序号功能。配合counter-increment和counter-reset属性使用。

.container{
    counter-reset: section;
}
h1::before{
    counter-increment: section;
    content:counter(section) "、";
}

<div class="container">
    <h1>AbingGo 1</h1>
    <h1>AbingGo 2</h1>
    <h1>AbingGo 3</h1>
</div>

三、实现多种效果

  • 三角形
.par{
	width: 0;
	border-top: 100px solid #19f305; 
	border-right: 100px solid #f33505; 
	border-bottom: 100px solid #2804f4; 
	border-left: 100px solid #000; 
	margin: auto;
}

<div class = "par"></div>

四个三角形

 

  • 图标
.logo {
  	position: relative;
	width: 90px;
  	height: 70px;
  	border: 25px solid red;
  	border-bottom-left-radius: 50%;
  	border-bottom-right-radius: 50%;
}

.logo:after {
	content: "";
  	width: 25px;
        height: 25px;
  	position: absolute;
  	top: -25px;
  	right: -25px;
  	background: #fff;
}

<div class="logo"></div>

 

  • 一个字多种颜色
.font {
    display: inline-block;
    position: relative;
    font-size: 80px;
    line-height: 80px;
    color: #000;
    overflow: hidden;
    white-space: pre;
}

.font:before {
    position: absolute;
    left: 0;
    top: 0;
    color: #f00;
    width: 30%;
    content: attr(data-font);
    overflow: hidden;
}

  <div class="font" data-font="等">等</div>
  <div class="font" data-font="你">你</div>
  <br>
  <div class="font" data-font="来">来</div>
  <div class="font" data-font="战">战</div>

 

 

 

本文只为自己总结学习。有错误或者误导的地方请指正。

call,apply,bind

AbingGo No Comments

call,apply,bind都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply,bind属性.既然作为方法的属性,那它们的使用就当然是针对方法的了.这三个方法是容易混淆的,因为它们的作用一样,只是使用方式不同。

 

  1. 这三者都是用来改变函数的this对象的指向的。
  2. 第一个参数都是this要指向的对象。
  3. 都可以利用后续参数传参。

 

var jianbing = {
    name:  "AbingGo",
    say:  function(company, address){
        console.log(this.name, company, address);
    }
}
var ty = {
    name:  "ty19105"
}

jianbing.say('Qihoo360', 'beijing');  // AbingGo Qihoo360 beijing

 


// call 方法
jianbing.say.call(ty, 'Qihoo360', 'beijing');  // ty19105 Qihoo360 beijing

 


// apply 方法
jianbing.say.apply(ty, ['Qihoo360', 'beijing']);  // ty19105 Qihoo360 beijing

 


// bind 方法的的两种传参方式

jianbing.say.bind(ty)('Qihoo360', 'beijing');    // ty19105 Qihoo360 beijing

jianbing.say.bind(ty, 'Qihoo360', 'beijing')();  // ty19105 Qihoo360 beijing

 

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以。三者之间的区别与联系一目了然。