Vue
1.第一个Vue程序
1.简介
Vue是一套用于构建用户界面的渐进式架构,发布于2014年2月。与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用。
Vue的核心只关注视图层,不仅易于上手,还便于与第三方库(如:vue-router,vue-resource,vuex)或既有项目整合。
2.MVVM模式的实现者
- Model:模型层,在这里表示JavaScript对象
- View:视图层,在这里表示DOM(HTML操作的元素)
- ViewModel:连接视图和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者
在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者
- ViewModel能够观察到数据的变化,并对视图对应的内容进行更新
- ViewModel能够监听到视图的变化,并能够通知数据发生变化
至此我们明白了, Vue.js就是一个MVVM的实现者,他的核心就是实现了DOM监听与数据绑定
3.为什么要使用Vue.js
- 轻量级,体积小是一个重要指标。Vue.js压缩后只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
- 移动优先。更适合移动端,比如移动端的Touch事件
- 易上手,学习曲线平稳,文档齐全
- 吸取了Angular(模块化)和React(虚拟DOM)的长处,并拥有自己独特的功能,并拥有自己独特的功能,如:计算属性
- 开源,社区活跃度高
- ......
4.第一个Vue程序准备
注意:Vue不支持IE8及以下,因为Vue使用了IE8无法模拟的ECMAScript5特性。但它支持所有兼容ECMAScript5的浏览器
开发版本
- 完整的警告和调试模式:https://vuejs.org/js/vue.js
- 删除警告,30.96KB min+gzip:https://vuejs.org/js/vue.min.js
CDN
-
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
-
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
5.Hello Vue
vue.js的核心是实现了MVVM模式,它扮演的角色就是ViewModel层,第一个应用程序就是展示它的数据绑定功能
创建一个HTML文件 hello.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 </body> 10 </html>
引入Vue.js
1 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
创建一个Vue实例
代码:hello01.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>dz学vue</title> 6 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> 7 8 </script> 9 </head> 10 <body> 11 <div id="vue"> 12 {{message}} 13 </div> 14 <script type="text/javascript"> 15 var vm = new Vue({ 16 el: '#vue', 17 data: {message: 'Hello Vue!' 18 } 19 }); 20 </script> 21 </body> 22 23 </html>
2.基础语法
基础语法,就是实现元素赋值,循环,判断以及事件响应即可。
1.v-bind
使用v-bind来绑定元素特性
代码:v-bind.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>dz学vue</title> 6 </head> 7 <body> 8 <div id="app"> 9 <h1 v-bind:title="message">鼠标悬停几秒</h1> 10 <h1 :title="message">我是标题</h1> <!-- v-bind指令的简写形式--> 11 </div> 12 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> 13 </script> 14 <script> 15 new Vue({ 16 el: '#app', 17 data: { 18 message: '页面加载于' + new Date().toLocaleString() 19 } 20 }) 21 </script> 22 </body> 23 24 </html>
v-bind特性被称为指令,指令带有前缀v-,表示他们是Vue提供的特殊属性
除了使用插值表达式{{}}进行数据渲染,也可以使用v-bind指令,它的简写形式就是一个冒号(:)
2.v-if系列
条件判断语句
- v-if
- v-else-if
- v-else
代码:v-if.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>dz学vue</title> 6 </head> 7 <body> 8 <div id="app"> 9 <h1 v-if="type === 'A'">A</h1> 10 <h1 v-else-if="type === 'B'">B</h1> 11 <h1 v-else-if="type === 'C'">C</h1> 12 <h1 v-else>who</h1> 13 </div> 14 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> 15 </script> 16 <script> 17 new Vue({ 18 el: '#app', 19 data: { 20 type: 'B' 21 } 22 }) 23 </script> 24 </body> 25 26 </html>
3.v-for
语法格式:
1 <div id="app"> 2 <li v-for="item in items"> 3 {{item.message}} 4 </li> 5 </div>
items是数组,item是数组元素迭代的别名。和Thymeleaf模板引擎的语法十分相似。
代码:v-for.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 5 </head> 6 <body> 7 <div id="app"> 8 <li v-for="item in items"> 9 {{item.message}} 10 </li> 11 </div> 12 <script> 13 var vm = new Vue({ 14 el:'#app', 15 data:{ 16 items:[ 17 {message:'dz学vue1'}, 18 {message: 'dz学vue2'} 19 ] 20 } 21 }) 22 </script> 23 </body> 24 </html>
测试:在控制台输入vm.items.push({message:'dz学vue3'}),尝试追加一条数据,浏览器中会增加一条内容
4.v-on
v-on监听事件:
事件有Vue的事件和前端页面本身的一些事件,click是vue的事件,可以绑定到vue中的methods中的方法事件
代码:v-on.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>dz学vue</title> 6 </head> 7 <body> 8 <div id="app"> 9 <button v-on:click="sayHi">点我</button> 10 <!-- v-on指令的简写形式@--> 11 <button @click="sayHi">点我</button> 12 </div> 13 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> 14 </script> 15 <script> 16 var vm = new Vue({ 17 el: '#app', 18 data: { 19 message:'Hello World' 20 }, 21 //方法必须定义在Vue实例的methods对象中 22 methods:{ 23 sayHi:function (event) { 24 //this在方法里指向当前vue实例 25 alert(this.message); 26 } 27 } 28 }) 29 </script> 30 </body> 31 32 </html>
5.v-model
双向数据绑定
Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化,这算是Vue,js的精髓之处了。
值得注意的是,我们所说的数据双向绑定,一定是对与UI控件来说的,非UI空间不会涉及到数据双向绑定,对于我们处理表单,Vue.js的双向数据绑定用起来就特别舒服了。
可以用v-model指令在表单<input>、<textarea>、<select>元元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
v-model本质上是语法糖,负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
代码:v-bind-1.html
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <!-- v-bind:value只能进行单向的数据渲染--> 10 <input type="text" v-bind:value="searchMap.keyword"> 11 <!-- v-model可以进行双向的数据绑定--> 12 <input type="text" v-model="searchMap.keyword"> 13 <p>查询的数据是:{{searchMap.keyword}}</p> 14 </div> 15 <script> 16 var vm = new Vue({ 17 el:'#app', 18 data:{ 19 searchMap:{ 20 keyword:'dz' 21 } 22 } 23 }) 24 </script> 25 </body> 26 </html>
两个输入框的对比,效果展示:
v-bind绑定的输入框,修改之后,只有本身的值会被修改
v-model绑定的数据框,修改之后,视图中所有对应的值都会被修改
代码:v-bind-2.html 单复选框
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <input type="checkbox" id="checkbox" v-model="checked"> 10 11 <label for="checkbox">{{checked}}</label> 12 </div> 13 <script> 14 var vm = new Vue({ 15 el:'#app', 16 data:{ 17 checked:false 18 } 19 }) 20 </script> 21 </body> 22 </html>
代码:v-bind-3 多复选框
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> 10 <label for="jack">Jack</label> 11 <input type="checkbox" id="jokn" value="Jokn" v-model="checkedNames"> 12 <label for="jokn">Jokn</label> 13 <input type="checkbox" id="dz" value="Dz" v-model="checkedNames"> 14 <label for="dz">Dz</label> 15 <span>选中的值:{{checkedNames}}</span> 16 </div> 17 <script> 18 var vm = new Vue({ 19 el:'#app', 20 data:{ 21 checkedNames:[] 22 } 23 }) 24 </script> 25 </body> 26 </html>
type中的id对应label中的for值
代码:v-bind-4.html 单选按钮
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <input type="radio" id="jack" value="Jack" v-model="pick"> 10 <label for="jack">Jack</label> 11 <input type="radio" id="jokn" value="Jokn" v-model="pick"> 12 <label for="jokn">Jokn</label> 13 <input type="radio" id="dz" value="Dz" v-model="pick"> 14 <label for="dz">Dz</label> 15 <span>选中的值:{{pick}}</span> 16 </div> 17 <script> 18 var vm = new Vue({ 19 el:'#app', 20 data:{ 21 pick:'' 22 } 23 }) 24 </script> 25 </body> 26 </html>
代码:v-bind-5.html
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <select v-model="selected"> 10 <option disabled value="">请选择</option> 11 <option>A</option> 12 <option>B</option> 13 <option>C</option> 14 </select> 15 <span>选中的值:{{selected}}</span> 16 </div> 17 <script> 18 var vm = new Vue({ 19 el:'#app', 20 data:{ 21 selected:'' 22 } 23 }) 24 </script> 25 </body> 26 </html>
注意:v-model表达式的初始值未能比配任何选项,<select>元素将被渲染为“未选中”状态。
第一个选项是无法被选择的,不会触发change事件,最好提供一个值为空的禁用选项
3.组件
什么是组件
组件是可复用的Vue实例,说白了就是一组可以重复使用的模板,跟JSTL的自定义标签、Thymeleaf的th:fragment等框架有着异曲同工之妙。
通常一个应用会以一棵嵌套的组件数的形式来组织:
例如:一个网页会有页头,侧边栏,内容区等组件,每个组件又包含了其他的像导航链接,博文之类的组件
第一个Vue组件
实际开发中,不会使用下面方式开发组件。
Vue.component()方法注册组件
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <ul> 10 <my-component-li></my-component-li> 11 </ul> 12 </div> 13 <script> 14 Vue.component('my-component-li',{ 15 template:'<li>Hello li</li>' 16 }); 17 var vm = new Vue({ 18 el:'#app', 19 }); 20 </script> 21 </body> 22 </html>
说明:
- Vue.component():注册组件
- my-component-li:自定义组件的名字
- template:组件的模板
使用props属性传递参数
我们需要传递参数到组件,此时就需要使用props属性
注意:默认规则下props属性里的值不能为大写
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <ul> 10 <my-component-li v-for="item in items" v-bind:item="item"></my-component-li> 11 </ul> 12 </div> 13 <script> 14 Vue.component('my-component-li',{ #####先注册组件##### 15 props:['item'], 16 template:'<li>Hello {{item}}</li>' 17 }); 18 var vm = new Vue({ ####再实例化Vue#### 19 el:'#app', 20 data:{ 21 items:["dz","dz1","dz2"] 22 } 23 }); 24 </script> 25 </body> 26 </html>
说明:
- v-for="item for items":遍历Vue实例中定义的名为items的数组,并创建同等数量的组件
- v-bind:item="item":将遍历的item项绑定到组件中props定义的名为item属性上
- v-bind:item="item" =号左边的item为props定义的属性名,右边的为item in items中遍历的item项的值
4.计算属性
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性,其次这个属性有计算的能力(计算是动词),这里的计算就是个函数
简单点说:它是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性)。可以想象为缓存。
代码:vue-computed.html
1 <!DOCTYPE html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 3 <html> 4 <head> 5 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"> </script> 6 </head> 7 <body> 8 <div id="app"> 9 <!-- 一个是方法,一个是属性--> 10 <p>调用当前时间的方法:{{currentTime1()}}</p> 11 <p>当前时间的计算属性:{{currentTime2}}</p> 12 </div> 13 <script> 14 var vm = new Vue({ 15 el:'#app', 16 data:{ 17 message:'Hello Vue' 18 }, 19 methods: { 20 currentTime1:function () { 21 return Date.now(); 22 } 23 }, 24 computed:{ 25 currentTime2:function () { 26 this.message; 27 return Date.now(); 28 } 29 } 30 }) 31 </script> 32 </body> 33 </html>
注意:methods和computed里的东西不能重名
说明:
- methods:定义方法,调用方法使用currentTime1(),需要带括号
- computed:定义计算属性,调用属性使用currentTime2,不需要带括号,this.message是为了能够让currentTime2观察到数据变化
- 如果在方法中的值发生了变化,则缓存就会刷新,在控制台使用vm.message="dz"改变数据的值,测试观察效果。
结论:
调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?
此时就可以考虑将这个结果缓存起来,采用计算属性可以方便的做到这个
计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销
5.插槽
在Vue中我们使用<slot>元素,作为承载分发内容的出口,作者称之为插槽,可以应用在组合组件的场景中
比如准备制作一个待办事项组件(todo),该组件由待办标题(todo-title),待办内容(todo-items)组成,但这三个组件又是互相独立的,该如何操作
待补充....