前端【VUE】02-vue指令【v-html 、v-show、 v-if 、v-else、v-on、v-bind、v-for、v-model】
Vue 指令
① v-html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 11 <div id="app"> 12 <div v-html="msg"></div> 13 </div> 14 15 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 16 <script> 17 const app = new Vue({ 18 el: '#app', 19 data: { 20 msg: ` 21 <h3>学前端!</h3> 22 ` 23 } 24 }) 25 </script> 26 </body> 27 </html>
② v-show 和 v-if
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>v-show和v-if</title> 8 <style> 9 .box { 10 width: 200px; 11 height: 100px; 12 line-height: 100px; 13 margin: 10px; 14 border: 3px solid #000; 15 text-align: center; 16 border-radius: 5px; 17 box-shadow: 2px 2px 2px #ccc; 18 } 19 </style> 20 </head> 21 <body> 22 <!-- 23 v-show底层原理:切换 css 的 display: none 来控制显示隐藏 24 v-if 底层原理:根据 判断条件 控制元素的 创建 和 移除(条件渲染) 25 --> 26 <div id="app"> 27 <div v-show="flag" class="box">我是v-show控制的盒子</div> 28 <div v-if="flag" class="box">我是v-if控制的盒子</div> 29 </div> 30 31 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 32 <script> 33 const app = new Vue({ 34 el: '#app', 35 data: { 36 flag: false 37 } 38 }) 39 </script> 40 </body> 41 </html>
③ v-else v-else-if
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>v-else 和 v-else-if</title> 8 </head> 9 <body> 10 11 <div id="app"> 12 <p v-if="gender === 1">性别:♂ 男</p> 13 <p v-else>性别:♀ 女</p> 14 <hr> 15 <p v-if="score >= 90">成绩评定A:奖励电脑一台</p> 16 <p v-else-if="score >= 70">成绩评定B:奖励周末郊游</p> 17 <p v-else-if="score >= 60">成绩评定C:奖励零食礼包</p> 18 <p v-else>成绩评定D:惩罚一周不能玩手机</p> 19 </div> 20 21 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 22 <script> 23 const app = new Vue({ 24 el: '#app', 25 data: { 26 gender: 2, 27 score: 95 28 } 29 }) 30 </script> 31 </body> 32 </html>
④ v-on
内联语句
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>v-on</title> 8 </head> 9 <body> 10 <div id="app"> 11 <button @click="count--">-</button> 12 <span>{{ count }}</span> 13 <button v-on:click="count++">+</button> 14 </div> 15 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 16 <script> 17 const app = new Vue({ 18 el: '#app', 19 data: { 20 count: 100 21 } 22 }) 23 </script> 24 </body> 25 </html>
配合methods中的函数使用
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <div id="app"> 11 <!-- 绑定点击事件,触发fn函数 --> 12 <button @click="fn">切换显示隐藏</button> 13 <h1 v-show="isShow">程序员</h1> 14 </div> 15 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 16 <script> 17 const app4 = new Vue({ 18 el: '#app', 19 data: { 20 isShow: true 21 }, 22 methods: { 23 fn () { 24 // 让提供的所有methods中的函数,this都指向当前实例 25 // console.log('执行了fn', app.isShow) 26 // console.log(app3 === this) 27 this.isShow = !this.isShow 28 } 29 } 30 }) 31 </script> 32 </body> 33 </html>
参数传递
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 .box { 10 border: 3px solid #000000; 11 border-radius: 10px; 12 padding: 20px; 13 margin: 20px; 14 width: 200px; 15 } 16 h3 { 17 margin: 10px 0 20px 0; 18 } 19 p { 20 margin: 20px; 21 } 22 </style> 23 </head> 24 <body> 25 <div id="app"> 26 <div class="box"> 27 <h3>小黑自动售货机</h3> 28 <!-- 传递参数 --> 29 <button @click="buy(5)">可乐5元</button> 30 <button @click="buy(10)">咖啡10元</button> 31 <button @click="buy(8)">牛奶8元</button> 32 </div> 33 <p>银行卡余额:{{ money }}元</p> 34 </div> 35 36 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 37 <script> 38 const app = new Vue({ 39 el: '#app', 40 data: { 41 money: 100 42 }, 43 methods: { 44 // 定义函数接收参数 45 buy (price) { 46 this.money -= price 47 } 48 } 49 }) 50 </script> 51 </body> 52 </html>
⑤ v-bind
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <div id="app"> 11 <!-- 完整写法 --> 12 <img v-bind:src="imgUrl" v-bind:title="msg" alt=""> 13 <!-- 简写方式 --> 14 <img :src="imgUrl" :title="msg" alt=""> 15 </div> 16 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 17 <script> 18 const app = new Vue({ 19 el: '#app', 20 data: { 21 imgUrl: './imgs/10-02.png', 22 msg: 'hello 波仔' 23 } 24 }) 25 </script> 26 </body> 27 </html>
切图案例
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <div id="app"> 11 <button v-show="index > 0" @click="index--">上一页</button> 12 <div> 13 <img :src="list[index]" alt=""> 14 </div> 15 <button v-show="index < list.length - 1" @click="index++">下一页</button> 16 </div> 17 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 18 <script> 19 const app = new Vue({ 20 el: '#app', 21 data: { 22 index: 0, 23 list: [ 24 './imgs/11-00.gif', 25 './imgs/11-01.gif', 26 './imgs/11-02.gif', 27 './imgs/11-03.gif', 28 './imgs/11-04.png', 29 './imgs/11-05.png', 30 ] 31 } 32 }) 33 </script> 34 </body> 35 </html>
⑥ v-for
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 11 <div id="app"> 12 <h3>小黑水果店</h3> 13 <ul> 14 <li v-for="(item, index) in list"> 15 {{ item }} - {{ index }} 16 </li> 17 </ul> 18 19 <ul> 20 <li v-for="item in list"> 21 {{ item }} 22 </li> 23 </ul> 24 </div> 25 26 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 27 <script> 28 const app = new Vue({ 29 el: '#app', 30 data: { 31 list: ['西瓜', '苹果', '鸭梨', '榴莲'] 32 } 33 }) 34 </script> 35 </body> 36 </html>
v-for 中的 key
书架案例
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <div id="app"> 11 <h3>小黑的书架</h3> 12 <ul> 13 <li v-for="(item, index) in booksList" :key="item.id"> 14 <span>{{ item.name }}</span> 15 <span>{{ item.author }}</span> 16 <!-- 注册点击事件 → 通过 id 进行删除数组中的 对应项 --> 17 <button @click="del(item.id)">删除</button> 18 </li> 19 </ul> 20 </div> 21 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 22 <script> 23 const app = new Vue({ 24 el: '#app', 25 data: { 26 booksList: [ 27 { id: 1, name: '《红楼梦》', author: '曹雪芹' }, 28 { id: 2, name: '《西游记》', author: '吴承恩' }, 29 { id: 3, name: '《水浒传》', author: '施耐庵' }, 30 { id: 4, name: '《三国演义》', author: '罗贯中' } 31 ] 32 }, 33 methods: { 34 del (id) { 36 // 通过 id 进行删除数组中的 对应项 → filter(不会改变原数组) 37 // filter: 根据条件,保留满足条件的对应项,得到一个新数组。 38 // console.log(this.booksList.filter(item => item.id !== id)) 39 this.booksList = this.booksList.filter(item => item.id !== id) 40 } 41 } 42 }) 43 </script> 44 </body> 45 </html>
⑦ v-model
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <div id="app"> 11 <!-- 12 v-model 可以让数据和视图,形成双向数据绑定 13 (1) 数据变化,视图自动更新 14 (2) 视图变化,数据自动更新 15 可以快速[获取]或[设置]表单元素的内容 16 --> 17 账户:<input type="text" v-model="username"> <br><br> 18 密码:<input type="password" v-model="password"> <br><br> 19 <button @click="login">登录</button> 20 <button @click="reset">重置</button> 21 </div> 22 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 23 <script> 24 const app = new Vue({ 25 el: '#app', 26 data: { 27 username: '', 28 password: '' 29 }, 30 methods: { 31 login () { 32 console.log(this.username, this.password) 33 }, 34 reset () { 35 this.username = '' 36 this.password = '' 37 } 38 } 39 }) 40 </script> 41 </body> 42 </html>
综合案例-记事本
css/index.js
1 html, 2 body { 3 margin: 0; 4 padding: 0; 5 } 6 body { 7 background: #fff; 8 } 9 button { 10 margin: 0; 11 padding: 0; 12 border: 0; 13 background: none; 14 font-size: 100%; 15 vertical-align: baseline; 16 font-family: inherit; 17 font-weight: inherit; 18 color: inherit; 19 -webkit-appearance: none; 20 appearance: none; 21 -webkit-font-smoothing: antialiased; 22 -moz-osx-font-smoothing: grayscale; 23 } 24 25 body { 26 font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; 27 line-height: 1.4em; 28 background: #f5f5f5; 29 color: #4d4d4d; 30 min-width: 230px; 31 max-width: 550px; 32 margin: 0 auto; 33 -webkit-font-smoothing: antialiased; 34 -moz-osx-font-smoothing: grayscale; 35 font-weight: 300; 36 } 37 38 :focus { 39 outline: 0; 40 } 41 42 .hidden { 43 display: none; 44 } 45 46 #app { 47 background: #fff; 48 margin: 180px 0 40px 0; 49 padding: 15px; 50 position: relative; 51 box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); 52 } 53 #app .header input { 54 border: 2px solid rgba(175, 47, 47, 0.8); 55 border-radius: 10px; 56 } 57 #app .add { 58 position: absolute; 59 right: 15px; 60 top: 15px; 61 height: 68px; 62 width: 140px; 63 text-align: center; 64 background-color: rgba(175, 47, 47, 0.8); 65 color: #fff; 66 cursor: pointer; 67 font-size: 18px; 68 border-radius: 0 10px 10px 0; 69 } 70 71 #app input::-webkit-input-placeholder { 72 font-style: italic; 73 font-weight: 300; 74 color: #e6e6e6; 75 } 76 77 #app input::-moz-placeholder { 78 font-style: italic; 79 font-weight: 300; 80 color: #e6e6e6; 81 } 82 83 #app input::input-placeholder { 84 font-style: italic; 85 font-weight: 300; 86 color: gray; 87 } 88 89 #app h1 { 90 position: absolute; 91 top: -120px; 92 width: 100%; 93 left: 50%; 94 transform: translateX(-50%); 95 font-size: 60px; 96 font-weight: 100; 97 text-align: center; 98 color: rgba(175, 47, 47, 0.8); 99 -webkit-text-rendering: optimizeLegibility; 100 -moz-text-rendering: optimizeLegibility; 101 text-rendering: optimizeLegibility; 102 } 103 104 .new-todo, 105 .edit { 106 position: relative; 107 margin: 0; 108 width: 100%; 109 font-size: 24px; 110 font-family: inherit; 111 font-weight: inherit; 112 line-height: 1.4em; 113 border: 0; 114 color: inherit; 115 padding: 6px; 116 box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); 117 box-sizing: border-box; 118 -webkit-font-smoothing: antialiased; 119 -moz-osx-font-smoothing: grayscale; 120 } 121 122 .new-todo { 123 padding: 16px; 124 border: none; 125 background: rgba(0, 0, 0, 0.003); 126 box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); 127 } 128 129 .main { 130 position: relative; 131 z-index: 2; 132 } 133 134 .todo-list { 135 margin: 0; 136 padding: 0; 137 list-style: none; 138 overflow: hidden; 139 } 140 141 .todo-list li { 142 position: relative; 143 font-size: 24px; 144 height: 60px; 145 box-sizing: border-box; 146 border-bottom: 1px solid #e6e6e6; 147 } 148 149 .todo-list li:last-child { 150 border-bottom: none; 151 } 152 153 .todo-list .view .index { 154 position: absolute; 155 color: gray; 156 left: 10px; 157 top: 20px; 158 font-size: 22px; 159 } 160 161 .todo-list li .toggle { 162 text-align: center; 163 width: 40px; 164 /* auto, since non-WebKit browsers doesn't support input styling */ 165 height: auto; 166 position: absolute; 167 top: 0; 168 bottom: 0; 169 margin: auto 0; 170 border: none; /* Mobile Safari */ 171 -webkit-appearance: none; 172 appearance: none; 173 } 174 175 .todo-list li .toggle { 176 opacity: 0; 177 } 178 179 .todo-list li .toggle + label { 180 /* 181 Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 182 IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ 183 */ 184 background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); 185 background-repeat: no-repeat; 186 background-position: center left; 187 } 188 189 .todo-list li .toggle:checked + label { 190 background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); 191 } 192 193 .todo-list li label { 194 word-break: break-all; 195 padding: 15px 15px 15px 60px; 196 display: block; 197 line-height: 1.2; 198 transition: color 0.4s; 199 } 200 201 .todo-list li.completed label { 202 color: #d9d9d9; 203 text-decoration: line-through; 204 } 205 206 .todo-list li .destroy { 207 display: none; 208 position: absolute; 209 top: 0; 210 right: 10px; 211 bottom: 0; 212 width: 40px; 213 height: 40px; 214 margin: auto 0; 215 font-size: 30px; 216 color: #cc9a9a; 217 margin-bottom: 11px; 218 transition: color 0.2s ease-out; 219 } 220 221 .todo-list li .destroy:hover { 222 color: #af5b5e; 223 } 224 225 .todo-list li .destroy:after { 226 content: '×'; 227 } 228 229 .todo-list li:hover .destroy { 230 display: block; 231 } 232 233 .todo-list li .edit { 234 display: none; 235 } 236 237 .todo-list li.editing:last-child { 238 margin-bottom: -1px; 239 } 240 241 .footer { 242 color: #777; 243 padding: 10px 15px; 244 height: 20px; 245 text-align: center; 246 border-top: 1px solid #e6e6e6; 247 } 248 249 .footer:before { 250 content: ''; 251 position: absolute; 252 right: 0; 253 bottom: 0; 254 left: 0; 255 height: 50px; 256 overflow: hidden; 257 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 258 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 259 0 17px 2px -6px rgba(0, 0, 0, 0.2); 260 } 261 262 .todo-count { 263 float: left; 264 text-align: left; 265 } 266 267 .todo-count strong { 268 font-weight: 300; 269 } 270 271 .filters { 272 margin: 0; 273 padding: 0; 274 list-style: none; 275 position: absolute; 276 right: 0; 277 left: 0; 278 } 279 280 .filters li { 281 display: inline; 282 } 283 284 .filters li a { 285 color: inherit; 286 margin: 3px; 287 padding: 3px 7px; 288 text-decoration: none; 289 border: 1px solid transparent; 290 border-radius: 3px; 291 } 292 293 .filters li a:hover { 294 border-color: rgba(175, 47, 47, 0.1); 295 } 296 297 .filters li a.selected { 298 border-color: rgba(175, 47, 47, 0.2); 299 } 300 301 .clear-completed, 302 html .clear-completed:active { 303 float: right; 304 position: relative; 305 line-height: 20px; 306 text-decoration: none; 307 cursor: pointer; 308 } 309 310 .clear-completed:hover { 311 text-decoration: underline; 312 } 313 314 .info { 315 margin: 50px auto 0; 316 color: #bfbfbf; 317 font-size: 15px; 318 text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); 319 text-align: center; 320 } 321 322 .info p { 323 line-height: 1; 324 } 325 326 .info a { 327 color: inherit; 328 text-decoration: none; 329 font-weight: 400; 330 } 331 332 .info a:hover { 333 text-decoration: underline; 334 } 335 336 /* 337 Hack to remove background from Mobile Safari. 338 Can't use it globally since it destroys checkboxes in Firefox 339 */ 340 @media screen and (-webkit-min-device-pixel-ratio: 0) { 341 .toggle-all, 342 .todo-list li .toggle { 343 background: none; 344 } 345 346 .todo-list li .toggle { 347 height: 40px; 348 } 349 } 350 351 @media (max-width: 430px) { 352 .footer { 353 height: 50px; 354 } 355 356 .filters { 357 bottom: 10px; 358 } 359 }
index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 <link rel="stylesheet" href="./css/index.css" /> 8 <title>记事本</title> 9 </head> 10 <body> 11 12 <!-- 主体区域 --> 13 <section id="app"> 14 <!-- 输入框 --> 15 <header class="header"> 16 <h1>小黑记事本</h1> 17 <input v-model="todoName" placeholder="请输入任务" class="new-todo" /> 18 <button @click="add" class="add">添加任务</button> 19 </header> 20 <!-- 列表区域 --> 21 <section class="main"> 22 <ul class="todo-list"> 23 <li class="todo" v-for="(item, index) in list" :key="item.id"> 24 <div class="view"> 25 <span class="index">{{ index + 1 }}.</span> <label>{{ item.name }}</label> 26 <button @click="del(item.id)" class="destroy"></button> 27 </div> 28 </li> 29 </ul> 30 </section> 31 <!-- 统计和清空 → 如果没有任务了,底部隐藏掉 → v-show --> 32 <footer class="footer" v-show="list.length > 0"> 33 <!-- 统计 --> 34 <span class="todo-count">合 计:<strong> {{ list.length }} </strong></span> 35 <!-- 清空 --> 36 <button @click="clear" class="clear-completed"> 37 清空任务 38 </button> 39 </footer> 40 </section> 41 42 <!-- 底部 --> 43 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 44 <script> 45 // 添加功能 46 // 1. 通过 v-model 绑定 输入框 → 实时获取表单元素的内容 47 // 2. 点击按钮,进行新增,往数组最前面加 unshift 48 const app = new Vue({ 49 el: '#app', 50 data: { 51 todoName: '', 52 list: [ 53 { id: 1, name: '跑步一公里' }, 54 { id: 2, name: '跳绳200个' }, 55 { id: 3, name: '游泳100米' }, 56 ] 57 }, 58 methods: { 59 del (id) { 60 // console.log(id) => filter 保留所有不等于该 id 的项 61 this.list = this.list.filter(item => item.id !== id) 62 }, 63 add () { 64 if (this.todoName.trim() === '') { 65 alert('请输入任务名称') 66 return 67 } 68 this.list.unshift({ 69 id: +new Date(), 70 name: this.todoName 71 }) 72 this.todoName = '' 73 }, 74 clear () { 75 this.list = [] 76 } 77 } 78 }) 79 </script> 80 </body> 81 </html>
⑧ 指令修饰符
按键修饰符
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 </head> 9 <body> 10 <div id="app"> 11 <h3>@keyup.enter → 监听键盘回车事件</h3> 12 <!-- 按键修饰符 @keyup.enter 监听键盘回车,然后触发指定函数 --> 13 <input @keyup.enter="fn" v-model="username" type="text"> 14 </div> 15 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 16 <script> 17 const app = new Vue({ 18 el: '#app', 19 data: { 20 username: '' 21 }, 22 methods: { 23 fn (e) { 24 // if (e.key === 'Enter') { 25 // console.log('键盘回车的时候触发', this.username) 26 // } 27 console.log('键盘回车的时候触发', this.username) 28 } 29 } 30 }) 31 </script> 32 </body> 33 </html>
v-model修饰符
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 .father { 10 width: 200px; 11 height: 200px; 12 background-color: pink; 13 margin-top: 20px; 14 } 15 .son { 16 width: 100px; 17 height: 100px; 18 background-color: skyblue; 19 } 20 </style> 21 </head> 22 <body> 23 <div id="app"> 24 <h3>v-model修饰符 .trim .number</h3> 25 姓名:<input v-model.trim="username" type="text"><br> 26 年纪:<input v-model.number="age" type="text"><br> 27 </div> 28 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 29 <script> 30 const app = new Vue({ 31 el: '#app', 32 data: { 33 username: '', 34 age: '', 35 } 36 }) 37 </script> 38 </body> 39 </html>
事件修饰符
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 .father { 10 width: 200px; 11 height: 200px; 12 background-color: pink; 13 margin-top: 20px; 14 } 15 .son { 16 width: 100px; 17 height: 100px; 18 background-color: skyblue; 19 } 20 </style> 21 </head> 22 <body> 23 <div id="app"> 24 <h3>@事件名.stop → 阻止冒泡</h3> 25 <div @click="fatherFn" class="father"> 26 <div @click.stop="sonFn" class="son">儿子</div> 27 </div> 28 29 <h3>@事件名.prevent → 阻止默认行为</h3> 30 <a @click.prevent href="http://www.baidu.com">阻止默认行为</a> 31 </div> 32 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 33 <script> 34 const app = new Vue({ 35 el: '#app', 36 data: { 37 }, 38 methods: { 39 fatherFn () { 40 alert('老父亲被点击了') 41 }, 42 sonFn (e) { 43 // e.stopPropagation() // 在这里通过事件对象阻止冒泡 44 alert('儿子被点击了') 45 } 46 } 47 }) 48 </script> 49 </body> 50 </html>
⑨ v-bind 对于样式控制的增强
为了方便开发者进行样式控制, Vue 扩展了 v-bind 的语法,可以针对 class 类名 和 style 行内样式 进行控制
操作class
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 .box { 10 width: 200px; 11 height: 200px; 12 border: 3px solid #000; 13 font-size: 30px; 14 margin-top: 10px; 15 } 16 .pink { 17 background-color: pink; 18 } 19 .big { 20 width: 300px; 21 height: 300px; 22 } 23 </style> 24 </head> 25 <body> 26 27 <div id="app"> 28 <div class="box" :class="{ pink: true, big: true }">黑马程序员</div> 29 <div class="box" :class="['pink', 'big']">黑马程序员</div> 30 </div> 31 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 32 <script> 33 const app = new Vue({ 34 el: '#app', 35 data: { 36 37 } 38 }) 39 </script> 40 </body> 41 </html>
tab栏active效果案例
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 * { 10 margin: 0; 11 padding: 0; 12 } 13 ul { 14 display: flex; 15 border-bottom: 2px solid #e01222; 16 padding: 0 10px; 17 } 18 li { 19 width: 100px; 20 height: 50px; 21 line-height: 50px; 22 list-style: none; 23 text-align: center; 24 } 25 li a { 26 display: block; 27 text-decoration: none; 28 font-weight: bold; 29 color: #333333; 30 } 31 li a.active { 32 background-color: #e01222; 33 color: #fff; 34 } 35 36 </style> 37 </head> 38 <body> 39 40 <div id="app"> 41 <ul> 42 <li v-for="(item, index) in list" :key="item.id" @click="activeIndex = index"> 43 <a :class="{ active: index === activeIndex }" href="#">{{ item.name }}</a> 44 </li> 45 </ul> 46 </div> 47 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 48 <script> 49 const app = new Vue({ 50 el: '#app', 51 data: { 52 activeIndex: 2, // 记录高亮 53 list: [ 54 { id: 1, name: '京东秒杀' }, 55 { id: 2, name: '每日特价' }, 56 { id: 3, name: '品类秒杀' } 57 ] 58 } 59 }) 60 </script> 61 </body> 62 </html>
操作style
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 .box { 10 width: 200px; 11 height: 200px; 12 background-color: rgb(187, 150, 156); 13 } 14 </style> 15 </head> 16 <body> 17 <div id="app"> 18 <div class="box" :style="{ width: '400px', height: '400px', backgroundColor: 'green' }"></div> 19 </div> 20 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 21 <script> 22 const app = new Vue({ 23 el: '#app', 24 data: { 25 26 } 27 }) 28 </script> 29 </body> 30 </html>
进度条效果案例
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 .progress { 10 height: 25px; 11 width: 400px; 12 border-radius: 15px; 13 background-color: #272425; 14 border: 3px solid #272425; 15 box-sizing: border-box; 16 margin-bottom: 30px; 17 } 18 .inner { 19 width: 50%; 20 height: 20px; 21 border-radius: 10px; 22 text-align: right; 23 position: relative; 24 background-color: #409eff; 25 background-size: 20px 20px; 26 box-sizing: border-box; 27 transition: all 1s; 28 } 29 .inner span { 30 position: absolute; 31 right: -20px; 32 bottom: -25px; 33 } 34 </style> 35 </head> 36 <body> 37 <div id="app"> 38 <!-- 外层盒子底色 (黑色) --> 39 <div class="progress"> 40 <!-- 内层盒子 - 进度(蓝色) --> 41 <div class="inner" :style="{ width: percent + '%' }"> 42 <span>{{ percent }}%</span> 43 </div> 44 </div> 45 <button @click="percent = 25">设置25%</button> 46 <button @click="percent = 50">设置50%</button> 47 <button @click="percent = 75">设置75%</button> 48 <button @click="percent = 100">设置100%</button> 49 </div> 50 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 51 <script> 52 const app = new Vue({ 53 el: '#app', 54 data: { 55 percent: 30 56 } 57 }) 58 </script> 59 </body> 60 </html>
v-model 应用于其他表单元素
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 textarea { 10 display: block; 11 width: 240px; 12 height: 100px; 13 margin: 10px 0; 14 } 15 </style> 16 </head> 17 <body> 18 <div id="app"> 19 <h3>小黑学习网</h3> 20 姓名: 21 <input type="text" v-model="username"> 22 <br><br> 23 是否单身: 24 <input type="checkbox" v-model="isSingle"> 25 <br><br> 26 <!-- 27 前置理解: 28 1. name: 给单选框加上 name 属性 可以分组 → 同一组互相会互斥 29 2. value: 给单选框加上 value 属性,用于提交给后台的数据 30 结合 Vue 使用 → v-model 31 --> 32 性别: 33 <input v-model="gender" type="radio" name="gender" value="1">男 34 <input v-model="gender" type="radio" name="gender" value="2">女 35 <br><br> 36 <!-- 37 前置理解: 38 1. option 需要设置 value 值,提交给后台 39 2. select 的 value 值,关联了选中的 option 的 value 值 40 结合 Vue 使用 → v-model 41 --> 42 所在城市: 43 <select v-model="cityId"> 44 <option value="101">北京</option> 45 <option value="102">上海</option> 46 <option value="103">成都</option> 47 <option value="104">南京</option> 48 </select> 49 <br><br> 50 自我描述: 51 <textarea v-model="desc"></textarea> 52 <button>立即注册</button> 53 </div> 54 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 55 <script> 56 const app = new Vue({ 57 el: '#app', 58 data: { 59 username: '', 60 isSingle: false, 61 gender: "2", 62 cityId: '102', 63 desc: "" 64 } 65 }) 66 </script> 67 </body> 68 </html>