前端【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>

 

posted @ 2024-04-07 15:21  为你编程  阅读(42)  评论(0编辑  收藏  举报