vue1-day2

小碎片

1、在vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了。
2、在vue中,已经实现了数据的双向绑定,每当我们修改了data中的数据,vie会默认监听到数据的改动,自动把最新的数据应用到页面上。
3、之前,v-for中的数据都是直接从data上的list直接渲染过来的;现在我们自定义了一个serch方法,同时,把所有的关键字,通过传参的形式,传递给了search方法。
4、forEach、some、filter、findIndex 这些都属于数组的新方法,都会对数组中的每一项,进行遍历,执行相关的操作。
5、ES6中,为字符串提供了一个新的方法,叫做string.prototype.includes(‘要包含的字符串’);如果包含,则返回true,否则返回false。

全局过滤器

vue允许自定义被过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache插值和v-bind表达式。过滤器应该被添加在js表达式的尾部,有管道标识符标识

要输出的内容和定义的内容有差别,就可以用过滤器来进行格式化的改变。只是改变输出格式的变化,数据本身没有变化。

在实例之前进行定义

过滤器调用的格式

1
{{ name | 过滤器的名称 }}

定义过滤器

1
vue.filter('过滤器的名称'function(data){})

过滤器中的function,第一个参数已经被规定死了,永远都是过滤器管道符前面传递过来的数据。其他位置可以进行传参,也可以进行多个传参。

过滤器也可以多个一起使用,比如

1
{{ msg | msgFormat('疯狂','123') | test }}

结果是,先调用第一个过滤器,把第一个过滤器的结果再作为第二个过滤器的参数进行调用。

所谓的全局过滤器就是所有的vm实例都可以共享。

私有过滤器

直接在vm实例内部进行定义

1
2
3
4
5
6
7
8
9
10
var vm = new Vue({
el:'#app',
data:{
dt:new Date()
},
methods:{},
filters:{
dateFormat:function(dataStr){}
}
})

定义私有过滤器,过滤器有两个条件:过滤器名称和处理函数。
过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称抑制了,这时候优先调用私有过滤器。

1
2
使用ES6中的字符串新方法String.prototype.padStart(maxLength,dillString='')
String.prototype.padEnd(maxLength,fillString='')来填充字符串

第一个参数表示填充的最大长度是多少,例如如果是2的话,那么小于2的字符串就会被填充,第二个参数表示用什么来进行填充。分别表示在前面填充和在后面填充。这个可以用来进行时间格式化。

注意:全局的过滤器定义的时候不加s,私有的过滤器定义的时候要加s。

键值修饰符

在监听键盘事件时,我们经常需要检测常见的键值。vue允许为v-on在监听键盘事件添加关键修饰符:

@keyup.13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
记住所有的keyCode比较困难,所以vue为做常用的按键提供了别名:
~~~
//这里两种写法都是可以的,可以是键码,也可以是别名和自定义别名
<input @keyup.enter="submit">
<input @keyup.13="submit">
~~~
全部的按键别名:
+ .enter
+ .tab
+ .delete(捕获删除键或者退格键)
+ .esc
+ .space
+ .up
+ .down
+ .left
+ .right

可以通过全局config.keyCodes对象自定义键值修饰符别名:
~~~
Vue.config.keyCodes.f1=112
//可以使用v-on:keyup.f1
~~~

定义的时候,跟定义全局过滤器一样,都是在全局进行定义的。


## 自定义全局定义
在vue中所有的指令在调用的时候都是以v-开头。
~~~
Vue.directive('focus')//调用的时候用v-focus
~~~
使用上述语法定义全局的指令。其中:
+ 参数1:指令的名称,注意,在定义的时候,指令的名称前面不需要加v-前缀,
但是 在调用的时候,必须在指令名称前加上v-前缀来进行调用。
+ 参数2:是一个对象,身上有一些指令相关的钩子函数,这些函数可以在特定的阶段,执行相关的指令

### 钩子函数
指令定义提供了几个钩子函数:
+ bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
+ inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)
+ update:所在组件的VNode更新时调用,但是可能发生在其孩子的VNode更新之前。指令的值可能发生了改变也可能没有。但是可以通过较更新前后的值来忽略不必要的模板更新
+ componentUpdated:所在组建的VNode及其汉字的VNode全部更新时调用
+ unbind:只调用一次,指令与元素解绑时调用

较为重要的时候,时前三个。

钩子函数的参数:el、binding、vnode、oldvnode


### 钩子函数参数列表
+ el:指令所绑定的元素,可以用来直接操作DOM。
+ binding:一个对象,包含以下属性:
- name:指令名,不包括v-前缀
- value:指令的绑定值,例如v-my-directive='1+1',value的值是2
- oldValue:指令绑定的前一个值,尽在update和component钩子中使用
- expression:绑定之的字符串形式。例如:v-my-directive=“1+1”,expression的值是“1+1”
- arg:传给指令的参数。例如:v-my-directive:foo,arg的值是foo
- modifiers:一个包含修饰符的对象。例如:v-mt-directive.foo.bar,修饰符对象modifiers的值是(foo:true,bar:true)。
+ vnode:Vue编译生成的虚拟节点
+ oldVnode:上一个虚拟节点,仅在update和component钩子中使用

注意binding.expression和binding.value的对比,前者是一个字符串形式,后者是它的值

除了el之外,其他参数都应该是只读的,尽量不要修改他们,如果需要在钩子之间共享数据,建议通过元素的dataset来进行

~~~
Vue.directive('focus',{
bind:function(el){//每当指令绑定到元素上的时候,会立即执行这个bind函数,只执行一次
//注意:在每个函数中,第一个参数永远是el,表示被绑定了指令的哪个元素,这个el参数,是一个原生的js对象
//在元素刚绑定了指令的时候,还没有插入到DOM中去,这时候,调用focus方法没有作用,
//因为一个元素,只有插入DOM之后,才能获取焦点
<!-- el.focus() -->
},
inserted:function(el){//表示元素插入到DOM中的时候,会执行该函数。只能触发一次
el.focus();//可以显示出来,因为这个已经插入到DOM中去了
},
updated:function(el){//当VNode更新的时候,会执行updated,可能会触发多次

}
})
~~~

### bind和inserted的区别:
我们看到的页面都是通过从内存中进行渲染在页面上来进行显示,数据从内存显示到页面的这个过程我们叫做inserted,而bind的话只要在内存中一进行绑定就可以执行该指令。

样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联样式。将来元素肯定会显示到页面中去,这时候,浏览器的渲染引擎必然会解析样式,应用给这个给样式。

和js行为有关的操作,做好在inserted中去执行,防止js行为不生效。和样式相关的操作,一般都可以在bind中执行。

### 使用钩子函数的第二个binding参数拿到传递的值

举例子定义一个自定义指令:
~~~
Vue.directive('color',{
bind:function(el,binding){
el.style.color=binding.value
}
})
~~~

调用的时候:
~~~
<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'blue'">
~~~

如果定义的时候是```el.style.color=binding.expression```的话,得到的是:
```el.style.color='blue'

自定义私有指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var vm = Vue({
el:'#app',
data:{
dt:new Date()
},
methods:{},
filters:{},
directives:{//自定义私有指令
'fontweight':{
bind:function(el,binding){
el.style.fontWeight = binding.value
}
}
}
})

指令函数的简写

不管是私有的还是全局的,后面都是跟的一个对象来进行定义
大多数情况下,我们可能想在bind和update钩子上做重复动作,并且不想关心其他的钩子函数。可以这样写:

1
2
3
Vue.directive('color',function(el,binding){
el.style.color = binding.value
})

相当于说,这个function在bind和update中都写了一份

生命周期函数

生命周期钩子=生命周期函数=生命周期事件

什么是生命周期:从vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件统称为生命周期
生命周期钩子:就是生命周期事件的别名而已
主要的生命周期函数分类:

  • 创建期间的生命周期函数

    • beforeCreated:实例刚在内存中被创建出来,此时还没有初始化好data和methods属性
    • created:实例已在内存中创建ok,此时data和methods属性已经创建ok,此时还没有编译模板
    • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
    • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中心事
  • 运行期间的生命周期函数

    • beforeUpdate:状态更新之前执行此函数,此时data中的状态值时最新的,但是界面上溴铵是的数据还是旧的,因为此时还没有开始重新渲染DOM节点
    • updated:实例更新完毕之后调用此函数,此时data中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了。
  • 销毁期间的生命周期函数

    • beforeDestroy:实例销毁之前调用,在这一步,实例仍然完全可用
    • destroy:Vue实例销毁后调用。调用后,Vue实例只是的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    var vm = new Vue({
    el:'#app',
    data:{},
    methods:{},
    beforeCreated(){//这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会调用它
    //在beforeCreated生命周期函数执行的时候,data和methods都还没有初始化。所以这个时候在这个
    //函数里面操作任何元素、属性或者数据都拿不到
    },
    created(){
    //在created里面,data和methods都已经初始化了
    //如果要调用methods或者data,最早都需要在created中去操作
    },
    beforeMount(){
    //表示模板已经在内存中编辑完成了,但是还没有渲染到页面上去
    //在该函数执行的时候,页面中的元素还没有真正切换过来,只是之前写的一些模板字符串
    },
    mounted(){
    //表示内存中的模板已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
    //注意:mounted是实例创建期间的最后一个生命周期函数,当执行完mounted,就表示实例已经完全创建好了
    //此时如果没有其他操作的话,这个实例就会静静的躺在内存中,一动不动
    //如果要通过某些插件要操作页面上的DOM节点最早要在mounted中进行
    },

    //接下来的是两个运行事件
    beforeUpdate(){
    //这时候,表示我们的界面还没有被更新,数据被更新了
    //当执行该函数的时候,页面中的显示数据,还是旧的,而此时data数据是最新的,页面尚未和最新的数据保持同步
    },
    updated(){
    //该事件执行的时候,页面和data数据已经保持同步了,都是最新的
    }
    })

beforeUpdate函数之后的一个变化就是,虚拟树的重新渲染和挂载。这一步执行的是,现根据data中的最新的数据,重新渲染出一份最新的内存DOM树,当最新的DOM树更新之后眯会吧最新的内存DOM书,重新渲染到真实的页面中去,这时候,就完成了数据从data->view的更新

当执行beforeDestroy钩子函数的时候,就已经从运行极端进入到了销毁阶段,实例身上所有的data和methods以及过滤器、指令等都处于可用过程,此时,还没有真正的执行销毁过程。

当执行dextroy钩子函数的时候,组件已经完全销毁了,组件中的所有data、methods、过滤器、指令都不可用。

vue-resource发起get、post、jsonp请求

使用jquery发起数据请求,需要操作DOM。
除了vue-resource还可以有使用axios的第三方包实现数据的请求。
常见的请求:个get、post、jsonp

vue-resource依赖vue

1
2
3
4
//发起get请求之后,通过.then来设置成功的回调函数
this.$http.get('路径地址').then(function(result){
//回调函数
})

手动发起的post请求,默认没有表单格式,所以,有的服务器处理不了

1
2
3
this.$http.post('路径地址',{},{}).then(result=> {

})

jsonp实现原理

由于浏览器的安全性限制,不允许AJAX访问协议不同、域名不同、端口号不同的数据接口,浏览器认为通过这种访问不安全。
可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称之为JSONP,其只支持get请求。

  • 具体实现过程
    • 先在客户端定义一个回调方法,预定义对数据的操作
    • 再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口
    • 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法和名称,拼接出一个调用这个方法的字符串,发送给客户端去执行
    • 客户端拿到服务器返回的字符串之后,当作script脚本去解析执行,这样就能够拿到jsonp的数据了
-------------本文结束感谢您的阅读-------------