简述
Vue是一个强大的javascript框架,它可以简化dom操作,大大提高开发效率,并且支持响应式数据驱动
Vue作者是尤雨溪,中国人,所以官方文档非常nice : https://cn.vuejs.org/
Vue采用组件化模式,提高了代码的复用率,一个页面会分为很多部分,每一个部分就是一个组件,对应一个.vue文件
Vue使用声明式编码,我们不用像原生JS一样直接操作DOM进行编码,提高了开发效率
第一个vue程序
引入vue框架
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
写点html和js
<div id="app"> {{ message }} </div> <script> var app = new Vue({ el:"#app", data:{ message:" hello vue! " } }) </script>
上面的代码干了什么事情呢——把data里的数据渲染到div里
这样我们第一个vue程序就能跑起来了,可以看到我们有几个地方是不懂的:双大括号、el、data
el属性
el就是设置挂载点,el的值是一个选择器
vue实例的范围就是el命中选择器内部及其子孙标签,一般使用的是id选择器
注意有个特例不能挂载到html和body标签上
除了在vue实例里进行el挂载,我们还有一种方式
<div id="root"> {{ message }} </div> <script> const x = new Vue({ data:{ message: "你好" } }) x.$mount('#root') </script>
我们可以使用vue实例对象的$mount方法,里面可以指定一个选择器进行挂载
data属性
上面的入门程序data里面渲染的是字符串类型,data其实还支持复杂类型的数据,渲染复杂类型的遵守js的语法即可
例如下面代码绑定了对象、数组
<!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, initial-scale=1.0"> <title>Vue基础</title> </head> <body> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <div id="app"> {{ message }} <h2> {{ man.name }} {{ man.age }}</h2> <ul> <li>{{ myFriend[0] }}</li> <li>{{ myFriend[1] }}</li> <li>{{ myFriend[2] }}</li> </ul> </div> <script> var app = new Vue({ el:"#app", data:{ message:" hello vue! ", man:{ name:"黄小鱼", age:12 }, myFriend:['黄小鱼','郭男','江硬锋'] } }) </script> </body> </html>
vue指令
以往我们通过dom的api获取dom元素进行js操作,有了vue之后则更为方便,我们使用的是一系列以v开头的标签,统称为vue指令
v-text
v-text用于设置标签的文本值,我们可以直接在标签中添加v-text的属性
<div id="app" v-text="message"></div>
这样该标签的文本就会替换为data绑定的数据,直接添加到标签里会替换掉所有内容
我们还可以像上面入门案例里的一样使用双大括号,那么文本替换就只会替换大括号里的,这种写法也叫做插值表达式
同时这个指令本质上可以看到vue实例对象的所有属性,以及vue原型上的所有属性和方法都可以访问
v-html
v-html和v-text指令类似,用于绑定文本数据,只不过的是如果数据是html的结构,那么vue就会将结构进行解析,例如:
<div id="app" v-html="message"></div> <script> var app = new Vue({ el:"#app", data:{ message:"<a href='#'>123</a>", } }) </script>
message数据里的a标签就会进行解析
v-on
v-on指令用于事件绑定,在标签内部使用 v-on:事件名="函数名" 的形式绑定触发函数
<div id="app"> <input type="button" value="test" v-on:click="test"> </div> <script> var app = new Vue({ el:"#app", data:{ message:"<a href='#'>123</a>", }, methods:{ test:function(){ alert("test"); } } }) </script>
v-on:可以简写成@,来提高开发效率
在事件名后可以使用事件修饰符来产生一定的效果,vue中一共有6个事件修饰符,例如
<div id="app"> <input type="button" value="test" @click.prevent="test"> </div>
prevent | 阻止默认事件 |
stop | 阻止事件冒泡 |
once | 事件只触发一次 |
capture | 使用事件的捕获模式 |
self | 只有event.target是当前操作的元素是触发事件 |
passive | 事件的默认行为立即执行,无需等待事件回调执行完毕 |
对于键盘事件,vue对常用的按键起了别名
回车 | enter |
删除 | delete |
退出 | esc |
空格 | space |
换行 | tab |
上 | up |
下 | down |
左 | left |
右 | right |
v-show
v-show指令可以根据表达式的真假切换元素的显示和隐藏,属性值可以为data里的数据,也可以是表达式
v-if
根据表达式值的真假,切换dom元素的隐藏和显示,和v-show不同的是,v-if操作的是dom元素
v-bind
v-bind指令用于设置元素的属性,例如:src、title、class
<div id="app"> <img v-bind:src="imgSrc"> </div> <script> var app = new Vue({ el:"#app", data:{ imgSrc:"图片地址" } }) </script>
上面的imgSrc即为v-bind指令绑定的属性,同样的我们还可以使用表达式,{active:isActive}表示isActive的值为真则生效
<div id="app"> <img v-bind:class="{active:isActive}"> </div> <script> var app = new Vue({ el:"#app", data:{ isActive:false } }) </script>
注意v-bind可以省略,直接写成 :属性 也可以生效
v-for
v-for用于响应式地根据数据生成列表结构,我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<ul id="example-1"> <li v-for="item in items" :key="item.message"> {{ item.message }} </li> </ul> <script> var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
在 v-for
块中,我们可以访问所有父作用域的 property。v-for
还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul> <script> var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
v-model
v-model用于获取和设置表单元素的值(双向数据绑定),双向数据绑定的双向,是input标签的值和data里的值进行双向绑定,任意一方的值进行更改会改变另一方的值
MVVM模型
vue的开发参考了MVVM模型,官网文档中vue的实例也用vm表示,英文是ViewModel的缩写
M:模型、Model,对应vue中data中的数据
V:视图、View,模板,可以理解为vue的模板
VM:视图模型、ViewModel,代表vue的实例对象
上图其实就是在说Model的数据通过vue进行绑定,通过vue进行数据的改变并渲染,同时vue可以监听页面的dom,实时改变Model的数据
Object.defineproperty方法
vue很多地方都用到了这个方法,这个方法是用来为对象添加属性用的
格式:
Object.defineProperties(对象名,属性,配置项)
其中对象名就是你要向哪个对象添加属性,属性就是你要添加的属性名,配置项就是添加时候的配置
最常见的配置就是value,就是这个添加的属性的值
使用该方法默认添加的属性是不能被枚举的,需要被枚举需要添加配置项:enumerable:true
使用该方法默认添加的属性是不能被修改的,需要被修改需要添加配置项:writable:true
使用该方法默认添加的属性是不能被删除的,需要被删除需要添加配置项:configurable:true
除了这四个基本的配置项,还有很多高级的配置项
数据代理
数据代理就是通过一个对象代理对另一个对象中属性的操作,vue中的数据代理其实就是通过vm对象来代理data对象中的属性操作
因为data对象本质上是存在了vm对象的_data属性里,如果没有数据代理,我们在插值表达式里就要写_data.xxx来访问data里的属性,而通过数据代理data里的属性已经被添加到了vm对象里,所以可以直接调用,这个添加的过程就是通过Object.defineproperty实现的
计算属性
data里的键值对在vue来说就是属性,计算属性就是根据现有的属性进行加工,计算出新的属性
我们使用computed关键字在vue实例里使用计算属性,计算出来的值要以类的形式在computed类中,里面提供get方法,用于vue获取这个被计算出来的属性,并且vue已经帮我们处理好了这个get方法里面的this指针,this指针就是vm实例了,例如:
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <div id="root"> {{fullName}} </div> <script> const vm = new Vue({ el: '#root', data:{ firstName:'张', lastName:'三' }, computed:{ fullName:{ get(){ return this.firstName + this.lastName; } } } }) </script>
同时计算出来后,当有人调用就会把计算出来的属性存入缓存,当二次调用的时候会直接从缓存里读
当所依赖的数据发生改变的时候,会更新缓存,保存计算出来的属性总是最新的
同时我们可以配置set方法,用于计算属性被修改的时候调用,当计算属性被修改的时候,我们可以修改所依赖的属性的值
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <div id="root"> {{fullName}} </div> <script> const vm = new Vue({ el: '#root', data:{ firstName:'张', lastName:'三' }, computed:{ fullName:{ get(){ return this.firstName + this.lastName; }, set(value){ const arr = value.spilt('-'); this.firstName = arr[0] this.lastName = arr[1] } } } }) </script>
一般来说计算属性不涉及修改,所以可以用简写形式,即直接在computed类里写方法,方法名就是计算属性的名,同时里面的方法体是计算属性的get,例如:
computed:{ fullName(){ return this.firstName + this.lastName; } }
监视属性
监视属性就是监视某一属性的变化,在vue实例中使用watch配置监视属性,里面是你要监视的属性的类,类里是配置项,例如hander函数,当该属性发生改变时会执行hander函数,immediate:true,一开始就执行
watch:{ isHot:{ handler(newValue,oldValue){ console.log('isHot 属性被改变了'); }, immediate:true } }
需要注意的是计算属性也能被监视
当需要监视多级结构中某个属性的变化时,就不能使用xxx.xxx的形式,因为那是key的简写形式,同时当你想监视整个属性(里面含有子属性)的时候,子属性的变化不会被监视到,需要添加deep配置项
computed能完成的功能,watch一定能完成,watch能完成的功能,computed不一定能完成,例如watch可以进行异步操作
原生axious
引入axious,引用只后会生成一个全局的axious对象
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
get请求格式,查询字符串就是以key=value方式以&分隔的查询参数
axios.get("地址?查询字符串").then(function(response){},function(err){})
post请求和get请求类似,不同之处是在参数是以对象的形式进行传递
axios.post("地址",{key1:value1,key2:value2}).then(function(response){},function(err){})
axious+vue作用域问题
我们可以将axious获得的respone数据与dom元素进行绑定,从而获取完成就渲染到页面上
在vue实例定义的触发函数中,this指针可以直接获得data里的数据
但在axious函数的response回调函数里,this获取到的就是response对象了
所以在axious操作前我们一般都会把this指针指向的对象存起来