第一章
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
第二章 基础特征
2.1 Vue 实例及选项
创建实例时,选项对象包括 挂载元素、数据、方法、生命周期钩子函数等选项
2.1.1 挂载元素
el: 可以使用CSS选择符,也可以是原生的DOM元素名称
2.1.2 数据
数据绑定到对应的模板中
<body>
<div id="app">
<h3>name: {{name}}</h3>
<h3>age: {{age}}</h3>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
name: 'xiaofu',
age: 20
}
});
</script>
</body>
data对象中定义的属性被称为响应式属性
<script type="text/javascript">
var data ={name:'xiaofu',age: 20};
let app = new Vue({
el: '#app',
data: data
});
</script>
2.1.3 方法
<body>
<div id="app">
<h3>name: {{name}}</h3>
<h3>age: {{age}}</h3>
<!--调用showInfo()方法-->
<h3>Info: {{showInfo()}}</h3>
</div>
<script type="text/javascript">
var data = {
name: 'xiaofu',
age: 20
};
let app = new Vue({
el: '#app',
data: data,
methods: {
showInfo: function() {
return this.name + ':' + this.age;
}
},
});
</script>
</body>
2.1.4 生命周期钩子函数
创建数据绑定→编译模板→将实例挂载到模板并实时触发DOM更新→销毁实例
<script type="text/javascript">
let app = new Vue({
el: '#app',
beforeCreate: function() {
console.log('boforeCreate');
},
created: function() {
console.log('created');
},
beforeDestroy: function() {
console.log('beforeDestroy');
},
destroyed: function() {
console.log('destroy');
},
mounted: function() {
console.log('mounted');
this.$destroy();
}
})
</script>
</body>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190033277.png)
2.2 数据绑定
2.2.1 插值
- 文本插值
数据绑定的基本方式,双大括号标签 {{}}
- 插入HTML
v-html指令,将数据值作为HTML元素插入
<body>
<!-- 在div中插入HTML语句 -->
<div id="app" v-html='msg'></div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
msg: '<h2>error</h2>'
}
})
</script>
</body>
- 属性
v-bind指令对属性进行绑定
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>绑定属性</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style type="text/css">
.common {
border: 1px solid rebeccapurple;
color: blue;
background-color: pink;
font: 500;
}
</style>
</head>
<body>
<div id="app" v-bind:class='style' v-html='msg'></div>
</body>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
style: 'common',
msg: '<h2>error</h2'
}
})
</script>
v-bind 指定元素属性时,可将属性值设置为对象的形式
<body>
<div id="app" v-bind:class="{'common':value}" v-html='msg'></div>
</body>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
value: false,
msg: '<h2>error</h2'
}
})
</script>
元素绑定属性简写
<a v-bind:href='url'>百度一下</a><br>
<a :href='url'>百度一下</a>
- 表达式
在双大括号标签中进行数据绑定,标签中可以是一个JavaScript表达式
<body>
<div id="app">
{{number+10}}<br> {{boo? 'true':'false'}}<br> {{str.toLowerCase()}} {{str.toUpperCase()}}<br>
<p>e-mail:{{Email}}</p>
<p>QQ: {{Email.substr(0,Email.indexOf('@'))}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
number: 100,
boo: '',
str: 'Hello world',
Email: '1234567890@qq.com'
}
})
</script>
</body>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190011815.png)
2.2.2 过滤器
进行复杂的数据绑定 对文本进行格式化
在双大括号中
{{message| myfilter}}
在v-bind指令中
<div v-bind:id='rawid| formatid'></div>
- 用Vue.filter()方法定义全局过滤器
格式: Vue.filter(id,function({}))
参数为:过滤器的id(自定义过滤器的唯一标识) 过滤器函数
<body>
<div id="app">
<p>{{date}}</p>
<p>{{date| nowdate}}</p>
</div>
<script type="text/javascript">
Vue.filter('nowdate', function(value) {
var year = value.getFullYear();
var month = value.getMonth() + 1;
var date = value.getDate();
var day = value.getDay();
var week = '';
switch (day) {
case 1:
week = '星期一';
break;
case 2:
week = '星期二';
break;
case 3:
week = '星期三';
break;
case 4:
week = '星期四';
break;
case 5:
week = '星期五';
break;
case 6:
week = '星期六';
break;
default:
week = '星期日';
break;
}
return '今天是' + year + '年' + month + '月' + date + '日' + week;
});
let app = new Vue({
el: '#app',
data: {
date: new Date()
}
});
</script>
</body>
-------------------------------------------
Sat May 08 2021 20:31:06 GMT+0800 (GMT+08:00)
今天是2021年5月8日星期六
- 应用filter定义本地过滤器
<body>
<div id="app">
<ol>
<li v-for='item in data'>{{item| subStr}}</li>
</ol>
</div>
<script type="text/javascript">
var data = ['你只有一定要,才一定会得到', '决心是成功的开始', '当你没有借口的那一刻,就是你成功的开始', '命运是可以改变的', '成功者绝不放弃', '成功永远属于马上行动的人', '下定决心一定要,才是成功的关键', '成功等于目标,其他都是这句话的注解', '成功是一个过程,并不是一个结果', '成功者学习别人的经验,一般人学习自己的经验', '只有第一名可以教你如何成为第一名'];
let app = new Vue({
el: '#app',
data: data,
filters: {
subStr: function(value) {
if (value.length > 10) {
return value.substr(0, 10) + '...';
} else {
return value;
}
}
}
});
</script>
</body>
多个过滤器串联使用
{{message|filterA|filterB}}
<body>
<div id="app"><span>{{str|lowerCase| firstUpperCase}}</span></div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
str: 'HTML+CSS+JavaScript'
},
filters: {
lowerCase: function(value) {
return value.toLowerCase();
},
firstUpperCase: function(value) {
return value.charAt(0).toUpperCase() + value.substr(1);
}
}
})
</script>
</body>
Html+css+javascript
filter 接受多个参数
<body>
<div id="app">
<ul>
<li v-for='item in prices'>{{item | formatPrice('¥')}}</li>
</ul>
<p>{{prices}}</p>
</div>
<script type="text/javascript">
var prices = [132.4, 432.564, 32, 654, 213, 0.434, 1234.56];
let app = new Vue({
el: '#app',
data: prices,
filters: {
formatPrice: function(value, symbol) {
return symbol + value.toFixed(2);
}
}
})
</script>
</body>
-----------------------
¥132.40
¥432.56
¥32.00
¥654.00
¥213.00
¥0.43
¥1234.56
[ 132.4, 432.564, 32, 654, 213, 0.434, 1234.56 ]
2.2.3 指令
指令的值限定为绑定表达式,当绑定的表达式值发生改变时,指令对DOM进行修改
参数和修饰符
第三章 条件判断与列表渲染
3.1 条件判断
3.1.1 v-if指令
3.1.2 v-else指令
3.1.3 v-else-if 指令
3.1.4 v-show指令
根据表达式的值判断是否显示和隐藏DOM元素;
无论表达式的值是 true或者false,该元素始终都会被渲染并保留在DOM中,只是简单地改变CSS属性display
<body>
<div id="app">
<input type="button" :value='bText' v-on:click='toggle'>
<div v-show='show'>
<img src="simpify.png" alt="simpify.png">
</div>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
bText: '显示图片',
show: true
},
methods: {
toggle: function() {
// 切换按钮文字
this.bText == '隐藏图片' ? '显示图片' : '隐藏图片';
this.show = !this.show;
}
},
})
</script>
</body>
3.1.5 v-if 和 v-show的对比
- 在进行v-if 切换时,v-if中的模板可能包括数据绑定或子组件,Vue.js存在一个局部编译/卸载的过程;v-show仅发生样式的变化
- v-if是惰性的,如果初始条件为false时,v-if本身什么都不会做,v-show 不论真假,DOM元素总是会被渲染
- 总结: 如果需要频繁的切换,用v-show比较好;运行时条件很少改变,用v-if比较好
3.2 列表渲染
3.2.1 用v-for指令遍历数组
<div id="app">
<table>
<tr>
<th>no</th>
<th>province</th>
<th>position</th>
<th>number</th>
</tr>
<tr v-for="(item,index) in datas">
<td>{{index+1}}</td>
<td>{{item.province}}</td>
<td>{{item.position}}</td>
<td>{{item.number}}</td>
</tr>
</table>
</div>
<body>
<script type="text/javascript">
var datas = [{
province: '湖北省',
position: '后湖乡世纪家园',
number: '430012'
}, {
province: '湖北省',
position: '江汉一路',
number: '430014'
}, {
province: '湖北省',
position: '北湖小路妙三社区',
number: '430015'
}, {
province: '湖北省',
position: '张自忠小路',
number: '430010'
}];
let app = new Vue({
el: '#app',
data: datas
});
</script>
</body>
3.2.2 在template中使用v-for
<body>
<div id="app">
<ul>
<template>
<li v-for="item in menulist">{{item}}</li>
<li>|</li>
</template>
</ul>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
menulist: ['首页', '闪购', '我的购物车', '关于我们']
}
});
</script>
</body>
3.2.3 数组更新检测
方法 | 描述 |
---|---|
concat() | 连接两个或更多的数组,并返回结果。 |
join() | 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。 |
pop() | 删除并返回数组的最后一个元素 |
push() | 向数组的末尾添加一个或更多元素,并返回新的长度。 |
reverse() | 颠倒数组中元素的顺序。 |
shift() | 删除并返回数组的第一个元素 |
slice() | 从某个已有的数组返回选定的元素 |
sort() | 对数组的元素进行排序 |
splice() | 删除元素,并向数组添加新元素。 |
toSource() | 返回该对象的源代码。 |
toString() | 把数组转换为字符串,并返回结果。 |
toLocaleString() | 把数组转换为本地数组,并返回结果。 |
unshift() | 向数组的开头添加一个或更多元素,并返回新的长度。 |
valueOf() | 返回数组对象的原始值 |
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
menulist: ['首页', '闪购', '我的购物车', '关于我们']
}
});
/* 实例方法Vue.set$(array,index,value)设置元素的值 因为JavaScript的限制 */
Vue.set(app.menulist, 1, 'hahah');
</script>
为数组重新排序
/* 为我的datas自定义排序 */
app.menulist.sort(function(a, b) {
var x = a;
var y = b;
return x < y ? 1 : -1;
});
3.2.4 v-for遍历对象
v-for='(value,key,index) in object'
的顺序
<body>
<div id="app">
<ul>
<li v-for='(value,key,index) in object'>{{index+1}}-{{key}}-{{value}}</li>
</ul>
</div>
</body>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
object: {
id: '12345',
name: 'zhangsan',
age: 24
}
}
})
</script>
3.2.5 向对象中添加属性
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
object: {
id: '12345',
name: 'zhangsan',
age: 24
}
}
});
/* 向对象中添加属性 */
Vue.set(app.object, 'interest', 'music');
/* 向对象中添加多个属性 */
app.object = Object.assign({}, app.object, {
address: '湖北武汉',
skill: 'java全栈'
})
</script>
3.2.6 v-for 遍历整数
打印九九乘法表
<body>
<div id="app">
<div v-for='m in end'>
<span v-for='n in m'>{{m}}*{{n}} = {{m*n}} </span>
</div>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
end: 9
}
})
</script>
</body>
综合案例: 成绩表
<body>
<div id="app">
<div style="text-align: center;">
<span>姓名:{{name}}</span>
<span>性别:{{sex}}</span>
<span>年龄:{{age}}</span>
</div>
<table>
<tr>
<th>编号</th>
<th>学期</th>
<!-- 点击科目排序 -->
<th v-on:click='compare("math")'>math</th>
<th v-on:click='compare("English")'>English</th>
<th v-on:click='compare("Chinese")'>Chinese</th>
<th>总分</th>
</tr>
<tr v-for='(item,index) in grades'>
<td>{{index+1}}</td>
<td>{{item.term}}</td>
<td v-for='score in item.scores'>{{score}}</td>
<td>{{sum(item.scores)}}</td>
</tr>
</table>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
name: 'zhangsan',
sex: '男',
age: 20,
grades: [{
term: '第一学期',
scores: {
math: 70,
English: 86,
Chinese: 100
}
}, {
term: '第二学期',
scores: {
math: 50,
English: 67,
Chinese: 90
},
}]
},
methods: {
sum: function(scores) {
var total = 0;
for (var obj in scores) {
total += scores[obj];
}
return total;
},
/* 根据分数排序 */
compare: function(property) {
alert('aaa');
return this.grades.sort(function(a, b) {
return a.scores[property] - b.scores[property];
});
}
},
})
</script>
</body>
第四章 计算属性与监听属性
4.1 计算属性
4.1.1 什么是计算属性
定义在computed 选项中;当计算依赖的数据发生变化时,这个属性的值会自动更新,所有依赖该属性的数据绑定也会同步进行更新
<body>
<div id="app">
<p>oldStr: {{oldStr}}</p>
<p>newStr: {{newStr}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
oldStr: 'HTML+CSS+JavaScript'
},
computed: {
newStr: function() {
return this.oldStr.split('+').join('**');
}
}
})
</script>
</body>
统计购物车商品的总价
<body>
<div id="app">
<table>
<tr>
<th>no</th>
<th>name</th>
<th>price</th>
<th>count</th>
<th>money</th>
<th>operate</th>
</tr>
<tr v-for='(good,index) in shop'>
<td>{{index}}</td>
<td>{{good.name}}</td>
<td>{{good.price}}</td>
<td>{{good.count}}</td>
<td>{{good.price*good.count| twoDecimal}}</td>
<td v-on:click='remove(index)' :style='pointer'>移除</td>
</tr>
</table>
<p style="text-align: right;">{{totalPrice| formatPrice('¥')}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
shop: [{
name: '小米11',
price: '3456',
count: 3
}, {
name: 'oppo R15',
price: '1324',
count: 30
}],
pointer: {
cursor: 'pointer',
display: 'block'
}
},
computed: {
totalPrice: function() {
var total = 0;
this.shop.forEach(element => {
total += element.price * element.count;
});
return total;
}
},
methods: {
remove: function(index) {
this.shop.pop(index);
}
},
filters: {
formatPrice: function(value, symbol) {
return symbol + value.toFixed(2) + '元';
},
twoDecimal: function(value) {
return value.toFixed(2);
}
}
})
</script>
</body>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190027874.png)
4.1.2 getter 和setter
每一个计算属性都包含一个getter和setter,当没有指明方法时,默认使用getter来读取数据
<body>
<div id="app">{{fullname}}</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
surname: '王',
name: '大毛'
},
computed: {
fullname: {
get: function() {
return this.surname + this.name;
},
set: function(value) {
this.surname = value.substr(0, 1);
this.name = value.substr(1);
}
}
}
});
/* 如果没有setter,将显示的是‘王大毛’ 计算属性fullname 先去调用setter()方法,然后赋值*/
app.fullname = '王小毛';
</script>
</body>
4.1.3 计算属性缓存
在表达式中调用方法
<body>
<div id="app">
方法拿到的时间戳:{{ now() }} <br> 计算属性拿到的时间戳:{{ thisTime }}
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {},
methods: {
now: function() {
return Date.now()
}
},
computed: {
thisTime: function() {
return Date.now()
}
}
});
</script>
</body>
方法拿到的时间戳:1620550130050
计算属性拿到的时间戳:1620550130051
4.2 监听属性
4.2.1 监听属性的定义
是Vue.js提供的一种用来监测和响应Vue实例中数据变化的方式。每当监听的属性发生变化,都会执行特定的操作
- 在watch选项中监听
<body>
<div id="app">{{fullname}}</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
fullname: '张三'
},
watch: {
/* 注意参数的顺序 */
fullname: function(newVal, oldVal) {
alert('oldVal:' + oldVal + '----' + 'newVal:' + newVal);
}
}
});
/* 修改属性值 */
app.fullname = '李四';
</script>
</body>
oldVal:张三----newVal:李四
- 实例方法vm. w a t c h ( ) watch() watch()
app.$watch('fullname', function(newVal, oldVal) {
alert('oldVal:' + oldVal + '----' + 'newVal:' + newVal);
});
- 人民币和美元之间的换算
<body>
<div id="app">
<p>¥:<input type="number" v-model='rmb'></p>
<p>$:<input type="number" v-model='dollar'></p>
{{rmb|formatNum('¥')}} ={{dollar|formatNum('$')}}
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
rmb: 0,
dollar: 0,
rate: 6.8
},
watch: {
dollar: function(val) {
this.rmb = val / this.rate;
},
rmb: function(val) {
this.dollar = val * this.rate;
}
},
filters: {
formatNum: function(value, symbol) {
return symbol + value.toFixed(2);
}
}
});
</script>
</body>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190043981.png)
4.2.2 deep 选项
监听对象内部的值得变化,在选项参数中设置deep选项的值为true
<body>
<div id='app'>{{user.name}}</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
user: {
name: 'zhangsan',
age: 20
}
},
watch: {
user: {
handler: function(val) {
alert('new name: ' + val.name);
},
/* false的时候不会执行该方法 */
deep: false
}
}
});
app.user.name = 'lisi';
</script>
</body>
第五章 样式绑定
5.1 class属性绑定
5.1.1 对象语法
将绑定的数据设置成一个对象,动态的切换元素的class
5.1.1.1 内联绑定
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>内联样式的绑定</title>
<script src="../vue.min.js"></script>
<style>
.blue {
color: blueviolet;
font-weight: bolder;
}
</style>
</head>
<body>
<div id="app" v-bind:class='{blue:isBlue}'>this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
isBlue: true
}
})
</script>
</body>
在对象中传入多个属性动态切换元素的多个class
<body>
<div id="app" v-bind:class='{blue:isBlue,border: isBorder}'>this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
isBlue: true,
isBorder: true
}
})
</script>
</body>
5.1.1.2 非内联样式绑定
将元素的class属性绑定的对象定义在data选项中
<body>
<div id="app" v-bind:class='classObj'>this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
classObj: {
/* 下边是类名 */
blue: true,
border: true
}
}
})
</script>
</body>
5.1.1.3 使用计算属性返回样式对象
将元素的class属性绑定在一个返回对象的计算属性
<body>
<div id="app" v-bind:class='show'>this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
isBlue: true,
isBorder: true
},
computed: {
show: function() {
return {
blue: this.isBlue,
border: this.isBorder
}
}
}
})
</script>
</body>
5.1.2 数组语法
5.1.2.1 普通样式
将元素的class属性直接绑定为一个数组
<div v-bind:class='[element1,element2,.....]'></div>
<body>
<div id="app" v-bind:class='[blueClass,borderClass]'>this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
/* 属性值为类名加引号 */
blueClass: 'blue',
borderClass: 'border'
}
})
</script>
</body>
5.1.2.2 在数组中使用条件运算符
<body>
<div id="app" v-bind:class="[isBlue? 'blue' : '',borderClass]">this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
/* 属性值为类名加引号 */
isBlue: true,
borderClass: 'border'
}
})
</script>
</body>
5.1.2.3 在数组中使用对象
<body>
<div id="app" v-bind:class="[{blue:isBlue},borderClass]">this a paragram</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
/* 属性值为类名加引号 */
isBlue: false,
borderClass: 'border'
}
})
</script>
</body>
5.2 内联样式的绑定
5.2.1 对象语法
5.2.1.1 内敛绑定
将元素的style属性直接绑定为对象
<body>
<div id="app" v-bind:style="{'font-weight':weight,color: color}">this is a paragraph</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
weight: 'bolder',
color: 'blue'
}
})
</script>
</body>
5.2.1.2 非内联样式的绑定
将元素的属性绑定的对象直接定义在data选项中
<body>
<div id="app" v-bind:style='styleObj'>this is a paragraph</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
styleObj: {
'font-weight': 'bolder',
'color': 'red'
}
}
})
</script>
</body>
5.2.1.3 使用计算属性返回样式对象
<body>
<div id='app' v-bind:style='show'>this is a paragraph</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
color: 'red',
fontSize: 40
},
computed: {
show: function() {
return {
color: this.color,
'font-size': this.fontSize + 'px'
}
}
}
})
</script>
</body>
5.2.2 数组语法
- 直接在元素中绑定样式对象
<body>
<div id="app" v-bind:style="[{color:'red'},{'font-size':'40px'}]">this is a paragraph</div>
<script type="text/javascript">
let app = new Vue({
el: '#app'
})
</script>
</body>
- 在data中定义样式对象数组
<body>
<div id="app" v-bind:style="arrStyle">this is a paragraph</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
arrStyle: [{
color: 'blue'
}, {
'font-size': '40px'
}]
}
})
</script>
</body>
- 对象数组的形式进行绑定
<body>
<div id="app" v-bind:style="[color,size]">this is a paragraph</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
color: {
'color': 'red'
},
size: {
'font-size': '50px'
}
}
})
</script>
</body>
第六章 事件处理
6.1 事件监听
6.1.1 使用v-on指令
<body>
<div id='app'>
<button v-on:click='count++'>计数</button>
<p>点击的次数:{{count}}</p>
<!-- @click简写的形式 两个count同步更新 -->
<button @click='count++'>计数</button>
<p>点击的次数:{{count}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
count: 0
}
})
</script>
</body>
6.1.2 事件处理方法
v-on将事件和某个方法绑定
<body>
<div id="app">
<button v-on:click='increase'>计数</button>
<p>{{count}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
increase: function() {
this.count++;
}
}
})
</script>
</body>
更改图片的样式
<body>
<div id="app">
<img :src="imgPath" :alt="imgAlt" :title='title' id='icon' @mouseover='visible(0)' @mouseout='visible(1)'>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
imgPath: '../img/icon.png',
imgAlt: 'icon',
title: 'icon'
},
methods: {
visible: function(i) {
var icon = document.getElementById('icon');
if (i == 0) {
icon.style.opacity = 0.5;
icon.style.border = '1px solid red'
} else {
icon.style.opacity = 1;
icon.style.border = ''
}
}
},
});
</script>
</body>
6.1.3 使用内联的JavaScript语句
<body>
<div id="app">
<button v-on:click="show('xiaogen')">点击</button>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
methods: {
show: function(name) {
alert('hello ' + name);
}
},
});
</script>
</body>
6.2 事件处理中的修饰符
6.2.1 事件修饰符
- .stop 阻止冒泡
- .prevent 阻止默认事件
- .capture 添加事件侦听器时使用事件捕获模式
- .self 只当事件在该元素本身(比如不是子元素)触发时触发回调
- .once 事件只触发一次
- .passive 以{passive: true}模式添加监听器
6.2.2 按键修饰符
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
使用 keyCode
特性也是允许的:
<input v-on:keyup.13="submit">
还可以通过全局 config.keyCodes
对象自定义按键修饰符别名:
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
案例: 省市二级联动菜单
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>省市二级联动菜单</title>
<script src="../vue.min.js"></script>
</head>
<body>
<div id="app">
<select v-on:change='getProvince'>
<option v-for='province in provinces' :value='province.name'>{{province.name}}</option>
</select>
<select>
<option v-for='city in getCities' :value='city'>{{city}}</option>
</select>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
pname: '湖北省',
provinces: [{
name: '湖北省',
city: ['武汉市', '黄石市', '十堰市', '宜昌市', '襄樊市', '鄂州市', '荆门市', '孝感市', '荆州市', '黄冈市', '咸宁市', '随州市', '恩施土家族苗族自治州', '仙桃市', '潜江市', '天门市', '神农架林区']
}, {
name: '陕西省',
city: ['西安市', '铜川市', '宝鸡市', '咸阳市', '渭南市', '延安市', '汉中市', '榆林市', '安康市', '商洛市']
}, {
name: '吉林省',
city: ['长春市', '吉林市', '四平市', '辽源市', '通化市', '白山市', '松原市', '白城市', '延边朝鲜族自治州']
}, {
name: '福建省',
city: ['福州市', '厦门市', '莆田市', '三明市', '泉州市', '漳州市', '南平市', '龙岩市', '宁德市']
}, {
name: '贵州省',
city: ['贵阳市', '六盘水市', '遵义市', '安顺市', '铜仁地区', '黔西南布依族苗族自治州', '毕节地区', '黔东南苗族侗族自治州', '黔南布依族苗族自治州']
}]
},
methods: {
getProvince: function(event) {
/* 获得主菜单项 */
this.pname = event.target.value;
}
},
computed: {
getCities: function() {
/* 获得相应省份的下标 */
for (var i = 0; i < this.provinces.length; i++) {
if (this.provinces[i].name == this.pname) {
return this.provinces[i].city;
}
}
}
}
});
</script>
</body>
</html>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190162895.png)
第七章 表单控件绑定
7.1 绑定文本框
v-model 会根据控件类型自动选择正确的方法来更新元素
7.1.1 单行文本框
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文本框搜索</title>
<script src="../vue.min.js"></script>
<link rel="stylesheet" href="css/table.css">
</head>
<body>
<div id="app">
<p><input type="text" v-model='searchStr' placeholder="keyword"></p>
<table>
<tr v-for='user in results'>
<td v-for='(value,key) in user'>{{value}}</td>
</tr>
</table>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
searchStr: '',
users: [{
name: '张山',
pos: '浙江宁波',
sex: '女'
}, {
name: '李四',
pos: '浙江杭州',
sex: '男'
}, {
name: 'Rain',
pos: '浙江温州',
sex: '女'
}, {
name: 'MAXMAN',
pos: '湖南长沙',
sex: '男'
}, ]
},
computed: {
results: function() {
var users = this.users;
if (this.searchStr == '') {
return users;
}
var searchStr = this.searchStr.trim().toLowerCase();
users = users.filter(function(ele) {
if (ele.name.toLowerCase().indexOf(searchStr) != -1 ||
ele.pos.toLowerCase().indexOf(searchStr) != -1 ||
ele.sex.toLowerCase().indexOf(searchStr) != -1
) {
return ele;
}
});
return users;
}
}
})
</script>
</body>
</html>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190114301.png)
7.1.2 多行文本框
<body>
<div id="app">
<textarea v-model='msg' placeholder="edit...."></textarea>
<!-- 加上的style确保p中显示的内容可以换行 -->
<p style="white-space: pre;">{{msg}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
msg: ''
}
});
</script>
</body>
7.2 绑定复选框
7.2.1 单个复选框
7.2.2 多个复选框
全选 全不选 反选操作
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多个复选框</title>
<script src="../vue.min.js"></script>
</head>
<body>
<div id="app">
<p v-for='item in checkedArr'>
<input type="checkbox" v-model='checkedNames' :value="item">
<label>{{item}}</label>
</p>
<p v-if='checked'>选择是: {{result}}</p>
<P>
<button @click='allChecked'>全选</button>
<button @click='noChecked'>全不选</button>
<button @click='reverseChecked'>反选</button>
</P>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
checked: false,
checkedNames: [],
checkedArr: ['xiaomi', 'huawei', 'OPPO', 'vivo', 'apple'],
tempArr: []
},
methods: {
allChecked: function () {
this.checkedNames = this.checkedArr;
},
noChecked: function () {
this.checkedNames = [];
},
reverseChecked: function () {
this.tempArr = [];
for (var i = 0; i < this.checkedArr.length; i++) {
if (!this.checkedNames.includes(this.checkedArr[i])) {
this.tempArr.push(this.checkedArr[i]);
}
}
this.checkedNames = this.tempArr;
}
},
/* 获取选中的兴趣爱好 */
computed: {
result: function () {
return this.checkedNames.toString();
}
},
watch: {
'checkedNames': function () {
if (this.checkedNames.length > 0) {
this.checked = true;
} else {
this.checked = false;
}
}
}
});
</script>
</body>
</html>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190190086.png)
7.3 绑定单选按钮
<body>
<div id="app">
<h2>查话费查流量</h2>
<input type="radio" value="balance" v-model='type'><label for="balance">查话费</label>
<input type="radio" value="traffic" v-model='type'><label for="traffic">查流量</label>
<button v-on:click='check'>查询</button>
<p v-if='show'>查询的结果:{{msg}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
show: false,
msg: '',
type: ''
},
methods: {
check: function() {
this.show = true;
if (this.type == 'balance') {
this.msg = '您的余额为6.66元'
} else if (this.type == 'traffic') {
this.msg = '您的剩余流量为66.6MB'
} else {
this.msg = '您还未选择任何选项'
}
}
},
});
</script>
</body>
7.4 绑定下拉菜单
7.4.1 单选
7.4.2 多选
<body>
<div id="app">
<select multiple v-model='selected' :style='selectStyle'>
<option v-for='like in likes':value="like" >{{like}}</option>
</select>
<p v-if='show'>{{selected}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
selected: [],
show: false,
likes: ['music', 'sport', 'run', 'reading', 'writing'],
selectStyle: {
'width': '130px',
'height': '70px'
}
},
watch: {
/* 监听 只有选择之后才会显示已选择的选项 */
'selected': function() {
if (this.selected.length > 0) {
this.show = true;
} else {
this.show = false;
}
}
}
});
</script>
</body>
<body>
<div id="app">
<select :style='selectStyle' multiple v-model='left'>
<option v-for='option in optional' :value='option'>{{option}}</option>
</select>
<div>
<button @click='toLeft'> << </button>
<button @click='toRight'> >> </button>
</div>
<select :style='selectStyle' multiple v-model='right'>
<option v-for='option in selected' :value='option'>{{option}}</option>
</select>
<p>{{left}}-----{{right}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
/* 全部的选项列表 */
optional: ['music', 'sport', 'run', 'reading', 'writing', 'walking'],
/* 选中的 */
selected: [],
left: [],
right: [],
selectStyle: {
'width': '120px',
'height': '140px'
}
},
methods: {
toLeft: function() {
for (var i = 0; i < this.right.length; i++) {
this.optional.push(this.right[i]);
/* 从已选列表中移除 */
var index = this.selected.indexOf(this.right[i]);
this.selected.splice(index, 1);
}
this.right = [];
},
toRight: function() {
for (var i = 0; i < this.left.length; i++) {
this.selected.push(this.left[i]);
var index = this.optional.indexOf(this.left[i]);
this.optional.splice(index, 1);
}
this.left = [];
}
},
})
</script>
</body>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190140157.png)
7.5 值绑定
把值绑定到Vue实例的一个动态属性上
7.5.1 单选按钮
<body>
<div id="app">
<P v-for='(value,key) in sexObj'>
<input type="radio" :value='key' v-model='sex'><label>{{value}}</label>
</P>
<p>result: {{sex}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
sex: '',
sexObj: {
'man': '男',
'women': '女'
}
}
});
</script>
</body>
7.5.2 复选框
在单个复选框中,用true-value false-value 属性将值绑定到动态属性上
<body>
<div id="app">
<input type="checkbox" v-model='toggle' :true-value='yes' :false-value='no'>
<label>{{toggle}}</label>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
toggle: '',
yes: '选中',
no: '取消'
}
});
</script>
</body>
7.5.3 下拉菜单
<body>
<div id="app">
<select v-model='selected'>
<option v-for='option in options' :value='option'>{{option}}</option>
</select>
<P>{{selected}}</P>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
selected: [],
options: ['music', 'sport', 'run', 'reading', 'writing']
}
});
</script>
</body>
7.6 使用修饰符
7.6.1 lazy
添加lazy修饰符之后转变为使用change事件同步
<body>
<div id="app">
<input type="text" v-model.lazy='msg'>
<p>{{msg}}</p>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
msg: ''
}
});
</script>
</body>
7.6.2 Number
自动将用户输入转换为数值类型;如果为转换结果为Nan,则返回用户输入的原始值
<input type="text" v-model.number='msg'>
7.6.3 trim
自动过滤用户输入的舒服穿首尾空格
<input type="text" v-model.trim='msg'>
案例: 三级级联操作
第八章 自定义指令
8.1 注册指令
8.1.1 注册全局指令
Vue.directive(id,definition)
id:指令的唯一标识
definition: 定义对象-->定义的指令的钩子函数
<body>
<div id="app">
<input v-focus>
</div>
<script type="text/javascript">
Vue.directive('focus', {
/* 当被绑定的元素插入DOM中时,使元素获得焦点 */
inserted: function(el) {
el.focus();
}
});
let app = new Vue({
el: '#app'
});
</script>
</body>
8.1.2 注册局部指令
案例: 为元素添加边框
<body>
<div id="app">
<span v-add-border='border'>hello world</span>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
border: '2px solid blue'
},
directives: {
addBorder: {
inserted: function(el, binding) {
el.style.border = binding.value;
}
}
}
});
</script>
</body>
8.2 钩子函数
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190212160.png)
定义对象的钩子函数参数如下:
el:指令所绑定的元素,可以用来直接操作 DOM
binding: 一个对象
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 编译生成的虚拟节点
oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用
<body>
<div id="app" v-demo:hello.a.b='message'></div>
<script type="text/javascript">
Vue.directive('demo', function(el, binding, vnode) {
el.innerHTML =
'name: ' + binding.name + '<br>' +
'value: ' + binding.value + '<br>' +
'expression: ' + binding.expression + '<br>' +
'arguement: ' + binding.args + '<br>' +
'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(',')
});
let app = new Vue({
el: '#app',
data: {
message: 'hello world'
}
});
</script>
</body>
name: demo
value: hello world
expression: message
arguement: undefined
modifiers: {"a":true,"b":true}
vnode keys: tag,data,children,text,elm,ns,context,fnContext,fnOptions,fnScopeId,key,componentOptions,componentInstance,parent,raw,isStatic,isRootInsert,isComment,isCloned,isOnce,asyncFactory,asyncMeta,isAsyncPlaceholder
下拉列表改变文字的大小
<body>
<div id="app">
<select v-model='size'>
<option v-for='value in values' :value='value'>{{value}}</option>
</select>
<span v-font-size='size'>hello</span>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
size: '10px',
values: ['10px', '15px', '20px', '25px', '30px', '40px']
},
directives: {
fontSize: function(el, binding) {
el.style.fontSize = binding.value;
}
}
});
</script>
</body>
![图片Base64编码](https://img-blog.csdnimg.cn/2022010708190274723.png)
8.3 自定义指令的绑定值
8.3.1 绑定数值常量
<body>
<div id="app">
<p v-set-position='500'>hello</p>
</div>
<script type="text/javascript">
Vue.directive('setPosition', function(el, binding) {
el.style.position = 'fixed';
el.style.left = binding.value + 'px';
});
let app = new Vue({
el: '#app'
});
</script>
</body>
8.3.2 绑定字符串常量
动态改变文字的颜色
<body>
<div id="app">
<input type="color" v-model="color"><span v-set-color='color'>{{color}}</span>
<span v-set-color='color'>hello Vue.js</span>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
color: '#ce2222'
},
directives: {
'setColor': function(el, binding) {
el.style.color = binding.value;
}
}
});
</script>
</body>