头部背景图片
小畅的学习笔记 |
小畅的学习笔记 |

Vue.js学习笔记Day2-4.24

Vue.js学习笔记Day2-4.24

今日主要学习内容:

  • 品牌列表案例;
  • 全局过滤器和私有过滤器;
  • 自定义按键修饰符;
  • 自定义指令;
  • Vue实例的生命周期;
  • vue-resource 实现 get, post, jsonp请求;
  • 配置本地数据库和数据接口API;

开始Vue框架的学习吧~

一、品牌列表案例

  1. 1.x 版本中的filterBy指令,在2.x中已经被废除:
    filterBy - 指令

    1
    2
    3
    4
    5
    6
    7
    8
    <tr v-for="item in list | filterBy searchName in 'name'">
    <td>{{ item.id }}</td>
    <td>{{ item.name }}</td>
    <td>{{ item.ctime }}</td>
    <td>
    <a href="#" @click.prevent="del(item.id)">删除</a>
    </td>
    </tr>
  2. 在2.x版本中手动实现筛选的方式

  • 筛选框绑定到 VM 实例中的 searchName 属性:

    1
    2
    <hr> 输入筛选名称:
    <input type="text" v-model="searchName">
  • 在使用 v-for 指令循环每一行数据的时候,不再直接 item in list,而是 in 一个 过滤的methods 方法,同时,把过滤条件searchName传递进去:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <tbody>
    <tr v-for="item in search(searchName)">
    <td>{{ item.id }}</td>
    <td>{{ item.name }}</td>
    <td>{{ item.ctime }}</td>
    <td>
    <a href="#" @click.prevent="del(item.id)">删除</a>
    </td>
    </tr>
    </tbody>
  • search 过滤方法中,使用 数组的 filter 方法进行过滤:

    1
    2
    3
    4
    5
    search(name) {
    return this.list.filter(x => {
    return x.name.indexOf(name) != -1;
    });
    }

二、过滤器

概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;

1.私有过滤器HTML元素:
1
<td>{{item.ctime | dataFormat()}}</td>

私有 filters 定义方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
filters:{ 
//定义私有过滤器,过滤器有两个条件,【过滤器名称和处理函数】
    //注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
    dateFormat:function(dateStr,pattern = ''){
        var dt = new Date(dateStr);
        // yy-mm-dd
        var y = dt.getFullYear();
        var m = (dt.getMonth()+1).toString().padStart(2,'0');
        var d = dt.getDate().toString().padStart(2,'0');

        if (pattern && pattern.toLowerCase() === 'yyyy-mm-dd'){
            return `${y}-${m}-${d}`;
        }
        // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
        // 否则,就返回 年-月-日 时:分:秒
        else{
            var hh = dt.getHours().toString().padStart(2,'0');
            var mm = dt.getMinutes().toString().padStart(2,'0');
            var ss = dt.getSeconds().toString().padStart(2,'0');
            return `${y}-${m}-${d} ${hh}:${mm}:${ss}~~~`;
        }
    }
}

使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString=’’) 或 String.prototype.padEnd(maxLength, fillString=’’)来填充字符串,例如.toString().padStart(2,’0’)用于不满两位数字则向前补零。

2.全局过滤器HTML元素:
1
<td>{{item.ctime | dateFormat()}}</td>

全局 filters 定义方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 创建一个全局的过滤器,进行事件的格式化
Vue.filter('dateFormat',function(dateStr,pattern){
// 根据给定的字符串得到特定时间
    var dt = new Date(dateStr);
    // yy-mm-dd
    var y = dt.getFullYear();
    var m = dt.getMonth()+1;
    var d = dt.getDate();
    // return y + '-' + m + '-' + d;
    // return `${y}-${m}-${d}`;

    if (pattern && pattern.toLowerCase() === 'yyyy-mm-dd'){
        return `${y}-${m}-${d}`;
    }
    // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
    // 否则,就返回 年-月-日 时:分:秒
    else{
        var hh = dt.getHours();
        var mm = dt.getMinutes();
        var ss = dt.getSeconds();
        return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
    }
})

注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!

Vue调试工具vue-devtools的安装步骤和使用

Vue.js devtools - 翻墙安装方式 - 推荐

三、自定义按键修饰符

1.直接使用按键码的别名

1
<input type="text" class="form-control" v-model="name" @keyup.enter="add">

Image1.png

2.使用js里面的键盘事件对应的键码

1
<input type="text" class="form-control" v-model="name" @keyup.13="add">

js里面的键盘事件对应的键码:http://www.cnblogs.com/wuhua1/p/6686237.html

3.通过Vue.config.keyCodes.名称 = 按键值来自定义案件修饰符的别名:

1
<input type="text" class="form-control" v-model="name" @keyup.f2="add">

自定义键盘修饰符
Vue.config.keyCodes.f2 = 113;

相关文章
  1. vue.js 1.x 文档
  2. vue.js 2.x 文档
  3. String.prototype.padStart(maxLength, fillString)
  4. js 里面的键盘事件对应的键码
  5. Vue.js双向绑定的实现原理

四、自定义指令

1.传统使用DOM方法进行定义指令

1
<input type="text" class="form-control" v-model="keywords" id="search">

中使用DOM方法进行定义
document.getElementById(‘search’).focus();

2.使用 vue.directive()定义全局的指令 ,其中参数一是指令的名称
使用 vue.directive()定义全局的指令注意:
在定义的时候,指令的名称前面,不需要加v-前缀,但在调用的时候,必须在指令名称前加上v-前缀进行调用
参数二是一个对象,在这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
Image2.png

1. 和JS行为有关的操作,最好在inserted中去执行,防止JS行为不生效,如v-focus
在每一个函数中,第一个参数永远是el,表示被绑定了指令的那个元素,这个el参数,是一个原生的JS对象(DOM对象)
在元素刚绑定指令的时候,还没有插入到DOM中去,这时候调用focus方法没有作用
因为一个元素只有插入DOM之后,才能获得焦点,所以要用inserted

1
<input type="text" class="form-control" v-model="keywords" id="search" v-focus>
1
2
3
4
5
6
7
8
9
10
Vue.directive('focus',{
    bind:function(el){ //每当指令绑定到元素上时,会立即执行这个bind指令,只执行一次
    //el.focus()
    },
    inserted: function(el){ //表示元素插入到DOM中的时候,会执行inserted函数,只触发一次
        el.focus() ;
    },
    updated: function(){ //当vnode更新的时候会执行updated,可能会触发多次
    },
})

2. 和样式相关的操作,可以放在bind中去执行,如v-color
样式:只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
将来元素肯定会显示到页面中,这时候浏览器的渲染引擎必然会解析样式,应用给这个元素
Image3.png

1
<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'blue'">
1
2
3
4
5
6
7
8
9
10
//设置一个定义字体颜色的指令
Vue.directive('color' ,{
    bind:function(el,binding){
    //el.style.color='red';
        console.log(binding.name); //输出的是样式名color
        console.log(binding.value); //输出的是计算后的参数blue
        console.log(binding.expression); //输出的是原本的参数'blue'
        el.style.color = binding.value;
    }
})

3. 函数简写
在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:

1
<h3 v-color="'pink'" v-fontweight="900" v-fontsize="'30px'">{{ dt |dateFormat() }}</h3>

1
2
3
4
5
6
7
8
9
10
11
12
directives:{ //定义私有过滤器,定义在vm2实例中
    'fontweight':{
        bind: function(el,binding){
        el.style.fontWeight = binding.value;
        }
    },
    'fontsize':function(el,binding){
        el.style.fontSize= parseInt(binding.value) + 'px';
    }
}

parseInt(binding.value) + 'px';用于解析输入的字符串,将'30px'解析成数字30,增强代码的健壮性

五、Vue实例的生命周期

什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
生命周期钩子:就是生命周期事件的别名而已;
生命周期钩子 = 生命周期函数 = 生命周期事件
Image4.png

主要的生命周期函数分类:

  • 创建期间的生命周期函数:
    • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
    • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
    • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
    • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
  • 运行期间的生命周期函数:
    • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
    • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
  • 销毁期间的生命周期函数:
    • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
    • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

六、vue-resource 实现 get, post, jsonp请求

  • 除了 vue-resource 之外,还可以使用 axios 的第三方包实现数据的请求
  • 之前的学习中,如何发起数据请求?
  • 常见的数据请求类型? get post jsonp
  • 测试的URL请求资源地址:
    get请求地址: http://vue.studyit.io/api/getlunbo
    post请求地址:http://vue.studyit.io/api/post
    jsonp请求地址:http://vue.studyit.io/api/jsonp

  • JSONP的实现原理
    由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;
    可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求);
    具体实现过程:

    • 先在客户端定义一个回调方法,预定义对数据的操作;
    • 再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
    • 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;
    • 客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了;
      带大家通过 Node.js ,来手动实现一个JSONP的请求例子;
  • vue-resource 的配置步骤:
    直接在页面中,通过script标签,引入 vue-resource 的脚本文件;
    注意:引用的先后顺序是:先引用 Vue 的脚本文件,再引用 vue-resource 的脚本文件;

    1
    2
    <script src="./lib/vue-2.4.0.js"></script>
    <script src="./lib/vue-resource-1.3.4.js"></script>

七、配置本地数据库和数据接口API

  • 先解压安装 PHPStudy;
  • 解压安装 Navicat 这个数据库可视化工具,并激活;
  • 打开 Navicat 工具,新建空白数据库,名为 dtcmsdb4;
  • 双击新建的数据库,连接上这个空白数据库,在新建的数据库上右键 -> 运行SQL文件,选择并执行 dtcmsdb4.sql 这个数据库脚本文件;如果执行不报错,则数据库导入完成;
  • 进入文件夹 vuecms3_nodejsapi 内部,执行 npm i 安装所有的依赖项;
  • 先确保本机安装了 nodemon, 没有安装,则运行 npm i nodemon -g 进行全局安装,安装完毕后,进入到 vuecms3_nodejsapi目录 -> src目录 -> 双击运行 start.bat
  • 如果API启动失败,请检查 PHPStudy 是否正常开启,同时,检查 app.js 中第 14行 中数据库连接配置字符串是否正确;PHPStudy 中默认的 用户名是root,默认的密码也是root
Lililich's Blog