npm私有包:键盘事件监听


编   写:袁 亮
时   间: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配置文件
1
13

2、config文件夹
这里主要需要注意这几点的设置,正式运行环境下assetsPublicPath的路径设置需要改动为【./】
2

3、package.json -- 记录项目基本信息
4、index.html -- vue生成html的默认head代码部分,需要调整
5、README.md -- 一些执行命令的说明,方便查看使用

6、src -- vue代码存放的主要路径
(1)api -- 封装的api调用方式
使用如下:
3
注:sys_name和store_id已默认,不用传

(2)assets -- 静态文件存放,比如css、js、image、font等等
(3)common -- 存放一些封装的公共方法,比如alertMes、弹出框等等
(4)router -- 路由设置
4

(5)App.vue -- 主体组件
组件内容在里显示,公共样式可以在这里引入
5

(6)main.js -- 入口文件,主要作用是初始化vue实例并使用需要的插件
614

(7)components -- 组件的存放位置
一个主体的集合组件,拼接各个模块的子组件
7

子组件常用代码结构
8

二、引用ElementUI组件
1、安装

npm i element-ui -S

2、main.js里引入Element
9

3、组件里使用
比如“消息提示”组件的使用
this.$message('请输入商品名称')

具体各组件的使用方式查看官方文档
http://element.eleme.io/#/zh-CN/component/installation

三、引用vue插件
举例:vue-awesome-swiper插件
1、安装

npm install vue-awesome-swiper --save

2、main.js里引入插件
11

3、组件里使用
12

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日志查看

基本说明

  1. 定义
    binlog基本定义:二进制日志,也成为二进制日志,记录对数据发生或潜在发生更改的SQL语句,并以二进制的形式保存在磁盘中;

  2. 作用
    可以用来查看数据库的变更历史(具体的时间点所有的SQL操作)、数据库增量备份和恢复(增量备份和基于时间点的恢复)、Mysql的复制(主主数据库的复制、主从数据库的复制)

  3. 格式
    binlog的格式有三种,这也反应了mysql的复制技术:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。相应地,binlog的格式也有三种:STATEMENT,ROW,MIXED。

  4. 日志位置
    修改my.cnf参数文件
    [mysqld]
    log-bin=mysql-bin

语法说明

  1. 命令
    binlog不能直接用文本的方式打开。
    使用show binlog events方式可以获取当前以及指定binlog的日志,不适宜提取大量日志。
    使用mysqlbinlog命令行提取(适宜批量提取日志)。

  2. 语法

    直接查看单个二进制日志文件:
    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语句

其他说明

  1. 在数据出错的情况下,使用 MYSQLBINLOG 来恢复数据

5.3 迁移 5.6 需要注意的问题

👁代表额外需要注意的,✅代表遇到过

5.3 Migrating 5.4

重点

  1. breakcontinue不再接受可变参数(break 1 + max(x, y)),break 0;continue 0不允许出现
  2. 现在参数名使用全局变量将会导致一个致命错误。禁止类似 function foo($_GET, $_POST) {} 这样的代码。
  3. 非数字的字符串偏移量👁
    $a = '12345';
     var_dump(isset($a['x']); // 5.3 true, 5.4 false
  1. 调用时的引用传递👁
 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

一些不常用的

  1. 不支持安全模式
  2. 移除魔术引号
  3. register_globals 和 register_long_arrays php.ini 指令被移除。

    PHP: 不向后兼容的变更 - Manual

5.4 Migrating 5.5

重点

  1. 原始的 MySQL 扩展 现在被废弃,当连接到数据库时会产生一个 E_DEPRECATED 错误。👁

PHP: 不向后兼容的变更 - Manual

5.5 Migrating 5.6

重点

  1. json_decode 严格模式
  2. cURL文件上传 👁✅
    > 必须先设置 CURLOPT_SAFE_UPLOAD为 FALSE 才能够使用 @file 语法来上传文件。 建议使用 CURLFile 类来上传文件。
  3. 使用::调用非静态方法,现在产生 E_DEPRECATED 错误 (以前是 E_STRICT)
  4. 使用 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 的错误) 👁✅
  5. 使用数组标识符为类定义数组类型的属性时,数组的键不会被覆盖
    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"
}
*/

PHP: 向后不兼容 - Manual

其他问题

  1. 线上的php5.6没有编译fileinfo,这个会导致读不到文件信息,因为运维都是统一安装的,所以最好看一下是否enable-fileinfo

  2. 启用 Opcache,之前因为出现了一些问题,运维那边关掉这个缓存,最好和运维沟通,并测试缓存是否正确使用、正常更新。

    现代 PHP 新特性系列(六) —— Zend Opcache

vue+webpack多页面应用设置

整   理:晋 哲

时   间:2017-04-10

说   明:vue+cli脚手架默认搭建的是单页面应用,在实际项目中需要优化配置生成多页面。

设置步骤:
一、修改src文件结构
图一为脚手架默认生成的src结构
p1

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

比如:login文件夹里的三个文件是由原先的App.vue、main.js、index.html整合到一个文件夹内进行修改,welcome文件夹就是再复制一份修改

二、修改build内的文件配置
主要是调整webpack中html-webpack-plugin插件的默认设置,这是用来将js和html对应起来的插件
调整三处js文件,如下图:
p3

1、webpack.base.conf.js
(1)在头部添加下面两行代码

var glob = require('glob'); // 引入glob工具
var entries = getEntry('./src/module/**/*.js'); // 获得入口js文件

(2)再将entry的配置修改为entries
p6-1

(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;
}

p6-2

2、webpack.dev.conf.js
(1)在头部添加下面两行代码,引入path和glob工具

// 引入path和glob工具
var path = require('path');
var glob = require('glob');

(2)将HtmlWebpackPlugin默认设置注释掉
p7-1

(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));
}

p7-2

3、webpack.prod.conf.js
和上一个文件webpack.dev.conf.js中做类似的处理,先注释掉原来的HtmlWebpackPlugin,然后在下面添加函数,通过迭代插入多个HtmlWebpackPlugin。

三、最终生成的文件会打包进对应的文件夹内
对比默认生成文件结构与修改后生成文件
p1-1
QQ截图20170630174703

安装vue-cli脚手架构建项目步骤

整   理:晋 哲

时   间:2017-03-30

说   明:安装脚手架,编译生成最终用于实际项目的压缩文件

1、确认已经安装node环境和npm包管理工具,建议将 npm 的注册表源设置为国内的镜像,可以大幅提升安装速度。

npm install -g cnpm --registry=https://registry.npm.taobao.org

pic1

2、安装 vue
pic2

3、全局安装 vue-cli
pic3

4、创建一个基于 webpack 模板的新项目
pic4

5、安装依赖
$ cd my-project
$ npm install

6、实时运行项目,会自动打开一个浏览器窗口,默认访问localhost:8080
$ npm run dev
pic5
pic6

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

最终访问:http://192.168.0.249:8080
pic6_3
pic6_4

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

PHP闭包

闭包的介绍

闭包是词法作用域的体现,一般编程语言有这些特性

  1. 函数是一阶值(First-class value),即函数可以作为另一个函数的返回值或参数,还可以作为一个变量的值。
  2. 函数可以嵌套定义,即在一个函数内部可以定义另一个函数。

三个关键点

  1. 函数
  2. 自由变量
  3. 作用域

自由变量

let a = 1
let b = function(){
    console.log(a)
}

在这个例子里函数b因为捕获了外部作用域(环境)中的变量a,因此形成了闭包。 而由于变量a并不属于函数b,所以在概念里被称之为「自由变量」。

注意点:

  1. 在一些语言里,「捕获」这一行为还有一个特点:闭包只会捕获自由变量的引用。
  2. 在PHP中,需要使用use关键词显示调用自由变量

作用域

可以使用外部的「自由变量」,内部变量不能被访问,形成一个相对安全的访问环境

总结

  1. 记住定义当时的外部环境
  2. 封闭外部环境
  3. 延迟执行

基本使用

$func = function () {

};

$func();

$a = '1';
$func = function () use ($a) {

}

$func();

作用域

  1. 闭包拥有独立的作用域,基本等同普通函数
  2. 在方法中使用时,等同于实例的方法,可以直接使用$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),结果在运行的时候,直接出现了语法级别的报错。

查了一些资料发现了问题

  1. 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类

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界面