基本使用
使用Vue的步骤
- 需要提供标签用于填充数据
 - 引入VUE.js文件
 - 可以使用vue的语法做功能
 - 把vue提供的数据填充到标签里
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | <body>     <div id="app">                  <h1>{{title}}</h1>     </div>     <script src="../js/vue.js"></script>     <script>         new Vue({                          el: '#app',                          data: {                 title: 'xiaokang'             }         })     </script> </body>
   | 

 指令
 v-cloak
https://cn.vuejs.org/v2/api/#v-cloak
作用:用于解决当vue没有渲染时显示两个大括号等问题。
指令用法:
提供样式
1 2 3 4 5
   | <style>     [v-cloak] {         display: none;     } </style>
   | 
在插值表达式所在的标签中添加v-cloak指令
1
   | <h1 v-cloak>{{title}}</h1>
  | 
 数据绑定
将数据填充到标签中。
v-text
此指令没有闪动问题,插入内容为纯文本内容
v-html
填充HTML片段,存在安全问题。
v-pre
显示原始信息,跳过编译过程
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
   | <!DOCTYPE html> <html lang="en">
  <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>Document</title> </head>
  <body>     <div id="app">                  <h1>{{title}}</h1>         <div v-text='text'></div>         <div v-html='html'></div>         <div v-pre='pre'>{{pre}}</div>     </div>     <script src="../js/vue.js"></script>     <script>         new Vue({                          el: '#app',                          data: {                 title: 'xiaokang',                 text: 'v-text 纯文本内容',                 html: '<h1>v-html 填充html</h1>',                 pre: 'v-pre显示原始信息,跳过编译过程'             }         })     </script> </body>
  </html>
   | 

 数据响应式
v-once指令可以使数据只渲染一次,即数据不再是响应式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | <body>     <div id="app">                  <h1>{{title}}</h1>         <h1 v-once>{{msg}}</h1>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',                          data: {                 title: 'xiaokang',                 msg: 'once只渲染一次',             }         })     </script> </body>
   | 

 双向数据绑定
双向数据绑定使用v-model命令。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | <body>     <div id="app">                  <p>{{msg}}</p>         <input type="text" v-model='msg'>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',                          data: {                 msg: 'once只渲染一次',             }         })     </script> </body>
   | 
原理:通过v-bind绑定属性,v-on:input绑定输入事件,以此改变属性的值。
 事件绑定
https://cn.vuejs.org/v2/guide/events.html
事件绑定通过v-on指令,v-on指令可以简写为@,例如:
1
   | <button @click='num++'>点击</button>
   | 

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
   | <body>     <div id="app">         <div>{{num}}</div>         <button v-on:click='add()'>加1</button>         <button v-on:click='min()'>减1</button>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',                          data: {                 num: 0,             },                          methods: {                 add() {                     this.num++                 },                 min() {                     this.num--                 }             },         })     </script> </body>
   | 
 参数传递
直接调用函数,不传递参数
1
   | <button v-on:click="fn">test</button>
   | 
此种情况在methods中接受的第一个参数为事件对象。
1 2 3 4 5
   | methods: {     fn(e) {         console.log(e);     } },
  | 

传递参数
1
   | <button v-on:click="fn(1,2,3,$event)">按钮 - {{title}}</button>
  | 
此时无论传递多少个参数,传递事件对象时必须使用$event名称且只能放在最后一个位置。
1 2 3 4 5 6 7 8
   | methods: {     fn(a, b, c, d) {         console.log("a: ", a);         console.log("b: ", b);         console.log("c: ", c);         console.log("d: ", d);     } }
  | 

 事件修饰符
.stop
阻止事件继续传播
.prevent
阻止默认事件
.capture
是否是以捕获模式
.self
是否是自己触发的
.once
只触发一次
.passive
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   |  <a v-on:click.stop="doThis"></a>
 
  <form v-on:submit.prevent="onSubmit"></form>
 
  <a v-on:click.stop.prevent="doThat"></a>
 
  <form v-on:submit.prevent></form>
 
 
  <div v-on:click.capture="doThis">...</div>
 
 
  <div v-on:click.self="doThat">...</div>
 
  | 
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | <body>     <div id="app">         <a href="https://xiaokang.me" target="_blank" @click.prevent='fn'>小康</a>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',                          methods: {                 fn() {                     console.log('点击a标签了。');                 }             },         })     </script> </body>
   | 
 按键修饰符
按键修饰符

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
   | <body>     <div id="app">         <input type="text" v-model='username' @keyup.delete='fn'>         <input type="text" v-model='password' @keyup.enter='fn2'>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 username: '',                 password: ''             },                          methods: {                 fn() {                     console.log('按下了delete键');                     this.username = ''                 },                 fn2() {                     console.log('按下了回车键');                 }             },         })     </script> </body>
   | 
虽然VUE提供了自定义按键修饰符的方法,但此方法已经被废弃。keyCode
 案例:简单计算器

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
   | <body>     <div id="app">         数值A: <input type="text" v-model='a'><br>         数值B: <input type="text" v-model='b'><br>         <button @click='fn'>计算</button>         <p>计算结果:{{result}}</p>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 a: '',                 b: '',                 result: ''             },                          methods: {                 fn() {                     this.result = parseInt(this.a) + parseInt(this.b)                 }             },         })     </script> </body>
   | 
 属性绑定
属性绑定通过v-bind实现,这个属性也可以存在两种写法:全写与简写
1 2
   | <a v-bind:href="href">{{href}}</a> <a :href="href">{{href}}</a>
  | 
例如:通过数据动态控制a标签中href属性的值。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | <body>     <div id="app">         <a v-bind:href="href">{{href}}</a>         <button @click='fn'>切换</button>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 href: 'https://xiaokang.me'             },                          methods: {                 fn() {                     this.href = 'https://www.antmoe.com'                 }             },         })     </script> </body>
   | 
 样式绑定
1 2 3
   |  <div :class='{active:isActive}'></div> <div :class='[activeClass,errorClass]'></div>
 
  | 
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
   | <head>     <style>         .active {             border: 1px solid red;             width: 100px;             height: 100px;         }     </style> </head>
  <body>     <div id="app">                  <div :class='{active:isActive}'></div>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 isActive: true             },         })     </script> </body>
   | 

通过isActive属性控制类是否生效
通过数组方式添加类名:
1
   | <div :class='[activeClass,errorClass]'></div>
   | 
1 2 3 4 5 6 7 8 9 10
   | <script>     let app = new Vue({                  el: '#app',         data: {             activeClass: 'active',             errorClass: 'error'         },     }) </script>
   | 
在数组中同样可以添加对象,即两者结合使用
1
   | <div :class='[activeClass,errorClass,{test:"isTest"}]'></div>
  | 
或者也可以通过如下方式:
1
   | <div :class='myClass'></div>
   | 
1 2 3 4 5 6 7 8 9
   | <script>     let app = new Vue({                  el: '#app',         data: {             myClass:['activeClass','errorClass',{test:"isTest"}]         },     }) </script>
   | 
关于样式绑定,如果元素存在默认的class,那么默认class会被保留
通过style绑定样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | <body>     <div id="app">         <div :style='{border:boderStyle,height:heightStyle,width:widthStyle}'></div>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 boderStyle: '1px solid red',                 heightStyle: '100px',                 widthStyle: '100px'             },         })     </script> </body>
   | 
关于样式也可以通过对象的方式
1
   | <div :style='objStyle'></div>
   | 
1 2 3 4 5 6 7 8 9 10 11
   | let app = new Vue({          el: '#app',     data: {         objStyle: {             border: '1px solid red',             height: '100px',             width: '100px',         }     }, })
  | 
直接操作值就会改变样式。
 分支循环
1 2 3
   | <div v-if='score>=90'>优秀</div> <div v-else-if='score<90&&score>=80'>良好</div> <div v-else='score<90&&score>=80'>垃圾</div>
   | 

此指令只会渲染一个div,然而v-show会渲染多个div,即控制display来决定是否显示。
1
   | <div v-show='flag'>测试</div>
   | 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | <body>     <div id="app">         <div v-if='score>=90'>优秀</div>         <div v-else-if='score<90&&score>=80'>良好</div>         <div v-else='score<90&&score>=80'>垃圾</div>         <div v-show='flag'>测试</div>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 score: 99,                 flag: false             },
          })     </script> </body>
   | 
 循环结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | <body>     <div id="app">         <ul>             <li v-for='(item,index) of fruits'>{{index}}---{{item}}</li>         </ul>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 fruits: ['apple', 'orange', 'banana']             },
          })     </script> </body>
   | 

为了保证没一条记录的唯一性,最好通过唯一值为每一个元素绑定key属性。
 分支与循环结合使用
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
   | <body>     <div id="app">         <ul>             <li v-if='flag' v-for='item of obj'>                 {{item.id}}---{{item.name}}---{{item.age}}             </li>         </ul>     </div>     <script src="../js/vue.js"></script>     <script>         let app = new Vue({                          el: '#app',             data: {                 obj: [                     {                         id: 1,                         name: 'a',                         age: 12                     },                     {                         id: 2,                         name: 'b',                         age: 13                     },                     {                         id: 3,                         name: 'c',                         age: 14                     },                 ],                 flag: false             },
          })     </script> </body>
   | 

 案例: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
   | <!DOCTYPE html> <html lang="en">
  <head>     <meta charset="UTF-8">     <title>Document</title>     <style type="text/css">         .tab ul {             overflow: hidden;             padding: 0;             margin: 0;         }
          .tab ul li {             box-sizing: border-box;             padding: 0;             float: left;             width: 100px;             height: 45px;             line-height: 45px;             list-style: none;             text-align: center;             border-top: 1px solid blue;             border-right: 1px solid blue;             cursor         }
          .tab ul li:first-child {             border-left: 1px solid blue;         }
          .tab ul li.active {             background-color: orange;         }
          .tab div {             width: 500px;             height: 300px;             display: none;             text-align: center;             font-size: 30px;             line-height: 300px;             border: 1px solid blue;             border-top: 0px;         }
          .tab div.current {             display: block;         }     </style> </head>
  <body>     <div id="app">         <div class="tab">             <ul>                 <li v-on:click='change(index)' :class='currentIndex==index?"active":""' :key='item.id'                     v-for='(item,index) in list'>{{item.title}}</li>             </ul>             <div :class='currentIndex==index?"current":""' :key='item.id' v-for='(item, index) in list'>                 <img :src="item.path">             </div>         </div>     </div>     <script type="text/javascript" src="../js/vue.js"></script>     <script type="text/javascript">         /*                    */         var vm = new Vue({             el: '#app',             data: {                 currentIndex: 0,                  list: [{                     id: 1,                     title: '第一个',                     path: 'https://cdn.jsdelivr.net/gh/blogimg/picbed@master/2020/04/13/5005109d1aa2ffd28984c2b02b8cbfbe.png'                 }, {                     id: 2,                     title: '第二个',                     path: 'https://cdn.jsdelivr.net/gh/blogimg/picbed@master/2020/04/13/163a2ade4361d1ed705ed523091af67e.png'                 }, {                     id: 3,                     title: '第三个',                     path: 'https://cdn.jsdelivr.net/gh/blogimg/picbed@master/2020/04/13/d8ccc2fd66f340c46b8fb98ed7148223.png'                 }]             },             methods: {                 change: function (index) {                                                               this.currentIndex = index;                 }             }         });     </script> </body>
  </html>
   | 

 案例:TODO
DEMO:https://tzk.acs.pw/2020-11/01/Stable/todos.html