1.列表的增删例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="lib/vue.js"></script>
<link rel="stylesheet" href="lib/bootstrap.css">
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"> 添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label>
Id:
<input type="text" name="" class="form-control" v-model="id">
</label>
<label>
Name:
<input type="text" name="" class="form-control" v-model="name">
</label>
<input type="button" value="添加" class="btn btn-primary" @click="add">
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list" :key="item.id">
<td>{{item.id}}</td>
<!--插值表达式-->
<td v-text="item.name"></td><!-- v-text -->
<td>{{item.ctime}}</td>
<td><a href="" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [
{ id: 1, name: '奥迪', ctime: new Date() },
{ id: 2, name: '比亚迪', ctime: new Date() },
{ id: 3, name: '宝马', ctime: new Date() },
{ id: 4, name: '奔驰', ctime: new Date() },
{ id: 5, name: '哈弗', ctime: new Date() },
{ id: 6, name: '奇瑞', ctime: new Date() },
{ id: 7, name: 'Jeep', ctime: new Date() },
]
},
methods: {
add() {//添加功能
this.list.push({ id: this.id, name: this.name, ctime: new Date() });
this.name = this.id = '';
},
del(id) {//通过id删除数据
this.list.some((item, i) => {
if (item.id == id) {
this.list.splice(i, 1);//数组的i位置删除一个元素
return true;//在数组的some方法如果return true ,就会终止循环, 这里一旦找到,就终止循环
}
});
//还可以通过 数组的findIndex 来查找索引
/*
var index = this.list.findIndex(item => {
if (item.id == id) {
return true;
}
});
console.log(index);
*/
}
}
});
</script>
</body>
</html>
forEach 、 some 、 filter 、findIndex 这些都属于数组的新方法,都会对数组中的每一项进行遍历,执行相关的操作。
2.过滤器-列表例子完善
2.1过滤器定义
过滤器可被用作一些常见的文本格式化,Vue.js允许自定义过滤器,过滤器只可以用在两个地方:mustache插值和v-bind表达式。过滤器应该被添加在JavaScript表达式的尾部。
语法:
//过滤器调用 对那个变量格式化,变量名称 | 过滤器名称
{{paramName | 过滤器名称}}// 竖线也叫管道符号 ,可以添加多个过滤器,以管道符隔开 如 {{pName | filter1 | filter2 | ...}},执行顺序从左到右依次执行
//定义过滤器的语法调用vue的filter方法,传入,过滤器名称,以及要处理数据的函数,函数中的第一个参数,是过利器管道符前面的数据
Vue.filter('过滤器名称',function(data){
return data+'sdgsdgssd';
})
//比如对上述案例的日期格式化
{{item.ctime | timeFormate}}//过滤器名称其实就是一个函数,可以传参的, timeFormate('paa','sdgas')
Vue.filter('timeFormate',function(ctime){//function(ctime,arg1,arg2,...)//除了第一个参数是固定的,后续可以自定义个数
});
2.2实现时间格式化:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="lib/vue.js"></script>
<link rel="stylesheet" href="lib/bootstrap.css">
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"> 添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label>
Id:
<input type="text" name="" class="form-control" v-model="id">
</label>
<label>
Name:
<input type="text" name="" class="form-control" v-model="name" @keyup.enter="add"><!--添加键盘抬起事件,回车键按下后触发该事件-->
</label>
<input type="button" value="添加" class="btn btn-primary" @click="add">
<label for="">
搜索名称:
<input type="text" name="" id="" class="form-control" v-model="keywords">
</label>
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr v-for="item in search(keywords)" :key="item.id">
<td>{{item.id}}</td>
<!--插值表达式-->
<td v-text="item.name"></td><!-- v-text -->
<td>{{item.ctime | dateFormat}}</td>
<td><a href="" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
<script>
Vue.filter('dateFormat', function (dateStr) {
var dt = new Date(dateStr);
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate();
// return y + '-' + m + '-' + d;
return `${y}-${m}-${d}`;//模板字符串, tab键上方的键输入的两撇
});
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
list: [
{ id: 1, name: '奥迪', ctime: new Date() },
{ id: 2, name: '比亚迪', ctime: new Date() },
{ id: 3, name: '宝马', ctime: new Date() },
{ id: 4, name: '奔驰', ctime: new Date() },
{ id: 5, name: '哈弗', ctime: new Date() },
{ id: 6, name: '奇瑞', ctime: new Date() },
{ id: 7, name: 'Jeep', ctime: new Date() },
]
},
methods: {
add() {//添加功能
this.list.push({ id: this.id, name: this.name, ctime: new Date() });
this.name = this.id = '';
},
del(id) {//通过id删除数据
this.list.some((item, i) => {
if (item.id == id) {
this.list.splice(i, 1);//数组的i位置删除一个元素
return true;//在数组的some方法如果return true ,就会终止循环, 这里一旦找到,就终止循环
}
});
//还可以通过 数组的findIndex 来查找索引
/*
var index = this.list.findIndex(item => {
if (item.id == id) {
return true;
}
});
console.log(index);
*/
},
search(keywords) {
/*
var newList = [];
this.list.forEach(element => {
if (element.name.indexOf(keywords) != -1) {
newList.push(element);
}
});
return newList;
*/
return this.list.filter(item => {
if (item.name.includes(keywords)) {//ES6 中,字符串新方法: String.prototype.includes('包含的字符串'), true包含,false不包含 jquery 中提供的是contains方法
return item;
}
});
}
}
});
</script>
</body>
</html>
2.3自定义局部过滤器
上述过滤器是全局的,也就是说不只是一个vue实例可以使用,其他的vue实例也可以使用,当然如果想让某个vue实例才能使用的话,就需要自定义一个局部的过滤器
var vm = new Vue({
el:'#app',
data: {
dt: new Date()
},
methods: {
},
filters: {//这就是局部过滤器,或者叫该vue实例私有的过滤器
//过滤器有两个条件 [过滤器名称 和 处理函数]
dateFormat: function(dateStr,param1){
//处理函数的内容同上
}
}
});
过滤器调用的时候如果有两个同名的过滤器,一个是私有的一个是全局的,那么它会调用自己私有的,不会调用全局的。
2.4字符串填充 ES6
使用ES6中的字符串新方法String.prototype.padStart(maxLength,fillString=’’) 头部填充或 String.prototype.padEnd(maxLength,fillString=’’) 尾部填充来填充字符串。
var m = (dt.getMonth() + 1).toString().padStart(2,'0');//这样就实现了月份是两位数字了
var d = dt.getDate().toString().padStart(2,'0');//小于10的日期天也被填充成两位数字了
3.按键码 按键修饰符
keyCode
的事件用法已经被废弃了并可能不会被最新的浏览器支持。
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
有一些按键 (.esc
以及所有的方向键) 在 IE9 中有不同的 key
值, 如果你想支持 IE9,这些内置的别名应该是首选。
你还可以通过全局 config.keyCodes
对象自定义按键修饰符别名:
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
除了用上述Vue给的这些按键修饰符,我们还可以自定义全局按键修饰符。
Vue.config.keyCodes.f2 = 113;//此时就可以使用
//html中使用:
Name:
<input type="text" name="" class="form-control" v-model="name" @keyup.f2="add">
4.自定义指令
比如说现在要自定义一个v-focus 指令,来让某个input自动获取焦点,比如定义全局的指令v-focus,其中第一个参数是指令的名称,且不需要在指令的名称前面加“v-” 前缀,在调用的时候,必须在指令名称前加上“v-”前缀。第二个参数是一个对象,这个对象有一些质量相关的函数,这些函数可以在指定的阶段执行相关的操作。
<script>
Vue.directive('focus',{
bind: function(el) {//el是绑定到的元素,在这些函数(当前以及下面的函数)中,第一个参数,都是el,表示被绑定了指令的元素,它是一个原生的jsDOM对象。
//当指令绑定到元素上时,执行,只执行一次
//el.focus();//但是当前方法调用后没有任何作用,原因是,在元素刚绑定指令时,还没有插入到内存中的DOM树中去,所以没反应。只有当元素插入DOM之后才能获取焦点。
},
inserted: function(el) {//当元素插入到DOM重视会执行,只执行一次,
el.focus();//此时元素已经插入到DOM中,所以可以看到效果。
},
updated: function(el) {}//当VNode更新时,会执行,可执行多次
});//定义全局的指令
</script>
//调用
<label for="">
搜索名称:
<input type="text" name="" id="" class="form-control" v-model="keywords" v-focus>
</label>
4.1钩子函数:
4.1.1指定定义函数提供了几个钩子函数(可选):
- bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作;和样式相关的操作可以在bind中执行,因为浏览器的渲染引擎会解析样式渲染到该元素。
- inserted:被绑定元素插入父节点时调用(附加点存在即可调用,不必存在于document中); 和js行为有关的操作最好在inserted中执行,防止效果不生效。
- update:所在组件的VNode更新时调用,但是可能发生在其孩子的VNode更新之前。指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
- componentUpdated: 所在组件的VNode及其孩子的VNode全部更新时调用。
- unbind: 只调用一次,指令与元素解绑时调用。
4.1.2钩子函数的参数
- el : 指令所绑定的元素,可以用来直接操作DOM;
- binding : 一个对象,包含如下属性:
- name:指令名,不包括 v-前缀;
- value : 指令的绑定值,例如: v-my-directive=“1+1” , value 的值是2;
- oldValue: 指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否改变都可用。
- expression:绑定值的字符串形式。例如 v-my-directive=“1+1” ,expression的值是“1+1”。
- arg:传给指令的参数。例如:v-my-directive:foo,arg的值是“foo”。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar,修饰符对象modifiers的值是(foo:true,bar:true)。
- vnode:Vue编译生成的虚拟节点,查阅VNode API可以了解更多详情。
- oldVode:上一个虚拟节点,仅在update和componentUpdated钩子中可用。
html 元素中使用 v-color="'blue'"
--------------------------------
Vue.directive('color',{
bind:function(el,binding){
console.log(binding.value);// 表达式的计算结果 -- blue
console.log(binding.expression);// 表达式 -- 'blue'
console.log(binding.name);// 名称 -- color
el.style.color = binding.value;//设置样式颜色
}
})
4.2 私有的自定义指令
var vm = new Vue({
el:'#app',
data: {
dt: new Date()
},
methods: {
},
filters: {//这就是局部过滤器,或者叫该vue实例私有的过滤器
//过滤器有两个条件 [过滤器名称 和 处理函数]
dateFormat: function(dateStr,param1){
//处理函数的内容同上
}
},
directives: {//自定义私有指令 [指令名称 对象(包含了函数)]
'fontweight': {
bind:function(el,binding){
el.style.fontWeight = binding.value;
}
}
}
});
//----------------------
html元素中使用时:
v-fontweight="900"
4.3 函数简写
大多数情况下,我们可能想在bind和update钩子上做重复动作,并且不希望关心其他的钩子函数,可以写成如下方式:
Vue.directive('color-swatch',function(el, binding){
el.style.backgroundColor = binding.value;
});
//私有:
directives: {//自定义私有指令 [指令名称 对象(包含了函数)]
'fontweight': {
bind:function(el,binding){
el.style.fontWeight = binding.value;
}
},
//私有
'fontsize':function(el,binding) {//这个function等同于,bind和update中都写了
el.style.fontSize = binding.value;
}
}
5.Vue实例的生命周期
从vue实例创建、运行、到销毁期间总是伴随着各种各样的事件,这些事件统称为生命周期。
生命周期钩子: 就是生命周期事件或者生命周期函数的别名而已;
var vm = new Vue({
el: '#app',
data: {},
methods:{},
beforeCreate(){//生命周期中的第一个函数,vue实例在完全创建出来之前会执行该函数
},
created(){//第二个生命周期函数
//此时data 和methods 都已经被初始化了
},
beforeMount(){//第三个声明周期函数 模板已编译完成,只是未挂载到页面中去
console.log(document.getElementById('h3').innerText);//此时输出的是{{msg}}而不是msg的值
},
mounted(){//第四个生命周期函数 此时内存中的模板,已经挂载到了浏览器页面中了,用户此时已经可以看到渲染好的页面了
console.log(document.getElementById('h3').innerText);//此时输出的是msg的值'OK',而不是插值表达式了
},
//接下来是运行期间的两个周期函数
beforeUpdate(){//数据更新时,且发生在更新之前
console.log('界面上元素的内容:'+document.getElementById('h3').innerText);//此时输出的依旧是没改变之前的数据
console.log('data中的msg数据是:'+this.msg);//此时已经是改变后的数据了
},
updated(){//数据更新后,页面和data数据已经同步为最新了
console.log('界面上元素的内容:'+document.getElementById('h3').innerText);//此时已经是改变后的数据了
console.log('data中的msg数据是:'+this.msg);//此时已经是改变后的数据了
}
});
主要的生命周期函数分类:
5.1 创建期间的生命周期函数:
5.1.1 beforeCreate()
在该函数体内操作时,此时data和methods都还没有被执行初始化
5.1.2 created()
在该函数体内,data和methods已经被初始化了,也就是说data和methods最早被使用的时候是在created()方法中。
5.1.3 beforeMount()
在该函数执行的时候,页面中的元素的内容并没有被替换过来,只是之前写的一些模板字符串,即如果我们想获取元素的内容,我们拿到的只是插值表达式,而不是值内容。
5.1.4 mounted()
实例创建期间的最后一个周期函数,执行完mounted就表示,实例已经完全被创建好了,此时如果没有其他操作的话,这个实例就会在内存中不动了。
5.2 运行期间的生命周期函数:
5.2.1 beforeUpdate()
一旦数据发生改变时就会先触发该事件,且页面中显示的数据还是旧的,但是此时data中的数据是最新的,页面和最新的数据尚未同步。
5.2.2 updated()
此时页面中的数据和data中的数据已经都是最新的了,保持同步了
5.3 销毁期间的生命周期函数:
5.3.1 beforeDestroy()
此时vue实例中的数据、方法、指令、过滤器等都还可用,没有被销毁
5.3.2 destroyed()
此时vue实例已被销毁,实例中的东西均不可用。
6.vue-resource实现get,post,jsonp请求
除了使用vue-resource之外,还可以使用“axios”的第三方包实现数据的请求
测试URL请求资源地址:
get请求: http://vue.studyit.io/api/getlunbo
post请求:http://vue.studyit.io/api/post
jsonp请求地址: http://vue.studyit.io/api/jsonp
methods: {
getInfo(){
this.$http.get(getUrl).then(function(result){//get() 第二个参数是请求参数,可不传
console.log('result='+result);
});
},
postInfo(){//手动发起的post请求,默认没有表单格式,服务器处理不了,所以需要给post的第三个参数设置提交的内容类型,现在设置为普通表单数据格式 application/x-wwww-form-rulencoded
this.$http.post(postUrl,{name,this.name},{emulateJSON:true}).then(result => {//post()第二个参数,是要传给接口的参数
console.log(result);
});
},
jsonpInfo(){
this.$http.jsonp(jsonpUrl).then(result => {
console.log(result);
});
}
}
全局设置根路径的方式:
Vue.http.options.root = 'http://vue.studyit.io/';
//如果通过全局配置根路径,请求的数据接口根域名则每次单独发起http请求的视乎url路径应该以相对路径开头,并且前面不能带'/'否则不会启用根路径做拼接。
this.$http.get('api/getprodlist').then(result=>{});//这里的是相对路径,并且url不能以'/'开始。
还可以配置emulateJSON为全局的省去每次的post还要传这个参数
Vue.http.options.emulateJSON = true;
this.$http.post(postUrl,{name,this.name}).then(result => {//post()第二个参数,是要传给接口的参数
console.log(result);
});