vueJs父子组件通信以及vue-resource的使用

整   理:晋 哲

时   间:2017-01-03

说   明:实例展示vueJs如何调取数据

一、父子组件基本代码块

/* 父组件 */
<div id="product_list">
    <nav-item></nav-item>
</div>

/* 子组件模块 */
<template id="nav-model">
    ……
</template>

/* 子组件对象 */
Vue.component('nav-item', {
    template: '#nav-model',
    ……
});

/* 主体构造器 */
var ins = new Vue({
    el: '#product_list',
    data: [
        ……
    ],
});

二、父子组件自定义事件,用于在组件树中通信
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件;
使用 $dispatch() 派发事件,事件沿着父链冒泡;
使用 $broadcast() 广播事件,事件向下传导给所有的后代。

三、常用父子组件通信方式
1、父组件向子组件传递数据
使用 Props 传递数据

2、子组件向父组件传递数据
使用 $on() 监听事件;
使用 $emit() 在它上面触发事件。

四、vue-resource的使用(在一个Vue实例内使用$http)
1、GET请求
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);

2、POST请求
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

参考网址:
http://vuejs.org.cn/guide/components.html#使用-v-on-绑定自定义事件
http://www.doc00.com/doc/1001004eg

实例代码请看源代码
vue实例-保险列表

01背包问题基础

编 写: zhangyue
时 间: 2016-12-27
说 明: 利用背包问题解决红包使用问题

一 01背包问题

    01背包问题是指在一个容量大小固定为M的背包中,装入体积和价值不同的宝石,怎么选择才能在背包中得到最大的价值。

二 动态规划

动态规划是指
        通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以一种循环的方式去解决。
        通常基于一个递推公式和一个或多个初始状态,当前子问题的解由上一个子问题的解推出。
        有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最        好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线
        
        状态转移方程:
            d(N,M) = max(d(N-1,M), d(N-1, M-weight(i)) + value(i));
            d(N,M) 有容量为M的背包,有N个宝石
            d(N-1,M) 当前的宝石不放入背包,所能获取的最大价值
            d(N-1, M-weight(i)) + value(i) 当前宝石放入背包,所能够获取的最大价值

三 代码

function getResult($bagItems, $bagSize) {
        var result = array();
        //生成状态数组
        foreach ($i = 0; $i < $bagSize; $i ++) {
            foreach ($j = 0; $j < count($bagItems); $j ++) {
                if ($bagItems[$j]['weight'] > $i) {
                    //当前重量大于当前背包总重量
                    if (j != 0) {
                        $result[$j][$i] = $result[$j-1][$i];
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = 0;
                    }
                } else {
                    //当前重量小于背包,可以放入背包
                    if ($j != 0 ) {
                        $tmp_value = $result[$j-1][$i - $bagItems[$j]['weight']] + $bagItems[$j]['weight'];
                        $result[$j][$i] = max($result[$j-1][$i], $tmp_value);
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = $bagItems[$j]['weight'];
                    }
                }
            }
        }

        //根据得到的状态得到所选的数组
        $return  = array();//存储放回的组合
        $cur_size = $bagSize;//当前红包容量
        for ($n = count($bagItems); $n >= 0 ; $n--) {
            if ($cur_size == 0) {
                break;
            } 

            if ($n == 0 && $bagItems[$n]['weight'] < $cur_size) {
                $return[] = $bagItems[$n]['id'];
                break;
            }

            if ($bagItems[$n][$cur_size] - $bagItems[$n-1][$cur_size - $bagItems[$n]['weight']] == $bagItems[$n]['weight']) {
                //判断当前的这个商品是不是在最优解里,如果不在则不放入
                $return[] = $bagItems[$n]['id'];
                $cur_size = $cur_size - $bagItems[$n]['weight'];
            }
        }

        //得到结果
        return $return;

    }

四 递推表格

函数得到的递推表格和最终最优结果:
体积 价值 0 1 2 3 4 5 6 7 8 9 10 11
4 4 0 0 0 0 4 4 4 4 4 4 4 4
5 5 0 0 0 0 4 5 5 5 5 9 9 9
6 6 0 0 0 0 4 5 6 6 6 9 10 11
解释: 1 表格是从上到下,即4-6,从左到右,即0-11生成的 2 第一行的意思:代表在0-11的背包容量下,只有一个体积为4价值为4的宝石时,所能获得最大容量 3 第二行的意思:代表在0-11的背包容量下,有一个体积为4价值为4和体积为5价值为5的两块宝石时,所能获得最大容量 4 第三行的意思:代表在0-11的背包容量下,有一个体积为4价值为4,体积为5价值为5,体积为6价值为6的三块宝石时,所能获得最大容量 5 最终结果:[6,11] = 11 这个最优解。

五 红包问题

使用红包时,只需要将价值和体积都类比于红包的金额即可,这样可以选出最后得到的红包使用组合。
存在问题:
    1 红包会涉及小数的问题,红包现在只保留两位小数,最简单的方法是给红包*100,这样会增加递推数组的大小,增加空间复杂度
    2 红包还存在过期时间,可考虑如何加上过期时间这一条件
    3 由于红包价格和体积是同一个值,可考虑简化算法

用户系统演进

用户系统演进.ppt

编   写:袁 亮
时   间:2016-12-21
说   明:用户系统演进

一、用户系统限制因素
    1、使用域名
        单个域名
        多个域名
    2、使用系统是单服务器还是多服务器
    3、使用域名是否属于同一个域名的不同子域名
    4、系统访问环境
        PC浏览器
        是否兼容IE浏览器
        是否兼容手机浏览器
    5、用户数据库是否唯一
        单一用户数据库
        多个用户数据库
        
二、单用户中心,单域名
    1、条件限制
        1.1 单个域名
        1.2 单一用户数据库
    2、实现方案
        2.1 session
            磁盘IO 
            多服务器session共享
        2.2 cookie
            域名,端口,路径,cookie名
            数据签名
            大小限制
            敏感信息
    3、其他
        3.1 可以有多种登陆方式
        3.2 可以接入很多种第三方登陆
        
三、单用户中心,单个根域名
    1、条件限制
        1.1 单个用户数据库
        1.2 多个域名同属于某个根域名
    2、实现方案
        2.1 cookie共享 (育儿网)
            a. cookie设置在根域名
            b. 所有子域名都可以正常读取并验证签名
            c. 不可扩展,安全性无保障
        2.2 token形式 (共享session机制的变种)
            a. cookie设置在根域名
            b. 子域名读取到cookie之后,调用用户中心接口获取用户数据
            c. 将用户数据写入当前域名下
            
四、单用户中心,多个根域名
    1、条件限制
        1.1 单个用户数据库
    2、实现方案
        2.1 单点登陆 jsonp方式跨域 (淘宝)
            a. 统一的登陆,查收ticket
            b. jsonp方式将ticket循环传递给所有业务
            c. 业务域名根据ticket获取用户信息设置登陆
            d. 退出同样方式处理
            缺点:
                ios下,浏览器默认禁止第三方域名cookie设置,直接歇菜
        2.2 单点登陆 cas方式 (新浪)
            a. 通过jsonp+ajax+iframe的方式,在各个子域名框用户中心登陆
            b. 
            缺点:手机浏览器对iframe支持的很差
        2.3 服务端ticket形式,jsonp形式单点登录的变种
        
五、多用户中心
    1、条件限制
        无
    2、实现方案
        2.1 单域名或者多根域名跨域同三和四
    3、额外增加处理
        3.1 统一跳转地址
        3.2 用户聚合统一
        3.3 平台信息维护
        3.4 vtoken登录

linux定时任务的设置 crontab

一、基本使用
#分 时 日 月 周
* * * * * /home/blue/do/rsyncfile.sh

二、语法
crontab [-u username] [-l|-e|-r]
选项与参数:
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作排程;
-e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容 (备份)
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑

三、crontab的限制
/etc/cron.allow:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;
/etc/cron.deny:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab 。

以优先顺序来说, /etc/cron.allow 比 /etc/cron.deny 要优先, 而判断上面,这两个文件只选择一个来限制而已,因此,建议你只要保留一个即可, 免得影响自己在配置上面的判断!一般来说,系统默认是保留 /etc/cron.deny ,你可以将不想让他运行 crontab 的那个使用者写入 /etc/cron.deny 当中,一个帐号一行!
crontab3

四、crontab的原理
crond服务的最低侦测限制是分钟,所以cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容,因此,只要你编辑完 /etc/crontab 这个文件,并且将他储存之后,那么 cron 的配置就自动的会来运行了!

执行脚本的用户:/var/spool/cron/
执行记录:/var/log/cron
crontab2

五、crontab 的格式

代表意义 分钟 小时 日期(天) 月份 周 命令
数字范围 0-59 0-23 1-31 1-12 0-7 执行的命令
周的数字为 0 或 7 时,都代表『星期天』的意思!

辅助字符

特殊字符 代表意义
*(星号) 任何时刻
,(逗号) 代表分隔时段
-(减号) 代表一段时间范围内
/n(斜线) 代表每隔n单位间隔

六、周与日月
周和日月不是 并 的关系,而是 或 的关系。

你可以分别以周或者是日月为单位作为循环,但你不可使用「几月几号且为星期几」的模式工作。
30 12 11 11 5 root echo "just test" <==这是错误的写法
本来你以为十一月十一号且为星期五才会进行这项工作,无奈的是,系统可能会判定每个星期五作一次,或每年的 11月 11 号分别进行。

测试:(12月8号为星期4)
25 18 08 12 4 (echo "just test1" >> /tmp/test.txt ) //执行一次
25 18 07 12 4 (echo "just test2" >> /tmp/test.txt ) //执行一次
25 18 08 12 5 (echo "just test3" >> /tmp/test.txt) //执行一次

七、& 后台执行命令
1. command & : 后台运行,你关掉终端会停止运行
2. nohup command & : 后台运行,你关掉终端也会继续运行

参考:http://www.cnblogs.com/lwm-1988/archive/2011/08/20/2147299.html

八、2>&1 含义
先看一个例子:
0 2 * * * echo "just test" >> /tmp/test.txt 2>&1 &
这句话的意思就是在后台执行这条命令,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null 文件,也就是清空。

注释:
数字的含义:
0表示 键盘输入
1表示 标准输出
2表示 错误输出
>>是追加内容
> 是覆盖原有内容

示例:
0 2 * * * sh /tmp/test.sh 1>/tmp/out.file &
0 2 * * * sh /tmp/test.sh 2>/tmp/out.file &
0 2 * * * sh /tmp/test.sh 2>/tmp/out.file 2>&1 &
1、将tesh.sh 命令输出重定向到out.file, 即输出内容不打印到屏幕上,而是输出到out.file文件中。
2、2>&1 是将错误输出重定向到标准输出。 然后将标准输入重定向到文件out.file。
3、&1 表示的是文件描述1,表示标准输出,如果这里少了&就成了数字1,就表示重定向到文件1。
4 、& :后台执行

测试:
ls 2>1 : 不会报没有2文件的错误,但会输出一个空的文件1;
ls xxx 2>1: 没有xxx这个文件的错误输出到了1中;
ls xxx 2>&1: 不会生成1这个文件了,不过错误跑到标准输出了;
ls xxx >out.txt 2>&1 == ls xxx 1>out.txt 2>&1: 因为重定向符号>默认是1,这句就把错误输出和标准输出都传到out.txt 文件中。

九、注意点:2>&1写在后面的原因
格式:command > file 2>&1 == command 1> file 2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。

如果改成: command 2>&1 >file
2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但错误输出仍然保持在终端。
crontab1

微信支付成功后推荐关注栏目规则

QQ图片20161129172427

官网QA:
1.刷卡支付默认有推荐关注;
2.公众号支付和扫码支付需要5元以上才有推荐关注;(0.01就有推荐栏,第一次5元以上默认选中)
3.APP支付默认没有,需要申请配置,需要有一定用户规模才可以申请;
4.已经关注的不展示推荐栏
5.服务号未设置头像的在IOS不展示推荐关注栏;
6.用户取消过关注的默认不勾选;
7.服务商模式的,需要在特约商户开发配置页设置推荐关注APP id;
8.订阅号目前是不会有默认推荐关注的;
9.对于粉丝数大于 50W的公众号,有消息链接,朋友圈链接,公众号发起的jsapi支付场景,支付成功后不默认勾选关注。

客服说明:
微信支付后默认选中关注微信公众号需要的额外条件
1、第一次消费
2、消费金额需要5元以上

JSONP

JSONP是什么

跨域资源共享(Resources Domain Resources Sharing),客户端从不同的域名发送JSON响应时绕过浏览器限制

JSONP原理解析

利用 script标签 的 src属性 进行跨域请求,服务器响应函数调用传参。

2.1 静态方法创建

代码:

<?php
 //echo "a = 1";
?>
//html代码
<script type="text/javascript" src="http://ly.yungou.ws/test/index"></script>
<script type="text/javascript">
    console.log(a);   // 1
</script>

跨域请求成功!

2.2、 动态方法创建

动态创建 script标签的方式,添加到头部,来获取变量参数

<?php
    echo "var a = 1;";
 ?>

//通过 script语句动态创建 script标签进行请求
<script type="text/javascript">
   var script = document.createElement('script');
   script.src = 'http://ly.yungou.ws/test/index';
   var head = document.getElementsByTagName('head')[0];
   head.appendChild(script);
   console.log( a );
</script>

注意:原来动态创建 script 的方式发送请求 是异步的,虽然请求成功了,但是在使用变量时,请求还没有完成,相当于还没有定义变量,然后就报错了。
解决办法:使用callback

<?php
    echo 'callback(123)';
 ?>

<script type="text/javascript">
    var script = document.createElement('script');
    script.src = 'http://ly.yungou.ws/test/index';
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);

    function callback(data){
        console.log( data );    //callback(123) 对 callback 调用 输出 123
    }
</script>

那我们就可以用这种动态的方式 很轻松的 拿到后台数据了,只不过前台声明的和 后台 调用的 函数名 需要一样才行,如上面的 然而这样也不太好,每次改动,那都要前后台对接一下。

所以我们可以把回调函数名放在参数中传输。案例如下:

<?php
$callback = $_GET[ 'callback' ];    // get 通过 callback键 得到 函数名
$userInfo = array( 'username' => 'leiyuan', 'password' => '123456' );// 生成数据
$data = json_encode($userInfo);
echo "{$callback}({$data});";// hello( json_encode($arr) )

通过 script语句动态创建 script标签进行请求

    var script = document.createElement('script');
    script.src = 'http://ly.yungou.ws/test/callback?callback=hello';
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(script);
     function hello(data){
        console.log(data);// Object {username: "leiyuan", password: "123456"}        
    }
  </script>

2.3 jsonp原理:

JSONP是一个协议(并且是非正式传输协议)。 该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了.
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求,

2.4 jsonp原理

首先在客户端注册一个callback, 然后把callback的名字传给服务器。
服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

JSONP和JSON的区别:
目前为止最被推崇或者说首选的方案还是用JSON来传数据,靠JSONP来跨域。
  JSON(JavaScript Object Notation)和JSONP(JSON with Padding)
JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。一个是描述信息的格式,一个是信息传递双方约定的方法。
  1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery等框架都把jsonp作为ajax的一种形式进行了封装;
  2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加
```

JSONP使用注意事项
1、跨系统跨域名,获取基本信息,
ps:后端不能存在任何页面跳转登陆信息,否则会请求失败
2、jsonp的缺陷:不提供错误处理(对方拒绝请求,网络不通,请求地址或者参数不正确等等)如果动态插入的代码正常运行,你可以得到返回,但是如果失败了,那么什么都不会发生。
3、动态请求,都是异步请求。不支持同步请求,async无效。
请求不是通过XHR完成的,而是动态创建script标记,并请求url。跨域请求和dataType: "jsonp" 本身不支持同步操作。
4、若要在fun中使用jsonp请求后的参数,需要注意的是执行顺序,fun需要写在callback中才能成功调用参数。
5、如果没有定义jsonp和jsonpCallback,jsonp默认为"callback",jsonpCallback会是Jquery自动生成的函数名。
6、请求返回的是script tag,首先会调用jsonpCallback函数,不管是否找到该函数,都会调用success函数

参考资料

http://api.jquery.com/jQuery.ajax/

vuejs基础

整   理:肖雅君

时   间:2016-11-18

说   明:vue.js的安装、基本用法

官网:http://vuejs.org.cn/

1.安装
安装npm,建议安装cnpm,超超快速。
淘宝镜像:npm install -g cnpm --registry=https://registry.npm.taobao.org
安装vue:npm install -g vue-cli【cnpm install -g vue-cli】

2.初始化:
vue init webpack vueTest
[项目类型]-如:使用webpack这个模板,进行压缩和打包

依次输入:项目名
项目描述
项目开发者
是否使用语法检测工具
是否进行单元测试
是否进行集成测试

3.下载依赖:cnpm install
下载完毕后,打开项目,一般所需修改的页面文件在src文件夹下,打开package.json文件,能看到我们在初始化项目的时候,输入的项目名、开发者等信息,如下图:
6

其中src文件夹下有个component文件夹,是专门安置自己封装的组件,引用这些组件的时候,直接在src文件夹下app.vue中引入,如下图:
7

4.在项目文件夹下运行项目:npm run dev
注:需要npm的版本在3.0.0,否则error。
升级npm:npm -g install nom@3.0.0 [用npm依旧是等待很长时间没反应,用cnpm很快]
1
升级完成后运行,浏览器自动跳转到8080端口打开测试页:
2

5.项目的页面是src文件下的 app.vue,修改这个文件夹即可。
另,后缀是.vue文件,在用brackets 或者sublime软件编辑的时候,需要安装对应的插件,才可显示高亮。
brackets vue插件:http://brackets.dnbard.com/extension/brackets.vue
sublime vue 插件: Vue Syntax highlight/Jade

6.重要指令:
new 一个vue对象时,可以设置:
(1)对象的属性:
数据:data
方法:method
监听:watch
new Vue()对象,注意大小写。new vue()无效。
(2)关联:
模板html页面和vue对象的粘合,用模板指令v-text、v-html进行数据渲染
(3)控制显示和隐藏:v-if、v-show
v-if通过控制dom结构控制显隐。v-show:控制css样式的display来控制显隐。
(4)循环渲染:v-for
(5)事件绑定:v-on
<button v-on:click = "doThis"></button>
简写:
<button @click = "doThis"></button>
(6)属性绑定:v-bind
<img v-bind:src="imageSrc" :class="{ red: isRed }"/>

7.基本功能和应用:
(1)数据的双向绑定
(2)v-show和v-if的使用
(3)事件处理
(4)组件化方法
(5)代码逻辑或者业务逻辑的输出处理:computed
(6)列表输出
(7)组件化综合应用:列表输出 + 组件化结合
(8)添加任务总数和删除任务
(9)jquery 、ajax 和vue的结合
(10)vue-resource插件的使用

8.代码demo
(1)数据的双向绑定

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>{{myhead}}</h1>
    <h1 v-text="mytext"></h1>
    <input type="text" v-model="mytext" />
    <!--打印出data里的代码,测试双向绑定过程-->
    <pre>
            {{$data | json}}
    </pre>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            myhead:'你好!',
            mytext:'My name is Michellya!'
        }
    });
</script>
</body>
</html>

(2)v-show和v-if的使用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
    <h1>{{myhead}}</h1>
    <h1 v-text="mytext"></h1>
    <p v-if="!mytext">警告:请填写内容!</p>
    <input type="text" v-model="mytext" />
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            myhead:'你好!',
            mytext:''
        }
    });
</script>
</body>
</html>

(3)事件处理

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
    <button @click="mysubmit">submit</button>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            myhead:'你好!',
            mytext:''
        },
        methods:{
            mysubmit:function(){
                alert(11);
            }
        }
    });
</script>
</body>
</html>

(4)组件化

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
<!--组件化:1.自己定义组件-->
    <mylabel mychoice="赞" bgcolor="red"></mylabel>
    <mylabel mychoice="嘘" bgcolor="blue"></mylabel>

<!--2.用h5的新标签template  组件封装——应用1:类似微博的喜欢、不喜欢的点选计数-->
    <template id="choice-model">
        <h3>{{mychoice}}</h3>
        <button @click="num += 1" style="background:{{bgcolor}}">{{num}}</button>
    </template>        
</div>

<script>
    Vue.component('mylabel',{
        template: '#choice-model',
        props:['mychoice','bgcolor'],
        data:function(){
            return {num : 0}
        }
    });

    new Vue({
        el: '#app',
    });
</script>
</body>
</html>

(5)代码逻辑或业务逻辑的输出处理:computed

应用1:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
<!--        level {{level <= 100 ? '普通会员' : 'VIP会员'}}  -->

    level {{level}}
</div>

<script>
/*
    new Vue({
        el: '#app',
        data: {
            points: 200,
            level: '普通会员'
        }
    });
*/
    new Vue({
        el: '#app',
        data: {
            points: 200,
        },
        computed:{
            level:function(){
                if(this.points <= 100){
                        return '普通会员';
                }
                return 'VIP会员';
            }
        }
    });
</script>
</body>
</html>

应用2:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
        p{color:#f00;}
</style>
</head>
<body>
<div id="app">
    用户名:{{username}}
    <br/>
    <input type="text" v-model="first" />
    <input type="text" v-model="second" />
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            first: 'Michelle',
            second: 'yajun',
        },
        computed:{
            username:function(){
                return this.first + ' ' + this.second;
            }
        }
    });
</script>
</body>
</html>

(6)循环列表输出

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
    <ul>
<!--                <li :class="task.completed ? 'mydone' : '' " v-for="task in tasks">{{task.body}}</li>-->
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in tasks"
                @click = "toggleclick(task)">{{task.body}}</li>
    </ul>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            tasks:[
                 {body:'sleeping',completed:false},
                 {body:'shopping',completed:true},
                 {body:'swimming',completed:true},
                 {body:'running',completed:false},
            ]
        },
                methods:{
            toggleclick:function(task){
                task.completed = !task.completed;
            }
        }
    });
</script>
</body>
</html>

(7)组件化list综合应用:todo应用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
    <mytask :list="tasks"></mytask>
    <mytask :list="[{body:'唱歌',completed:true},{body:'跳舞',completed:false},]"></mytask>
    <mytask :list="tasks"></mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">{{task.body}}</li>
    </ul>
</template>
</div>

<script>
Vue.component('mytask',{
        template: '#mytask-model',
        props: ['list'],
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            }
        }
    });

    new Vue({
        el: '#app',
        data: {
            tasks:[
                {body:'sleeping',completed:false},
                {body:'shopping',completed:true},
                {body:'swimming',completed:true},
                {body:'running',completed:false}
            ]
        }
    });
</script>
</body>
</html>

(8)添加任务总数、删除任务和添加任务

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://vuejs.org.cn/js/vue.js"></script>
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">     
    <mytask :list="tasks"></mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <h1>My Task <span v-show="remaining">({{ remaining}})</span></h1>
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">{{task.body}}
                <strong @click="deleteTask(task)">点我删除</strong>        
        </li>        
    </ul>
</template>
</div>

<script>
    Vue.component('mytask',{
        template: '#mytask-model',
        props: ['list'],
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            },
            deleteTask:function(task){
                this.list.$remove(task);
            }
        },
        computed:{
            remaining:function(){
                return this.list.filter(function(task){
                    return ! task.completed;
                }).length;
            }
        }
    });

    new Vue({
        el: '#app',
        data: {
            tasks:[
                {body:'sleeping',completed:false},
                {body:'shopping',completed:true},
                {body:'swimming',completed:true},
                {body:'running',completed:false}
            ]
        }
    });
</script>
</body>
</html>

(9)jquery 、ajax 和vue的结合
3

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
        
    <mytask>{{ $task }}</mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <h1>My Task <span v-show="remaining">({{ remaining}})</span></h1>
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">@{{task.body}}
                <strong @click="deleteTask(task)">点我删除</strong>        
        </li>        
    </ul>
</template>
</div>
<script src="http://vuejs.org.cn/js/vue.js"></script>
<script src="http://file2.ci123.com/ast/js/jquery_172.js"></script>
<script>
    Vue.component('mytask',{
        template: '#mytask-model',
        //创建一个空list数组
        data:function(){
            return {
                list:[]
            }
        },
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            },
            deleteTask:function(task){
                this.list.$remove(task);
            }
        },
        computed:{
            remaining:function(){
                return this.list.filter(function(task){
                    return ! task.completed;
                }).length;
            }
        },
        create:function(){
           $.getJSON('api/...',function(data){
                this.list = data; 
            })
        }
    });

    new Vue({
        el: '#app'
    }
});
</script>
</body>
</html>

(10)vue-resource插件的使用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue js - Michellya</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style>
    p{color:#f00;}
    .mydone{text-decoration:line-through;}
    .nodone{color:coral;}
</style>
</head>
<body>
<div id="app">
        
    <mytask></mytask>

<!--组件化:将每日任务变成组件list-->
<template id="mytask-model">
    <h1>My Task <span v-show="remaining">({{ remaining}})</span></h1>
    <ul>
        <li :class="{'mydone':task.completed,'nodone':!task.completed }" 
                v-for="task in list"
                @click = "toggleclick(task)">@{{task.body}}
                <strong @click="deleteTask(task)">点我删除</strong>        
        </li>        
    </ul>
</template>
</div>

<script src="http://vuejs.org.cn/js/vue.js"></script>
<script src="https://github.com/vuejs/vue-resource"></script>

<script>
    Vue.component('mytask',{
        template: '#mytask-model',
        data:function(){
            return {
                list:[]
            }
        },
        methods: {
            toggleclick:function(task){
                task.completed = !task.completed;
            },
            deleteTask:function(task){
                this.list.$remove(task);
            }
        },
        computed:{
            remaining:function(){
                return this.list.filter(function(task){
                        return ! task.completed;
                }).length;
            }
        },
        create:function(){
            this.$http.get('api/...',function(){

            })
        }
    });

    new Vue({
        el: '#app',
    });
</script>
</body>
</html>

9.强荐浏览器插件:vue-devtools
作用、操作及下载:http://www.cnplugins.com/devtool/vuejs-devtools/
插件:
4
界面:
5

Json的使用

一、简介
JSON:JavaScript 对象表示法
JSON 是存储和交换文本信息的语法。类似 XML。
JSON 比 XML 更小、更快,更易解析。
JSON的媒体类型被定义为 application/json,而文件的后缀为.json。

二、应用
JSON的应用
1、接口
2、微信开发

XML的应用
1、我们一般用于sitemap较多
2、xmlrpc是使用http协议做为传输协议的rpc机制,使用xml文本的方式传输命令和数据。
备注:json和XML可以互转

和JavaScript

一、JSON - 转换为 JavaScript 对象
1、能够使用内建的 JavaScript eval(string)方法进行解析
原因:JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。
由于这种相似性,无需解析器,JavaScript 程序能够使用内建的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象。

ajax返回的是字符串,而不是json对象。
data = eval('('+data+')');

二、实例
var JSONObject=
{
"name":"Bill Gates", "street":"Fifth Avenue New York 666", "age":56, "phone":"555 1234567"
};

JSONObject.name //调用
三、语法规则
数据在名称/值对中
数据由逗号分隔
花括号保存对象
方括号保存数组
值/对象/数组

四、方法
1、JSON.parse()
parse用于从一个字符串中解析出json对象

例子:
var str = '{"name":"huangxiaojian","age":"23"}'
结果:
JSON.parse(str)
Object
age: "23"
name: "huangxiaojian"
proto: Object

2、JSON.stringify()
stringify()用于从一个对象解析出字符串

例子:
var a = {a:1,b:2}
结果:
JSON.stringify(a)
"{"a":1,"b":2}"

五、错误提示
1、
1
data不是正确的json格式,造成解析出错
2、
2

var a=JSON.parse('{"a":"aaaaa"}');//正确
var a=JSON.parse("{'a':'aaaaa'}");//错误

3、 Uncaught TypeError: Cannot use 'in' operator to search for '' in JSON string
解决方案:JSON字符串转换为JavaScript对象。
要修复它,通过标准JSON.parse()或jQuery 的 $.parseJSON 将其转换为JavaScript对象。
4、
4
var a = { };
var b = { a: a };
a.b = b;
JSON.stringify(a);

参考:https://segmentfault.com/a/1190000002532027

php中的json
一、注意点
1、json_last_error:返回最后发生的错误
2、json_decode 当第二个参数为 TRUE 时,将返回 array 而非 object 。
3、由于json只接受utf-8编码的字符,所以json_encode()的参数必须是utf-8编码,否则会得到空字符或者null。

4、PHP支持两种数组,一种是只保存"值"(value)的索引数组(indexed array),另一种是保存"名值对"(name/value)的关联数组(associative array)。
由于javascript不支持关联数组,所以json_encode()只将索引数组(indexed array)转为数组格式,而将关联数组(associative array)转为对象格式。
$arr = array('one', 'two', 'three');
echo json_encode($arr); //["one","two","three"]

$arr = array('1'=>'one', '2'=>'two', '3'=>'three');
echo json_encode($arr); // {"1":"one","2":"two","3":"three"}
数据格式从"[]"(数组)变成了"{}"(对象)。
如果你需要将"索引数组"强制转化成"对象",可以这样写
echo json_encode((object)$arr);
echo json_encode($arr,JSON_FORCE_OBJECT )

5、类的转换

{     
  "public_ex": "this is public" 
 }

除了公开变量(public),其他东西(常量、私有变量、方法等等)都遗失了。

二、错误
  $json = "{ 'bar': 'baz' }";      //分割符只能用单引号  
$json = '{ bar: "baz" }';        
$json = '{ "bar": "baz", }';

二、中文编码的问题
1、
function getJson($data){
if(version_compare('5.4',PHP_VERSION,'<')){
//5.4以上
return json_encode($data,JSON_UNESCAPED_UNICODE);
}else{
return urldecode(json_encode(url_encode($data)));
}
}

数据存的json格式,如果数据库存的是array
eval("\$session= $str;");

三、json格式的问题
微信放的json解析不了:
去除反斜杠 StripSlashes

其他补充:
json的校验
一个文本文档或字符串必须遵守JSON的语法定义,才能被视作一个有效的JSON文档。
http://www.jsonlint.com/
补充:
用 JSON 构建 API 的标准指南中文版
http://jsonapi.org.cn/

bug来源与如何避免

前提更要:从初来乍到,到熟悉业务核心代码。总有一天我们要去更改或者升级核心内容,对于逻辑复杂业务繁多的功能模块或者是流程,如何能够完成更改或者升级,且避免bug的出现,保正新旧业务流程能够正常使用。
目录

bug来源与如何避免
目录
一、修复现有的bug
二、首次开发新项目
三、二次开发
栗子:

优惠券使用经历4次bug修改
满减赠的二次开发:增加N元任,选前台购买涉及到分摊优惠,对分摊优惠进行重新整理(在尽量不改的原有的其他功能的逻辑的基础上,对代码整合个更改,便于可读和后期的再次开发)
抢购超卖的问bug,库存不足,则返回生成订单失败
一、修复现有的bug

步骤:bug怎么产生的 -> 快速定位 -> 熟悉代码 -> 改bug ->测试bug

开发前须知:
1.1 bug是如何提出来源:用户、不正常的数据、运营、开发人员操作
1.2 快速定位:(apache的错误日志、重现操作、数据库错误数据)
1.3 熟悉原有的代码逻辑,清楚了解如何更改现有的代码
开发后测试
2.1 该bug是否对原有的逻辑流程或者数据造成影响(较难,主要是细心)
2.2 除了此bug外,造成bug的因素是否还存在一定的潜在影响
2.2 改完后,会不会导致其他的功能不能正常使用,(必须测试)
例子一:优惠券分摊不均衡,10元优惠券分摊到两个价格相同的商品上,分摊金额是2.5 :7.5 应该是 5:5
例子二:检查订单是否能使用某张优惠券,以用户已经领取到的优惠券为判断依据
coupon,user_coupon
ps:优惠券使用经历4次bug修改

二、首次开发新项目

开发前须知
1.1 熟悉需要开发的内容
1.2 列需求文档、api接口
开发后测试
2.1 测试各个接口
2.2 所有需要走的逻辑流程是否正确
优点:对开发内容和功能了如指掌,确保接口程序无误即可
缺陷:初次开发,考虑简单需求,虽尽可能完善,但仍会有某些功能忽略掉,后期会进行二次开发
三、二次开发

难点:必须熟悉项目整理流程

开发前须知:
1.1 熟练掌握现有的功能和代码逻辑
1.2 了解二次开发目的和内容
1.3 清楚二次开发的程序如何写,且尽可能不影响原有的功能(是在原有的基础上扩充还是另写,或者合并)
开发后测试
2.1 局部测试:新增的功能是否能正常使用,所更改的代码是否对原有的逻辑造成影响
2.2 全局测试:对原有的功能进行测试,
缺点:对原有的功能块和程序逻辑不熟悉;若代码逻辑负责,业务繁琐,修改很容易出错;因新增加功能,对代码进行整合,也很容易出问题
注意:逻辑过于复杂的话,测试时不可能每种情况都测试到,所以需要自己审核代码

grep和find命令的基本用法:

grep命令:文本搜索

命令格式 : grep [options] pattern files
pattern 即 匹配的条件

[options]主要参数:
-c:只输出匹配行的计数。
-i:不区分字符大小写。默认区分大小写
-h:查询多文件时不显示文件名,显示文件的内容。
-l:查询多文件时只输出包含匹配字符的文件名。
-L:列出不匹配的文件名,
-n:显示匹配行及行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。

pattern正则表达式主要参数:
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达 式的行开始。
>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
* :有字符,长度可以为0。

files 即 匹配的文件地址 获取当前目录的地址可以使用 ./,也可以使用绝对地址/opt/.....

一些有意思的匹配:
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

find命令:文件搜索

命令格式:find pathname -options [-print -exec -ok ...]
参数:
pathname: find命令所查找的目录路径。例如用.来表示当前目录,也可以使用绝对地址

-print: find命令将匹配的文件输出到标准输出。

-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' { } ;,注意{ }和;之间的空格。

-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

使用print将参数输出到下一条命令,使用exec或ok来执行shell命令

[options]一些常用的命令选项:
-name 按照文件名查找文件。
-perm 按照文件权限来查找文件。
-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-mtime -n +n 按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件。
-type 查找某一类型的文件,诸如:
b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-mount:在查找文件时不跨越文件系统mount点。
-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。

另外,下面三个的区别:

-amin n 查找系统中最后N分钟访问的文件
-atime n 查找系统中最后n24小时访问的文件
-cmin n 查找系统中最后N分钟被改变文件状态的文件
-ctime n 查找系统中最后n
24小时被改变文件状态的文件
-mmin n 查找系统中最后N分钟被改变文件数据的文件
-mtime n 查找系统中最后n*24小时被改变文件数据的文件

find命令实例:
1.在当前目录及子目录中,查找大写字母开头的txt文件
find . -name '[A-Z]*.php' -print

2.在当前及其子目录中,查找test开头的文件
find . -name 'test*' -print

3.在当前目录及子目录中,查找不是out开头的php文件
find . -name "out" -prune -o -name ".php" -print

4.查找2天内被更改过的文件
find . -mtime -2 -type f -print

5.查找超过1M的文件
find . -size +1M -type f -print

6.用grep命令在当前目录下的所有普通文件中搜索hostnames这个词
find . -name * -type f -print | xargs grep "host"

7.删除指定目录下带有“我是”的文件
find ./* - name "*.php" -print | xargs grep -l "我是" | xargs rm -rf