编 写:袁 亮 时 间:2017-08-17 说 明:复杂页面交互,键盘快捷键监听组件 一、功能描述 1、事件监听 默认绑定keydown事件 绑定单例,防止多次绑定,导致多次触发 ps:vue如果代码自动刷新,会导致又绑定一次 2、触发条件 配置条件 inInput:光标在输入框内是否触发 true:触发,false:不触发,默认true needCtrl:是否需要同时按下ctrl键 不传,不限制 true:必须按下Ctrl false:不能按下Ctrl needShift:是否需要同时按下shift键 同needCtrl needAlt:是否需要同时按下alt键 同needCtrl 自定义方法 触发的时候,会执行该方法判断是否要执行,返回true或者false 不传,默认true 3、事件触发执行 同一事件,多次绑定 后绑定的优先级更高 事件冒泡 如果事件没有被响应,自动按绑定顺序冒泡 事件互斥 同一事件,只会触发一次,捕获后,不再冒泡 默认行为阻止 事件被捕获,默认行为将被阻止 4、事件定义 内置常见事件 esc:取消 backspace enter delete up down increase decrease number:数字 float:浮点数 letter:字母 支持自定义事件配置 优先级高于内置事件 二、使用方法 1、安装包 npm install @duomai/keylisten --save ps:先切换到多麦的源 2、代码 import KeyListen from '@duomai/keyListen' // 在created钩子里,使用内置事件,不需要setConfig KeyListen.setConfig(config.shortcutKey).add({ up: function () { // todo up }, down: function () { // todo down } })
npm私有仓库3:项目中使用
编 写:袁 亮 时 间:2017-08-15 说 明:npm私有仓库3:项目中使用 一、修改dns地址 192.168.0.224 1、linux vim /etc/resolv.conf nameserver 192.168.0.224 2、windows 网络设置 清除缓存 cmd命令行 ipconfig /flushdns 二、nrm管理npm源 1、安装 npm install -g nrm 2、添加私有源 nrm add duomai http://npm.duomai.com 3、查看所有源 nrm ls 4、使用私有源 nrm use duomai 三、安装包 1、私有包(跟其他包一样,只是多了一个统一的前缀) npm install @duomai/urls 2、普通包 npm install vue 3、包查看 http://npm.duomai.com 4、注意事项 如果私有包使用es6的语法写,webpack打包的时候,需要将其使用babel转换,否则打包的时候会报错 { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/\@duomai')] } 四、使用参考 @duomai/urls 1、安装 npm install @duomai/urls --save 2、全局引入,设置 import Urls from '@duomai/urls' Urls.init({ store_id: Login.state.data ? Login.state.data.store_id : '' // 链接公共参数注入 }, { shop: process.env.SHOP_BASE_URL, // 测试链接前缀注入,可以不写,默认正式环境 seller: process.env.SELLER_BASE_URL, dealer: process.env.DEALER_BASE_URL }) 3、组件中使用 import Urls from '@duomai/urls' console.log(Urls.shop.item(1921))
解读vue-cli脚手架并实际使用
整 理:晋 哲 时 间:2017-06-29 说 明:介绍脚手架搭建生成的各个文件功能,以及在实际项目中使用
一、vue-cli脚手架搭建之后的文件介绍及应用
1、build -- 开发配置文件夹,一般情况下安装时自动添加,通常不用改动
webpack.base.conf.js -- webpack配置文件
2、config文件夹
这里主要需要注意这几点的设置,正式运行环境下assetsPublicPath的路径设置需要改动为【./】
3、package.json -- 记录项目基本信息
4、index.html -- vue生成html的默认head代码部分,需要调整
5、README.md -- 一些执行命令的说明,方便查看使用
6、src -- vue代码存放的主要路径
(1)api -- 封装的api调用方式
使用如下:
注:sys_name和store_id已默认,不用传
(2)assets -- 静态文件存放,比如css、js、image、font等等
(3)common -- 存放一些封装的公共方法,比如alertMes、弹出框等等
(4)router -- 路由设置
(5)App.vue -- 主体组件
组件内容在
(6)main.js -- 入口文件,主要作用是初始化vue实例并使用需要的插件
(7)components -- 组件的存放位置
一个主体的集合组件,拼接各个模块的子组件
二、引用ElementUI组件
1、安装
npm i element-ui -S
3、组件里使用
比如“消息提示”组件的使用
this.$message('请输入商品名称')
具体各组件的使用方式查看官方文档
http://element.eleme.io/#/zh-CN/component/installation
三、引用vue插件
举例:vue-awesome-swiper插件
1、安装
npm install vue-awesome-swiper --save
Vue开发快速起步
编 写:袁 亮 时 间: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界面