# vue 的事件指令

作用:给标签绑定事件

1
2
3
4
5
6
7
8
9
10
<div v-on:事件类型="表达式"></div>
因为事件也经常使用,所以可以把v-on简写为@
<div @事件类型="表达式"></div>
//语法:
@事件类型="表达式"
比如:
<div @click="fun"></div>
<div @click="age>18"></div>
//一般表达式写事件的函数名

# v-model 双向数据绑定的指令

作用:实现数据与 DOM 结构的双向绑定,彼此之间互相影响。
数据的改变会引起 DOM 的改变;
DOM 的改变也会引起数据的改变。(获取用户的值)

写在何处:表单控件 input、select、textarea、组件

语法:
在 HTML 属性上使用
v-model=“数据属性名”

特点:
1、在表单元素上创建双向数据绑定
2、会根据控件类型自动选取正确的方法来更新元素交互的值。即不同的 type 数据交互的方式也不同,比如单行文本框与 value 属性交互,单选复选框 checkbox 与 checked 属性交互
3、负责监听用户的输入事件以更新数据

注意:
1、会忽略所有表单元素的 value、checked、selected 等属性的初始值。也就是在标签上再写 value 属性等是无效的了。

1
2
<input value="默认值" v-model="ipt">
//这里的value=“默认值”不会显示,无效了

​ 2、将 vue 实例的数据作为数据来源

1
2
3
4
5
6
7
<input v-model="ipt">
//ipt属性需要在vue的data中也要有
<script>
data:{
ipt:""
}
</script>

​ 3、需要在数据对象中声明初始值

1
2
3
4
5
6
7
<input v-model="ipt">
//ipt属性需要在vue的data中也要有
<script>
data:{
ipt:"这里设置要显示到input的默认值"
}
</script>

# v-for 指令 - 实现列表的循环

作用:遍历数组或对象,并渲染成 DOM 结构。

用于:标签中,要循环生成谁,就加在谁身上

1
2
3
4
5
6
7
8
9
10
//item每一项元素,index索引
<li v-for="item,index in 数组"></li>
//为了让index,item看起来更加像参数,可以使用()包起来,而且index可以省略
<li v-for="(item,index) in 数组"></li>
//循环对象
//item是每一项,key是属性名,index是索引
//后面的key,index可以省略,()也可以省略
<li v-for="(item,key,index) in 对象"></li>
// 注意:是添加到要重复生成的元素而不是它的父级上
//补充一个知识点:对象如何也有索引了?这个不是因为学了vue才有的,而是vue对对象进行了改造,让对象有了索引

# 对象的响应式变化

数据都是计划好了的,使用插值运算符才不会报错。如果试图显示一个尚不存在的 data 属性值,那么很可能会报错。也就是只有计划好的数据或计划好的数据进行了改变才会做响应式的更新(动态更新 HTML 上的数据)
目的:操作一个未来的数据时,让视图也能响应式的变化。

以下几种方式虽然可以给对象添加数据,但是不会引起视图的更新:

1
2
3
4
5
6
7
8
JS:
data:{
obj:{}
}
//第一种
obj.name="张三"
//第二种
Object.assign(vm.obj,{新的对象})

以下几种方式可以给对象添加数据,也可以引起视图的更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1、Vue.set(target,key,value);
参数说明:
{Object | Array} target 对象或数组作为target
{string | number} key 对象的属性名或数组的下标作为key
{any} value 任意JS类型值作为value
返回值:设置的值,即value

2、vm.$set(target,key,value);
实例上的方法,用法同1,只不过该方法是vue实例上的

3Object.assign(target,obj1,obj2)或直接重新赋值改写;
a、对象扩展方法,将该对象重新改写,也就是扩展了对象本身,返回的是被改写的target对象。注意target应该是一个空对象或者新对象。不然数据还是不会做响应。
b、还可以重新对上面的空对象进行重新赋值,也可以做到改写,从而引起数据刷新。
两种写法对比:
第二种写法一不小心会导致原来的要保留的属性也给替换掉。所以建议使用assign方法。

# 数组的响应式变化

1、避免以下几种添加方式就可以让数据响应式:

1
2
3
4
1. 直接通过数组下标添加,比如
arr[0]=123
2. 通过改变数组的长度
arr.length=2;

2、可以让按数据响应式的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
一、该方法都可以改变原数组,所以能做到响应式。
1、push() 往数组尾部插入
2、pop() 往数组头部插入
3、shift() 往数组尾部删除
4、unshift() 往数组头部删除
5、splice(index,howmany,要添加的数组元素) 可删除的同时还可添加,适合只替换某一项数组元素
6、sort() 排序
7、reverse() 反转

二、其他可间接改变数组的方法(类似于Object.assign,或直接替换原对象)
1、map/filter
2、concat
3、slice

# v-if,v-show,v-else

  1. v-if
    作用:用来新增或删除一个元素

    用于不需要频繁切换它的可见性那种场景,比如广告只需要打开显示一次那种。

    用法:

    1
    2
    3
    <div v-if="表达式">看看我是否被显示</div>
    //工作原理
    如果表达式成立,则显示该标签,否则删除,会自动将表达式转为一个布尔值
  2. v-show

    v-show 与 v-if 相比,v-show 性能更优,适用于平常显示和隐藏场景

    作用:用来显示或隐藏一个元素。相当于是操作了 display 值。

    1
    2
    3
    <div v-show="表达式">看看我是否被显示</div>
    //工作原理
    如果表达式成立,则显示该标签,否则隐藏(结构还在),会自动将表达式转为一个布尔值
  3. v-else

    1
    2
    跟v-if配套使用
    如果v-if显示了A元素,那么else代表的B元素就会隐藏,否则也成立

# 动态操作 class 和样式

用的还是 v-bind 指令

1
<div :class='box' :style="{color:red} "></div>
  1. :class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    给标签动态添加class的3种方式:
    1. 添加一个
    <div :class="box"></div>
    2. 添加多个:
    <div :class="[box1,box2,box3]"></div>
    3. 按需添加(重点,按需添加,满足条件再添加)
    里面写对象的形式,属性名指的是要添加的class,属性值指的是是否添加的条件
    <div :class="{要添加的class:条件表达式}"></div>

    比如,业绩达到>=10万,文字标红,业绩小于10w,则绿色,业绩达到<=1w,则灰色
    <div :class="{red:money>=10,green:money<10,gray:money<=1}">要着色的文字</div>
  2. :style
    作用:按需添加行内样式
    添加 {} 是因为样式也是这么写的,同时也是对象

    1
    2
    3
    <div :style="{样式1:值1}">样式文字</div>
    <div :style="{样式1:值1,样式2:值2}">样式文字</div>
    <div :style="{样式1:表达式}">样式文字</div>

# vue 实例

# tab 页

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue.v2.6.12.min.js"></script>
<style type="text/css">
.bgRed{ background-color: red; }
/*#app ul{ display: none; }*/
.v-enter{
opacity: 0;
}
.v-enter-active{
transition:all 2s;
}
.v-enter-to{
opacity: 1;
}
.v-leave{
opacity: 1;
}
.v-leave-active{
transition:all 1s;
}
.v-leave-to{
opacity: 0;
}
.abs ul{
position: absolute;
}
</style>
</head>
<body>
<div id="app">
<!-- tab结构,先在HTML中规划好tab标签页的结构
该结构就是我们平常写的tab切换页
-->
<!-- tab按钮 -->
<div class="tab">

<!-- 3个按钮 -->
<input
v-for="item,index in json"
type="button"
:class="{bgRed:index==i}"
:value="item.title"
@click="cg(index)">
<!-- <input type="button" value="娱乐新闻">
<input type="button" value="体育新闻"> -->
<!-- 3个tab面板 -->
<transition-group tag="div" mode="out-in" class="abs">
<ul v-show="index==i" v-for="item,index in json" :key="index">
<li v-for="t in item.list">{{t}}</li>
<!-- <li>西红柿首富</li>
<li>巨齿鲨</li> -->
</ul>
</transition-group>
<!-- <ul>
<li>XXX结婚了</li>
<li>XXX出轨了</li>
<li>XXX分手了</li>
</ul>
<ul>
<li>孙杨亚运会夺冠了</li>
<li>女足16:0大胜塔吉克斯坦</li>
<li>中国队在亚运会金牌总数已经突破100枚</li>
</ul> -->
</div>
</div>
<script>

//在vue中,一切皆数据,按钮和面板数据都用json来表示
//先规划我的数据
var json=[{
title:"电影新闻",
list:["一出好戏","西红柿首富","巨齿鲨"]
},{
title:"娱乐新闻",
list:["XXX结婚了","XXX出轨了","XXX分手了"]
},{
title:"体育新闻",
list:["孙杨亚运会夺冠了","女足16:0大胜塔吉克斯坦","中国队在亚运会金牌总数已经突破100枚"]
}
]

// HTML结构模拟出来后,就可以将结构改成数据了
var vm=new Vue({
el:"#app",
data:{
json,
// index表示的是当前是第几个面板(按钮)
i:0
},
methods:{
//i指的是调用时传进来的那个参数
cg(i){
this.i=i;
}
}
});

</script>
</body>
</html>

# 选择品牌

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue.v2.6.10.js"></script>
<!-- <script src="vue.js"></script> -->
<style type="text/css">
* {
margin: 0;
padding: 0;
}

li {
list-style: none;
}

a {
color: #333;
text-decoration: none;
}

a:hover {
color: red
}

#product {
width: 700px;
margin: 20px auto;
background: #f2f2f2;
border: 1px solid #ddd;
}

ul {
padding: 10px;
}

#filter {
padding: 0 10px;
height: 40px;
line-height: 40px;
background-color: #ddd
}

#brand span {
display: inline-block;
margin-right: 30px;
}

#brand a {
margin: 0 5px;
}

#brand li {
margin-bottom: 10px;
}

mark {
border: 1px solid red;
padding-left: 5px;
margin-right: 15px;
}

mark em {
border-left: 1px solid red;
padding: 0 5px;
margin-left: 5px;
font-style: normal;
}
</style>
</head>

<body>
<div id="product">
<div id="filter">
<span>您筛选的手机:</span>
<mark v-for="item,index in obj">{{item}}<em @click="del(index,item)">X</em></mark>
</div>
<ul id="brand">
<li v-for="item,index in json">
<span>{{item.title}}</span>
<a href="#" v-for="i in item.list" @click="add(index,i)">{{i}}</a>
<!-- <a href="#">小米</a>
<a href="#">魅族</a>
<a href="#">三星</a>
<a href="#">锤子</a>
<a href="#">VIVO</a>
<a href="#">OPPO</a> -->
</li>
<!-- <li>
<span>内存</span>
<a href="#">4GB</a>
<a href="#">2GB</a>
<a href="#">3GB</a>
<a href="#">2GB以下</a>
</li>
<li>
<span>存储</span>
<a href="#">16GB</a>
<a href="#">32GB</a>
<a href="#">64GB</a>
<a href="#">128GB及以上</a>
</li>
<li>
<span>尺寸</span>
<a href="#">5.6英寸及以上</a>
<a href="#">5.5-5.1英寸</a>
<a href="#">5.0-4.6英寸</a>
</li> -->
</ul>
</div>
<!--
要求与提示:
1、需要固定显示位置,也就是第一行只能显示品牌,且只能单选,这个可以通过对象的方式固定位置,因为对象的属性名是不能重复的,然后对象的键名可以设置为下标,下标来源于循环
2、提供删除功能
-->
<script>
var json = [{
title: "品牌",
list: ["苹果", "小米", "三星", "vivo", "OPPO", "华为"]
},
{
title: "内存",
list: ["4GB", "8GB", "2GB", "3GB以下", "8GB以上"]
},
{
title: "存储",
list: ["8GB", "16GB", "32GB", "64GB以下", "128GB以上"]
},
{
title: "尺寸",
list: ["4.5英寸", "5.5英寸以上", "4英寸以下"]
},
];
var vm=new Vue({
el: "#product",
data: {
json,
obj:{}
},
methods:{
add(index,i){
this.$set(this.obj,index,i);
},
del(index){
this.$delete(this.obj,index);
}
}
});
</script>
</body>

</html>

# 轮播图

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<script src="vue.js"></script>
<title>Vue焦点图</title>
</head>

<body>


<style type="text/css">
/* css 重置 */
* {
margin: 0;
padding: 0;
list-style: none;
}

body {
background: #fff;
font: normal 12px/22px 宋体;
width: 100%;
}

img {
border: 0;
}

a {
text-decoration: none;
color: #333;
}

a:hover {
color: #1974A1;
}

#footer {
text-align: center;
padding-top: 20px;
}

/* 本例子css */
.w3cFocus {
width: 100%;
position: relative;
height: 250px;
padding: 10px 0;
background: #292929;
}

.w3cFocus .prev,
.w3cFocus .next {
position: absolute;
display: block;
left: 10px;
top: 97px;
width: 46px;
height: 62px;
background: url(img/focusAdvBg.png) no-repeat;
filter: alpha(opacity=80);
opacity: 0.8;
}

.w3cFocus .next {
left: auto;
right: 10px;
background-position: -46px 0;
}

.w3cFocus .prev:hover,
.w3cFocus .next:hover {
filter: alpha(opacity=100) !important;
opacity: 1 !important;
}

.w3cFocusIn {
width: 960px;
height: 250px;
position: relative;
margin: 0 auto;
overflow: hidden;
}

.w3cFocusIn .bd ul {
position: relative;
height: 250px;
overflow: hidden;
}

.w3cFocusIn .bd li {
float: left;
width: 960px;
vertical-align: middle;
}

.w3cFocusIn .bd li img {
width: 960px;
height: 250px;
display: block;
}

.w3cFocusIn .hd {
position: absolute;
right: 4px;
bottom: 6px;
}

.w3cFocusIn .hd ul {
vertical-align: middle;
display: inline-block;
*display: inline;
overflow: hidden;
zoom: 1;
}

.w3cFocusIn .hd ul li {
position: relative;
float: left;
display: inline;
padding-top: 4px;
margin-right: 6px;
filter: alpha(opacity=80);
opacity: 0.8;
cursor: pointer;
}

.w3cFocusIn .hd ul li img {
width: 76px;
height: 46px;
border: 2px solid #fff;
display: block;
}

.w3cFocusIn .hd ul li.on {
filter: alpha(opacity=100);
opacity: 1;
background: url(img/focusArrow.png) center 0 no-repeat;
}

.w3cFocusIn .hd ul li.on img {
border: 2px solid #3499EA;
border-bottom-width: 4px;
}
</style>
<div class="w3cFocus" id="slide">
<div class="w3cFocusIn">
<div class="bd">
<ul>
<li v-for="item,index in data" v-show="index==i"><a href="#"><img :src="item.bgimg" /></a></li>
<!-- <li><a href="#"><img src="img/pic2.jpg" /></a></li>
<li><a href="#"><img src="img/pic3.jpg" /></a></li>
<li><a href="#"><img src="img/pic4.jpg" /></a></li> -->
</ul>
</div>

<div class="hd">
<ul>
<li v-for="item,index in data" :class="{on:index==i}" @click="cg(index)"><img :src="item.smimg" />
</li>
<!-- <li><img src="img/pic2_s.png" /></li>
<li><img src="img/pic3_s.png" /></li>
<li><img src="img/pic4_s.png" /></li> -->
</ul>
</div>
</div>
<a class="prev" href="javascript:void(0)" @click="i--,i<0?i=3:''"></a>
<a class="next" href="javascript:void(0)" @click="i++,i>3?i=0:''"></a>

</div>
<script>
//数据
var data = [{
bgimg: "img/pic1.png",
smimg: "img/pic1_s.png"
},
{
bgimg: "img/pic2.jpg",
smimg: "img/pic2_s.png"
},
{
bgimg: "img/pic3.jpg",
smimg: "img/pic3_s.png"
},
{
bgimg: "img/pic4.jpg",
smimg: "img/pic4_s.png"
}
];
var vm = new Vue({
el: "#slide",
data: {
//这里放数据
data,
i: 0
},
methods: {
//i指的是调用时传进来的那个参数
cg(i) {
this.i = i;
}
},

});
// 定时轮播
var timer=setInterval(fun, 1000)
function fun() {
vm.i += 1
if (vm.i > 3) {
vm.i = 0
}
}
// 移入停止
var slide=document.getElementById("slide")
slide.onmouseenter=function(){
clearInterval(timer)
}
// 移出继续
slide.onmouseleave=function(){
timer=setInterval(fun, 1000)
}
</script>

</body>

</html>

# 其他指令

  1. v-text

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <div>
    {{msg}}
    </div>
    //可以使用v-text来代替
    <div v-text="msg">
    </div>
    // 更新元素的textContent(文本内容),可替代{{}}
    // 为什么要使用?
    // 如果网速比较慢时还没等到vue解析{{}},这时网页会出现源代码,但使用v-text 是写在标签内的,就不会有该问题。
    // 总结:使用频率不高

  2. v-html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //v-html会渲染写在数据中的标签内容
    <div v-html="msg">

    </div>
    <script>
    new Vue({
    data:{
    msg:"<div>这里的数据带标签内容</div>"
    }
    });
    </script>

    更新元素的 innerHTML
    如果不使用该指令,插入的 HTML 结构会变成文本显示
    注意:不要插入不安全的 HTML 结构,比如允许用户输入 HTML 并解析
    我们之前的属性放的值都是一些简单的文本,现在也可以放一些 HTML 标签和内容,然后使用该指令解析

  3. v-once

    1
    2
    3
    4
    <div v-once>
    {{msg}}
    </div>
    //msg的值只会在第一次时渲染,后续即使数据更新了也不会被改变。类似于一次性事件

    不需要赋值,只需要写指令

    只渲染一次,随后数据改变将不再渲染,视为静态内容
    也就是只会使用最开始给标签的值,以后尽管数据更新了,但该处的数据依然保持不变。
    用于优化更新性能
    使用场景:比如一些 tab 标题等不需要更改的地方

  4. v-cloak

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //批量替换v-text的,让所有的小胡子语法在数据准备好了再渲染
    <style>
    [v-cloak]{
    display:none;
    }
    </style>
    <div id="app" v-cloak>
    {{msg}}
    </div>
    // 隐藏未编译的Mustache标签({{}})直到实例准备完毕
    // 该指令其实就是用来替代v-text的,这个直接放到vue托管的最开始标签处,然后在样式中写 [v-cloak]{ display:none} 即可将vue托管的HTML标签中的所有{{}}都先隐藏,直到解析完毕。这样就避免了有时候在手机端先显示{{}}的尴尬。

# 事件修饰符

event 对象、阻止冒泡、默认事件等

1
2
//.enter就是事件修饰符,指的是按了回车键再执行事件
<input @keyup.enter="fun">
  1. 事件修饰符

    1
    2
    3
    4
    5
    .stop - 调用 event.stopPropagation()。
    .prevent - 调用 event.preventDefault()。
    .capture - 添加事件侦听器时使用 capture 模式。
    .self - 只当事件是从侦听器绑定的元素本身触发时才触发。(只能够在事件源上触发)
    .once - 只触发一次回调。
  2. 按键修饰符:(一般用于键盘、鼠标事件中)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    .enter 键盘代码 也可写成 .13 - 按回车键时触发
    .tab - 按tab键时触发
    .delete - 按delete键或backspace退格键时触发
    .esc - 按Esc退出键时触发
    .space - 按空格键时触发
    .ctrl - Ctrl键
    .alt -alt键
    .shift -shift键
    .up - 按键盘上
    .down -键盘下
    .left - (2.2.0) 键盘左箭头(键盘事件)、只当点击鼠标左键时触发(点击事件)。
    .right (2.2.0) 键盘右箭头(键盘事件)、只当点击鼠标右键时触发(点击事件)。
    .middle - (2.2.0) 只当点击鼠标中键时触发(点击事件)。

    如果还想要其他键名怎么办?可以直接写键值,比如enter的键值为13

    如果要组合按键触发,可以写两个键值,比如Ctrl+enter键一起按下去才触发可以这样写:
    @keyup.ctrl.enter="事件名"

用法总结:

1. v-on:事件名.修饰符="事件处理函数"
   2. v-on:事件名.修饰符  
      		  不需要添加事件处理函数,起到的就是与修饰符有关的操作
   3. v-on:事件名.修饰符1.修饰符2="事件处理函数"
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

tz 微信支付

微信支付

tz 支付宝

支付宝