ZhangYang's Blog

Vue.js造轮子系列

导航菜单实例

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
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Vue.js 导航菜单</title>
<script src="https://cdn.bootcss.com/vue/2.6.3/vue.min.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
body{
text-align: center;
}
nav{
display: inline-block;
background-color: skyblue;
border-radius: 4px;
margin-top: 10%;
font-size: 0;
}
nav a{
display: inline-block;
padding: 20px 30px;
color: #fff;
font-size: 20px;
text-decoration: none;
transition: background-color 0.5s;
}
p{
margin-top: 20px;
font-size: 22px;
font-weight: bold;
color: #ccc;
}
p b{
color: #fff;
font-weight: bold;
background-color: #c4d7e0;
padding: 4px 8px;
margin-left: 10px;
}
nav.Home .home,
nav.Projects .projects,
nav.Services .services,
nav.Contact .contact{
background-color: #e35880;
}
</style>
</head>
<body>
<div id="main">
<nav v-bind:class="active" v-on:click.prevent>
<a href="#" class="home" v-on:click="makeActive('Home')">Home</a>
<a href="#" class="projects" v-on:click="makeActive('Projects')">Projects</a>
<a href="#" class="services" v-on:click="makeActive('Services')">Services</a>
<a href="#" class="contact" v-on:click="makeActive('Contact')">Contact</a>
</nav>
<p>您选择了<b>{{ active }}菜单</b></p>
</div>
<script>
var nav = new Vue({
el: '#main',
data: {
active: 'Home'
},
methods: {
makeActive: function(item){
this.active = item
}
}
})
</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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Vue.js 编辑文本</title>
<script src="https://cdn.bootcss.com/vue/2.6.3/vue.min.js"></script>
<style>
[v-cloak]{
display: none
}
*{
margin: 0;
padding: 0;
}
body{
text-align: center;
}
#main{
position: relative;
top: 150px;
}
.tooltip{
position: absolute;
left: 50%;
top: -74px;
margin-left: -150px;
width: 300px;
padding: 10px;
background-color: skyblue;
border-radius:3px;
}
.tooltip:after{
content: '';
width: 0;
height: 0;
position: absolute;
left: 50%;
top: 100%;
margin-left: -5px;
border-top: 10px solid skyblue;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid transparent;
}
.tooltip input{
border: none;
width: 100%;
line-height: 34px;
border-radius: 3px;
text-align: center;
font-size: 16px;
color: #8d9395;
}
p{
font-size: 24px;
font-weight: bold;
cursor: default;
color: #6d8088;
}
p:before{
content:'✎';
display: inline-block;
margin-right: 10px;
}
</style>
</head>
<body>
<div id="main" v-cloak v-on:click="hideTooltip">
<div class="tooltip" v-on:click.stop v-if="show_tooltip">
<input type="text" v-model="text_content">
</div>
<p v-on:click.stop="toggleTooltip">{{text_content}}</p>
</div>
<script>
var nav = new Vue({
el: '#main',
data: {
show_tooltip: false,
text_content: '点我,并编辑内容。'
},
methods: {
hideTooltip: function () {
this.show_tooltip = false
},
toggleTooltip: function(){
this.show_tooltip = !this.show_tooltip
}
}
})
</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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Vue.js 订单列表</title>
<script src="https://cdn.bootcss.com/vue/2.6.3/vue.min.js"></script>
<style>
[v-cloak]{
display: none
}
*{
margin: 0;
padding: 0;
}
body{
text-align: center;
}
#main{
position: relative;
top: 150px;
}
form{
background-color: skyblue;
border-radius: 2px;
width: 400px;
margin: 50px auto;
}
form h1{
color: #fff;
font-size: 40px;
font-weight: bold;
}
form ul{
list-style: none;
color: #fff;
font-size: 20px;
font-weight: bold;
text-align: left;
margin-top: 20px;
margin-bottom: 15px;
}
form ul li{
padding: 20px 30px;
background-color: pink;
margin-bottom: 8px;
cursor:pointer;
}
form ul li span{
float: right;
}
form ul li.active{
background-color: green;
}
div.total{
border-top: 1px solid #fff;
padding: 15px;
margin: 0 15px;
font-size:20px;
font-weight:bold;
text-align: left;
color: #fff;
}
div.total span{
float: right;
}
</style>
</head>
<body>
<form id="main" v-cloak>
<h1>Services</h1>
<ul>
<li v-for="service in services" v-on:click="toggleActive(service)" v-bind:class="{'active' : service.active}">
{{ service.name }} <span>{{ service.price | currency }}</span>
</li>
</ul>
<div class="total">
Total: <span>{{ total() | currency }}</span>
</div>
</form>
<script>
Vue.filter('currency',function(value){
return '$' + value.toFixed(2)
})
var nav = new Vue({
el: '#main',
data: {
services: [
{
name: 'Web Development',
price: 300,
active: true
},
{
name: 'Design',
price: 400,
active: false
},
{
name: 'Integration',
price: 250,
active: false
},
{
name: 'Training',
price: 220,
active: false
}
]
},
methods: {
toggleActive: function(s){
s.active = !s.active
},
total: function(){
var total = 0
this.services.forEach(function(s){
if(s.active){
total += s.price
}
})
return total
}
}
})
</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
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Vue.js 搜索页面</title>
<script src="https://cdn.bootcss.com/vue/2.6.3/vue.min.js"></script>
<style>
[v-cloak]{
display: none
}
*{
margin: 0;
padding: 0;
}
body{
text-align: center;
}
#main{
position: relative;
top: 150px;
}
.bar{
width: 400px;
padding: 10px;
border-radius: 2px;
margin: 45px auto;
background-color: skyblue;
}
.bar input{
background: #fff;
border: none;
width: 100%;
line-height: 20px;
padding: 10px 0;
text-align: left;
border-radius: 2px;
color: #ccc;
font-weight: bold;
}
ul{
list-style: none;
width: 450px;
margin:0 auto;
text-align: left;
}
ul li{
border-bottom: 1px solid #ddd;
padding: 10px;
overflow: hidden;
}
ul li img{
width: 40px;
height: 40px;
float: left;
}
ul li p{
margin-left: 58px;
font-weight: bold;
padding-top: 6px;
color: #ccc;
}
</style>
</head>
<body>
<form id="main" v-cloak>
<div class="bar">
<input type="text" v-model="searchString" placeholder="输入搜索内容">
</div>
<ul>
<li v-for="article in filteredArticles">
<a v-bind:href="article.url"><img v-bind:src="article.image"></a>
<p>{{ article.title }}</p>
</li>
</ul>
</form>
<script>
var nav = new Vue({
el: '#main',
data: {
searchString: '',
articles: [
{
"title": "What You Need To Know About CSS Variables",
"url": "http://www.runoob.com/css/css-tutorial.html",
"image": "http://static.runoob.com/images/icon/css.png"
},
{
"title": "Freebie: 4 Great Looking Pricing Tables",
"url": "http://www.runoob.com/html/html-tutorial.html",
"image": "http://static.runoob.com/images/icon/html.png"
},
{
"title": "20 Interesting JavaScript and CSS Libraries for February 2016",
"url": "http://www.runoob.com/css3/css3-tutorial.html",
"image": "http://static.runoob.com/images/icon/css3.png"
},
{
"title": "Quick Tip: The Easiest Way To Make Responsive Headers",
"url": "http://www.runoob.com/css3/css3-tutorial.html",
"image": "http://static.runoob.com/images/icon/css3.png"
},
{
"title": "Learn SQL In 20 Minutes",
"url": "http://www.runoob.com/sql/sql-tutorial.html",
"image": "http://static.runoob.com/images/icon/sql.png"
},
{
"title": "Creating Your First Desktop App With HTML, JS and Electron",
"url": "http://www.runoob.com/js/js-tutorial.html",
"image": "http://static.runoob.com/images/icon/html.png"
}
]
},
computed: {
filteredArticles: function(){
var articles_array = this.articles
var searchString = this.searchString
if (!searchString) {
return articles_array
}
searchString = searchString.trim().toLowerCase()
articles_array = articles_array.filter(function(item){
if (item.title.toLowerCase().indexOf(searchString)!==-1) {
return item
}
})
return articles_array
}
}
})
</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
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Vue.js 切换不同显示布局</title>
<script src="https://cdn.bootcss.com/vue/2.6.3/vue.min.js"></script>
<style>
[v-cloak]{
display: none
}
*{
margin: 0;
padding: 0;
}
body{
text-align: center;
}
.bar{
background-color: skyblue;
border-radius: 2px;
width: 580px;
padding: 10px;
margin: 45px auto 25px;
text-align:right;
}
.bar a{
background:#4987a1 center center no-repeat;
width:32px;
height:32px;
display:inline-block;
text-decoration:none;
margin-right:5px;
border-radius:2px;
cursor:pointer;
}
.bar a.active{
background-color: pink;
}
.bar a.list-icon{
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkYzNkFCQ0ZBMTBCRTExRTM5NDk4RDFEM0E5RkQ1NEZCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkYzNkFCQ0ZCMTBCRTExRTM5NDk4RDFEM0E5RkQ1NEZCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RjM2QUJDRjgxMEJFMTFFMzk0OThEMUQzQTlGRDU0RkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RjM2QUJDRjkxMEJFMTFFMzk0OThEMUQzQTlGRDU0RkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7h1bLqAAAAWUlEQVR42mL8////BwYGBn4GCACxBRlIAIxAA/4jaXoPEkMyjJ+A/g9MDJQBRhYg8RFqMwg8RJIUINYLFDmBUi+ADQAF1n8ofk9yIAy6WPg4GgtDMRYAAgwAdLYwLAoIwPgAAAAASUVORK5CYII=);
}
.bar a.grid-icon{
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjBEQkMyQzE0MTBCRjExRTNBMDlGRTYyOTlBNDdCN0I4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjBEQkMyQzE1MTBCRjExRTNBMDlGRTYyOTlBNDdCN0I4Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MERCQzJDMTIxMEJGMTFFM0EwOUZFNjI5OUE0N0I3QjgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MERCQzJDMTMxMEJGMTFFM0EwOUZFNjI5OUE0N0I3QjgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4MjPshAAAAXklEQVR42mL4////h/8I8B6IGaCYKHFGEMnAwCDIAAHvgZgRyiZKnImBQsACxB+hNoDAQyQ5osQZIT4gH1DsBZABH6AB8x/JaQzEig++WPiII7Rxio/GwmCIBYAAAwAwVIzMp1R0aQAAAABJRU5ErkJggg==);
}
ul.list{
list-style: none;
width: 500px;
margin: 0 auto;
text-align: left;
}
ul.list li{
border-bottom: 1px solid #ddd;
padding: 10px;
overflow: hidden;
}
ul.list li img{
width: 80px;
height: 80px;
float:left;
border:none;
}
ul.list li p{
margin-left: 135px;
font-weight: bold;
color:#6e7a7f;
}
ul.grid{
list-style: none;
width: 570px;
margin: 0 auto;
text-align: left;
}
ul.grid li{
padding: 2px;
float:left;
}
ul.grid li img{
width: 180px;
height: 180px;
object-fit: cover;
display:block;
border:none;
}
</style>
</head>
<body>
<form id="main" v-cloak>
<div class="bar">
<a class="list-icon" v-bind:class="{ 'active': layout == 'list' }" v-on:click="layout = 'list'"></a>
<a class="grid-icon" v-bind:class="{ 'active': layout == 'grid' }" v-on:click="layout = 'grid'"></a>
</div>
<ul v-if="layout == 'grid'" class="grid">
<li v-for="a in articles">
<a v-bind:href="a.url" target="_blank"><img v-bind:src="a.image.large"></a>
</li>
</ul>
<ul v-if="layout == 'list'" class="list">
<!-- 使用大图,没有文本 -->
<li v-for="a in articles">
<a v-bind:href="a.url" target="_blank"><img v-bind:src="a.image.small" /></a>
<p>{{a.title}}</p>
</li>
</ul>
</form>
<script>
var nav = new Vue({
el: '#main',
data: {
layout: 'grid',
articles: [
{
"title": "HTML 教程",
"url": "http://www.runoob.com/html/html-tutorial.html",
"image": {
"large": "http://static.runoob.com/images/mix/htmlbig.png",
"small": "http://static.runoob.com/images/icon/html.png"
}
},
{
"title": "CSS 教程",
"url": "http://www.runoob.com/css/css-tutorial.html",
"image": {
"large": "http://static.runoob.com/images/mix/cssbig.png",
"small": "http://static.runoob.com/images/icon/css.png"
}
},
{
"title": "JS 教程",
"url": "http://www.runoob.com/js/js-tutorial.html",
"image": {
"large": "http://static.runoob.com/images/mix/jsbig.jpeg",
"small": "http://static.runoob.com/images/icon/js.png"
}
},
{
"title": "SQL 教程",
"url": "http://www.runoob.com/sql/sql-tutorial.html",
"image": {
"large": "http://static.runoob.com/images/mix/sqlbig.png",
"small": "http://static.runoob.com/images/icon/sql.png"
}
},
{
"title": "Ajax 教程",
"url": "http://www.runoob.com/ajax/ajax-tutorial.html",
"image": {
"large": "http://static.runoob.com/images/mix/ajaxbig.png",
"small": "http://static.runoob.com/images/icon/ajax.png"
}
},
{
"title": "Python 教程",
"url": "http://www.runoob.com/pyhton/pyhton-tutorial.html",
"image": {
"large": "http://static.runoob.com/images/mix/pythonbig.png",
"small": "http://static.runoob.com/images/icon/python.png"
}
}
]
}
})
</script>
</body>
</html>