编 写:袁 亮
时 间:2017-06-28
说 明:Vue开发快速起步
一、工作模式
1、类似jquery,作为类库
2、单文件组件方式
开发环境
node hot reload
生产环境
静态html
任意部署在webserver下即可
二、安装起步
1、环境安装
node npm vue vue-cli 等安装
2、项目脚手架安装
vue init webpack {project_name}
cd {project_name}
npm install
ps:vim config/dev.env.js 修改开发环境端口,默认8080很有可能被占用
npm run dev
放在后台运行:nohup npm run dev &
3、访问
http://192.168.0.249:8081
4、IDE
webstorm
sublime
vscode
5、其他模块安装
vuex的安装
npm install vuex --save
修改package.json
6、编译
npm run build
三、开发环境访问流程
1、index.html
2、src/main.js
类似php框架的index.php
3、src/App.vue
4、router/index.js
规则匹配,进行转发
路由处理
5、components/Hello.vue
具体处理逻辑
可以包含其他的组件
四、组件开发
1、类库文件引入
1.1 引入
import
必须在最开始的地方加,不能放在条件判断等
require
可以在条件判断里
1.2 类库导致
export default
module.exports
2、组件引入
2.1 html结构
2.2 组件源
import modalMember from '@/components/modalMember.vue'
2.3 注册?
components: {
modalMember
}
3、组件数据
3.1 父组件数据传递 props
props验证
值传递 引用传递
单向数据流
3.2 组件本身数据 data
3.3 组件计算属性 computed
method的区别,缓存,依赖
getter
setter
3.4 数据监听 watch
vs computed
异步、开销大的时候,用watch
4、模板语法
4.1 文本
{{}}
v-text
v-html
v-once
不更新
4.2 属性
v-bind:{name}
简写 :{name}
:class 注意注意
4.3 条件属性
v-if
v-else-if
v-else
v-show
4.4 循环 v-for
4.5 事件
v-on:click
@click
4.6 输入数据双向绑定
v-model
修饰符
.lazy
.number
.trim
4.6 注意事项
a. 以下对数组操作,不会触发视图变更
当你利用索引直接设置一个项时
当你修改数组的长度时
b. 视图更新队列
数据变更,视图更新会放入到更新队列,异步更新
如果想更新完进行回调,可以采用Vue.nextTick(callback)
ps:监听数据变更,改版dom的滚动条位置计算等,数据更新了,但是dom还没有
5、组件方法
5.1 method
获取绑定的数据
e.currentTarget.dataset.index (数据绑定在父元素的时候用这个)
e.target.dataset.index (数据绑定在当前元素的时候用这个)
event
事件修饰符
.stop
.prevent
.capture
.self
.once
键值修饰符
事件
别名 自定义
修饰键
5.2 directive 自定义指令(不能直接操作dom,所以需要自定义指令)
bind
inserted
update
componentUpdated
unbind
6、生命周期
beforeCreate
√ created
mount
beforeMount
mounted
beforeUpdate
updated
beforeDestory
destroyed
五、状态管理 Vuex
1、解决什么问题
一份数据,很多个组件需要使用
这些组件不仅仅是父子关系
2、安装
npm install vuex --save
3、项目使用(全局store)
import store from './store/index'
new Vue({
el: '#app',
router,
store,
template: ' ',
components: { App }
})
4、store介绍
4.1 state
类似组件的data
4.2 getters
类似computed计算属性
setters: 没用过
4.3 mutations
类似method
ps:mutations之间不能直接调用,不确定是否可以这么做
六、网络请求 vue-resource
1、安装
2、使用
import VueResource from 'vue-resource'
Vue.use(VueResource)
ps:作为插件引入
3、需要重新封装,跟常规的ajax请求不大一样
3.1 api地址区分环境
3.2 统一做鉴权等
七、语法注意
1、var 改用let 或者const
2、缩进 2个字符
3、不能有;号
4、空格
function () {
}
// 注释文字
mysql binlog日志查看
基本说明
-
定义
binlog基本定义:二进制日志,也成为二进制日志,记录对数据发生或潜在发生更改的SQL语句,并以二进制的形式保存在磁盘中; -
作用
可以用来查看数据库的变更历史(具体的时间点所有的SQL操作)、数据库增量备份和恢复(增量备份和基于时间点的恢复)、Mysql的复制(主主数据库的复制、主从数据库的复制) -
格式
binlog的格式有三种,这也反应了mysql的复制技术:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。相应地,binlog的格式也有三种:STATEMENT,ROW,MIXED。 -
日志位置
修改my.cnf参数文件
[mysqld]
log-bin=mysql-bin
语法说明
-
命令
binlog不能直接用文本的方式打开。
使用show binlog events方式可以获取当前以及指定binlog的日志,不适宜提取大量日志。
使用mysqlbinlog命令行提取(适宜批量提取日志)。 -
语法
直接查看单个二进制日志文件:
mysqlbinlog filename提取指定position位置的binlog日志
--start-position="120" --stop-position="332"提取指定数据库binlog并转换字符集到UTF8
--database=test --set-charset=utf8指定结束时间
--start-datetime='2015-01-20 09:00:00' --stop-datetime='2015-01-20 12:59:59'指定row格式解码
--base64-output=decode-rows-v用于输出基于row模式的binlog日志
-vv为列数据类型添加注释
日志格式
# at 579744(开始位置)
#150905 7:02:54(时间截) server id 2543308(产生该事件的服务id) end_log_pos(日志的结束位置) 579815 Query(事件类型) thread_id=21 exec_time=0 error_code=0
SET TIMESTAMP=1441407774/*!*/;
BEGIN
执行的sql语句
其他说明
- 在数据出错的情况下,使用 MYSQLBINLOG 来恢复数据
5.3 迁移 5.6 需要注意的问题
👁代表额外需要注意的,✅代表遇到过
5.3 Migrating 5.4
重点
break和continue不再接受可变参数(break 1 + max(x, y)),break 0;continue 0不允许出现- 现在参数名使用全局变量将会导致一个致命错误。禁止类似
function foo($_GET, $_POST) {}这样的代码。 - 非数字的字符串偏移量👁
$a = '12345';
var_dump(isset($a['x']); // 5.3 true, 5.4 false
- 调用时的引用传递👁
function f(&$v){$v = true;}
f(&$v); // 5.3 no problem 5.4 PHP Fatal error
function f1($v){$v = true;}
f1(&$v); // 5.3 no problem 5.4 PHP Fatal error
function f2(&$v){$v = true;}
f2($v); // ok
一些不常用的
- 不支持安全模式
- 移除魔术引号
-
register_globals 和 register_long_arrays php.ini 指令被移除。
5.4 Migrating 5.5
重点
- 原始的 MySQL 扩展 现在被废弃,当连接到数据库时会产生一个 E_DEPRECATED 错误。👁
5.5 Migrating 5.6
重点
json_decode严格模式cURL文件上传 👁✅
> 必须先设置CURLOPT_SAFE_UPLOAD为 FALSE 才能够使用@file语法来上传文件。 建议使用 CURLFile 类来上传文件。- 使用
::调用非静态方法,现在产生 E_DEPRECATED 错误 (以前是 E_STRICT) - 使用
always_populate_raw_post_data会导致在填充$HTTP_RAW_POST_DATA时产生E_DEPRECATED错误。 请使用php://input替代$HTTP_RAW_POST_DATA, 因为它可能在后续的 PHP 版本中被移除。 在php.ini中设置 always_populate_raw_post_data 为 -1 (这样会强制 $HTTP_RAW_POST_DATA 未定义,所以也不回导致 E_DEPRECATED 的错误) 👁✅ - 使用数组标识符为类定义数组类型的属性时,数组的键不会被覆盖
class C {
const ONE = 1;
public $array = [
self::ONE => 'foo',
'bar',
'quux',
];
}
var_dump((new C)->array);
/* 5.5 before array(2) {
[0]=>
string(3) "bar"
[1]=>
string(4) "quux"
}
*
* 5.6
* array(3) {
[1]=>
string(3) "foo"
[2]=>
string(3) "bar"
[3]=>
string(4) "quux"
}
*/
其他问题
-
线上的php5.6没有编译
fileinfo,这个会导致读不到文件信息,因为运维都是统一安装的,所以最好看一下是否enable-fileinfo -
启用 Opcache,之前因为出现了一些问题,运维那边关掉这个缓存,最好和运维沟通,并测试缓存是否正确使用、正常更新。
vue+webpack多页面应用设置
整 理:晋 哲 时 间:2017-04-10 说 明:vue+cli脚手架默认搭建的是单页面应用,在实际项目中需要优化配置生成多页面。
设置步骤:
一、修改src文件结构
图一为脚手架默认生成的src结构

图二为调整后的文件结构,新建module文件夹,将每个页面都对应一个同名的文件夹

比如:login文件夹里的三个文件是由原先的App.vue、main.js、index.html整合到一个文件夹内进行修改,welcome文件夹就是再复制一份修改
二、修改build内的文件配置
主要是调整webpack中html-webpack-plugin插件的默认设置,这是用来将js和html对应起来的插件
调整三处js文件,如下图:

1、webpack.base.conf.js
(1)在头部添加下面两行代码
var glob = require('glob'); // 引入glob工具
var entries = getEntry('./src/module/**/*.js'); // 获得入口js文件
(3)在底部添加getEntry方法,用于匹配路径
function getEntry(globPath) {
var entries = {},
basename, tmp, pathname;
glob.sync(globPath).forEach(function (entry) {
basename = path.basename(entry, path.extname(entry));
tmp = entry.split('/').splice(-3);
pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径
entries[pathname] = entry;
});
return entries;
}
2、webpack.dev.conf.js
(1)在头部添加下面两行代码,引入path和glob工具
// 引入path和glob工具
var path = require('path');
var glob = require('glob');
(3)在底部也添加getEntry方法,并添加自定义HtmlWebpackPlugin插件的配置
function getEntry(globPath) {
var entries = {},
basename, tmp, pathname;
glob.sync(globPath).forEach(function(entry) {
basename = path.basename(entry, path.extname(entry));
tmp = entry.split('/').splice(-3);
pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径
entries[pathname] = entry;
});
return entries;
}
// 自定义HtmlWebpackPlugin插件配置
var pages = getEntry('./src/module/**/*.html');
for (var pathname in pages) {
// 配置生成的html文件,定义路径等
var conf = {
filename: pathname + '.html',
template: pages[pathname], // 模板路径
minify: { //传递 html-minifier 选项给 minify 输出
removeComments: true
},
inject: 'body', // js插入位置
chunks: [pathname, "vendor", "manifest"] // 每个html引用的js模块,也可以在这里加上vendor等公用模块
};
// 需要生成几个html文件,就配置几个HtmlWebpackPlugin对象
module.exports.plugins.push(new HtmlWebpackPlugin(conf));
}
3、webpack.prod.conf.js
和上一个文件webpack.dev.conf.js中做类似的处理,先注释掉原来的HtmlWebpackPlugin,然后在下面添加函数,通过迭代插入多个HtmlWebpackPlugin。
安装vue-cli脚手架构建项目步骤
整 理:晋 哲 时 间:2017-03-30 说 明:安装脚手架,编译生成最终用于实际项目的压缩文件
1、确认已经安装node环境和npm包管理工具,建议将 npm 的注册表源设置为国内的镜像,可以大幅提升安装速度。
npm install -g cnpm --registry=https://registry.npm.taobao.org
5、安装依赖
$ cd my-project
$ npm install
6、实时运行项目,会自动打开一个浏览器窗口,默认访问localhost:8080
$ npm run dev


(2)如果是在测试机249上安装,则默认的localhost:8080访问不了,需要修改build/dev-server.js文件里的uri

最终访问:http://192.168.0.249:8080
![]()

7、开发版本用于实际项目中,编译vue文件,在dist文件夹内最终生成压缩版html、js、css。
$ npm run build


PHP闭包
闭包的介绍
闭包是词法作用域的体现,一般编程语言有这些特性
- 函数是一阶值(First-class value),即函数可以作为另一个函数的返回值或参数,还可以作为一个变量的值。
- 函数可以嵌套定义,即在一个函数内部可以定义另一个函数。
三个关键点
- 函数
- 自由变量
- 作用域
自由变量
let a = 1
let b = function(){
console.log(a)
}
在这个例子里函数b因为捕获了外部作用域(环境)中的变量a,因此形成了闭包。 而由于变量a并不属于函数b,所以在概念里被称之为「自由变量」。
注意点:
- 在一些语言里,「捕获」这一行为还有一个特点:闭包只会捕获自由变量的引用。
- 在PHP中,需要使用
use关键词显示调用自由变量
作用域
可以使用外部的「自由变量」,内部变量不能被访问,形成一个相对安全的访问环境
总结
- 记住定义当时的外部环境
- 封闭外部环境
- 延迟执行
基本使用
$func = function () {
};
$func();
$a = '1';
$func = function () use ($a) {
}
$func();
作用域
- 闭包拥有独立的作用域,基本等同普通函数
- 在方法中使用时,等同于实例的方法,可以直接使用$this(>=5.4)
注意点
$this 的使用
在一次开发中遇到关于闭包的一个问题
class Demo
{
/**
*
*/
public function test()
{
$data = $this->isCache('name', function () {
$this->sayHello();
});
}
/**
*
*/
protected function sayHello()
{
echo 'Hello, World';
}
/**
* @param $name
* @param $callback
* @return array
*/
public function isCache($name, $callback)
{
$callback();
return array();
}
}
我希望在一个闭包中调用这个类的一个受保护的方法(这里假设是sayHello),结果在运行的时候,直接出现了语法级别的报错。
查了一些资料发现了问题
- 5.3 版本不能直接在闭包中使用$this
PHP的bug,在5.4中得以修复
$that = $this;
$data = $this->isCache('name', function () use ($that) {
$that->sayHello(); // 这里只能是public
});
看似这个问题解决了,不过在stackoverflow上一位热心人士的提醒中,这样是会出现一些问题的,因为这样传递$this, 是赋值传递,也就是说,在闭包中调用方法导致实例属性的变化不会反应到闭包外面,这样在一些特殊情况,会导致闭包内外属性不一致,所以这里最好使用引用传递,除非你知道你在干什么!
$that = $this;
$data = $this->isCache('name', function () use (&$that) {
$that->sayHello(); // 这里只能是public
});
如果在5.4版本下,不但可以直接使用$this,而且作用域等同于实例中的方法
$data = $this->isCache('name', function () {
$that->sayHello(); // 这里可以是任意限制符
});
Closure类
- Closure::__construct — Constructor that disallows instantiation
- Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
- Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。
- Closure::call — 绑定指定的$this对象和类作用域并执行
- Closure::fromCallable — 将一个可执行函数转换为闭包函数
bind和bindTo的区别
// bind,相当把一个类的加上加上一个方法,并且将该方法转换成闭包
class A {
private static $sfoo = 1;
private $ifoo = 2;
}
$cl1 = static function() {
return A::$sfoo;
};
$cl2 = function() {
return $this->ifoo;
};
$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo $bcl1(), "\n"; // 1
echo $bcl2(), "\n";// 2
// bindTo,改变指定的$this对象和类作用域
class A {
function __construct($val) {
$this->val = $val;
}
function getClosure() {
//returns closure bound to this object and scope
return function() { return $this->val; };
}
}
$ob1 = new A(1);
$ob2 = new A(2);
$cl = $ob1->getClosure();
echo $cl(), "\n";
$cl = $cl->bindTo($ob2);
echo $cl(), "\n";
虽然两者看上去像,实际上不是一回事。
Vue开发环境搭建
一、安装虚拟机
1)版本:Vmware 12 Pro版 + Cent-OS 32位
2)密钥:5A02H-AU243-TZJ49-GTC7K-3C61N
3)分区:/、/boot、swap
二、配置网络
1)ifconfig查看windows配置
2)修改文件:vim /etc/sysconfig/network-scripts/ifcfg-eth0
# Xen Virtual Ethernet
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
HWADDR=2e:c1:12:61:5f:ea
NETMASK=255.255.255.0
IPADDR=192.168.0.249
GATEWAY=192.168.0.1
TYPE=Ethernet
三、配置远程控制器putty
直接设置ip即可,没有选择生成秘钥
四、安装nodejs
1、安装依赖包:yum install gcc-c++ openssl-devel
2、安装最新版本node.js:
cd /usr/local/src
wget http://nodejs.org/dist/node-latest.tar.gz
tar -zxvf node-latest.tar.gz
cd node-v7.7.0
./configure
make && make install
3、如果需要升级gcc,则升级gcc,不要忘记加软连接
4、解决警告:sudo date -s '01:10:00 2017-03-02'
5、重新执行 ./configure 以及 make && make install
五、vue安装
# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev
六、本地(windows)与虚拟机(Cent-OS)交互
1、vim build/dev-server.js
修改localhost为虚拟机IPADDR
2、关闭防火墙
3、在本地浏览器输入IP:8080展现vue界面
关于用户体验的十大原则
用户体验的核心和本质就是研究人在特定场景下的思维模式和行为模式,然后顺应和利用它。
举例:
为什么要把网页的重要内容放到页面的左上部分?因为人的视觉注意力会首先锁定在左上的位置。
为什么按钮平常状态和按下状态一般是不同的?因为用户需要反馈,没有反馈人会产生疑惑。
为什么超市收银台面前会有货物架?因为顾客在排队的时候处于非常无聊的状态,这时候任何商品或信息都会引起他们的注意,是销售某些易耗便携物品的绝佳时机。
-
系统可见原则
保证界面的内容可见、状态可见、变化可见

内容你要考虑到用户最想看见关注的是什么,收货人信息,支付方式和派送方式,总价以及扣除其它折扣优惠等最终用户需要花的钱,这些是用户最关注的点。
不管是有网、没网,还是错误、成功、警告、提示等状态都要给用户一个反馈;

像左划右划,上拉下拉,抽屉效果等动画都需要展现出来给用户一个暗示:这个是可以手势操作的。 - 可控性原则
让用户能对当前情况有很好的了解与掌握,要给用户足够的自由度。
-
一致性
用户在同一款产品里接受同一套规范和逻辑。比如说收藏、关注、点赞等,不管是名称还是图标都要形成一个大的规范,更换名词和图标会导致用户的学习成本提高。还有行为逻辑一定要规范。 - 协助用户记忆原则
在需要记忆某些信息时,产品功能上要帮助用户记忆。如账号密码的记录,短信的草稿等。

-
简约易读原则
界面足够简单、内容易换 - 帮助和提示
在任何时候,考虑到用户需要得到的帮助情况予以提示,比如删除东西,添加修改等。 - 灵活高效原则
用户在使用时,要能够方便,高效的完成任务,如注册流程,填写资料、分享文章,书写动态等。 - 恢复现场原则
适应用户的碎片化使用习惯,在各种切换和退出返回时,要有恢复现场的能力。比如在看视频电影的时候,有人找你聊天,你退出回复完,再点击进入还能继续观看你的电影。
Git命令-rebase和merge的区别
编写: zhangyue 时间: 2017-02-23 说明: git的一些命令使用
1 merge和rebase的区别
merge:合并两个分支,根据两个分支的同一个起点,同相同起点开始,把两个分支的修改进行合并,之后生成生成一个commit。
rebase:合并两个分支,抽取出当前的分支的commit, 之后合并目标分支commit,再将置顶抽出的commit重新合并入当前分支的commit
2 两者合并的示意图
merge:
master: master:1 -- master:2
|
dev : |-- dev:1 --- dev:2 执行git merge master
dev的log:
dev : master:1 --> dev:1 --> dev:2 --> master:2 --> merge commit
rebase:
master: master:1 -- master:2
|
dev : |-- dev:1 -- dev:2 执行git rebase master
dev的log:
dev : master:1 --> master:2 --> dev:1 --> dev:2
3 在发生冲突时两者的不同处理方式
merge: 有冲突->停止合并->手动解决后->再次merge
rebase:有冲突->暂停操作->手动解决,
git rebase --continue继续(--skip跳过/--abort 停止rebase操作)
4 rebase对commit的操作
git rebase -i HEAD~3 对所做的提交进行修改
# Commands:
# p, pick = use commit 不做任何修改
# r, reword = use commit, but edit the commit message 只修改提交注释信息
# e, edit = use commit, but stop for amending
修改提交的文件,做增补提交
# s, squash = use commit, but meld into previous commit
将该条提交合并到上一条提交,提交注释也一并合并
# f, fixup = like "squash", but discard this commit's log message
将该条提交合并到上一条提交,废弃该条提交的注释
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
删除某次提交
5 其他的一些功能命令
git cherry-pick 取某一个分支中的一个或几个commit(s)来进行合并
git stash [pop/apply /drop/save] 将改动存入暂存区[弹出暂存区记录/恢复一个暂存区内记录]
git blame 文件逐行追溯
git clean 清除工作区未跟踪文件
移动前端自适应解决方案
2.网易 设置根元素html字体大小,使用rem,并用js计算不同分辨率下的html字体大小
使用rem布局结合在html上根据不同分辨率设置不同font-size,通过js计算出来的,所以当分辨率发生变化时,html的font-size就会变。
为了计算方便,取一个100px的font-size为参照,如设计稿的横向分辨率为640px,则body的width:6.4rem; 于是html的font-size=deviceWidth / 6.4。
这个deviceWidth就是viewport设置中的那个deviceWidth, 这个deviceWidth通过document.documentElement.clientWidth就能取到了。所以当页面的dom ready后,做的第一件事情就是:
document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 +’px’;
视口要如下设置:
meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
该meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。也许允不允许用户缩放不同的网站有不同的要求,但让viewport的宽度等于设备的宽度,这个应该是大家都想要的效果,如果你不这样的设定的话,那就会使用那个比屏幕宽的默认viewport,也就是说会出现横向滚动条。
网易:http://3g.163.com/touch/all?nav=2&dataversion=A&version=v_standard
3.淘宝 动态设置viewport的scale以及动态计算html的font-size
视口要如下设置:
meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
动态设置viewport的scale
var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
device-width的计算公式为:
设备的物理分辨率/(devicePixelRatio * scale);devicePixelRatio称为设备像素比
动态计算html的font-size
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10
font-size可能需要额外的媒介查询,并且font-size不使用rem
淘宝:https://m.taobao.com/?sprefer=sypc00#index















