Vue
Vue是一个前端js框架,由尤雨溪开发,是个人项目
Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,因为它有一个特性是虚拟DOM,从性能上碾轧angularJS,这个时候,vue1.0悄悄的问世了,它的优雅,轻便也吸引了一部分用户,开始收到关注,16年中旬,VUE2.0问世,这个时候vue不管从性能上,还是从成本上都隐隐超过了react,火的一塌糊涂,这个时候,angular开发团队也开发了angular2.0版本,并且更名为angular,吸收了react、vue的优点,加上angular本身的特点,也吸引到很多用户,目前已经迭代到5.0了。
学习vue是现在前端开发者必须的一个技能。
前端js框架到底在干嘛,为什么要用
js框架帮助开发者写js逻辑代码,在开发应用的时候js的功能划分为如下几点:
- 渲染数据
- 操作dom(写一些效果)
- 操作cookie等存储机制api
在前端开发中,如何高效的操作dom、渲染数据是一个前端工程师需要考虑的问题,而且当数据量大,流向较乱的时候,如何正确使用数据,操作数据也是一个问题
而js框架对上述的几个问题都有自己趋于完美的解决方案,开发成本降低。高性能高效率。唯一的缺点就是需要使用一定的成本来学习。
Vue官网介绍
vue是渐进式JavaScript框架
“渐进式框架”和“自底向上增量开发的设计”是Vue开发的两个概念
Vue可以在任意其他类型的项目中使用,使用成本较低,更灵活,主张较弱,在Vue的项目中也可以轻松融汇其他的技术来开发,并且因为Vue的生态系统特别庞大,可以找到基本所有类型的工具在vue项目中使用
特点:易用(使用成本低),灵活(生态系统完善,适用于任何规模的项目),高效(体积小,优化好,性能好)
Vue是一个MVVM的js框架,但是,Vue 的核心库只关注视图层,开发者关注的只是m-v的映射关系
与AngularJS的对比
Vue的很多api、特性都与angularJS相似,其实是因为Vue在开发的时候借鉴了很多AngularJS中的特点,而AngularJS中固有的缺点,在Vue中已经解决,也就是青出于蓝而胜于蓝,Vue的学习成本比AngularJS低很多,因为复杂性就低
AngularJS是强主张的,而Vue更灵活
Vue的数据流是单向的,数据流行更清晰
Angular里指令可以是操作dom的,也可以封装一段结构逻辑代码,例如:广告展示模块
Vue中的指令只是操作dom的,用组件来分离结构逻辑
AngularJS的性能比不上Vue
Vue的使用
Vue不支持IE8,因为使用了ES5的很多特性
可以直接通过script标签来引入vue.js,有开发版本和生产版本,开发版本一般我们在开发项目的时候引入,当最后开发完成上线的时候引入生产版本,开发版本没有压缩的,并且有很多提示,而生产版本全部删掉了
在Vue中提供了一个脚手架(命令行工具)可以帮我们快速的搭建基于webpack的开发环境...
Vue的实例
每一个应用都有一个根实例,在根实例里我们通过组件嵌套来实现大型的应用
也就是说组件不一定是必须的,但是实例是必须要有的
在实例化实例的时候我们可以传入一个;配置项,在配置项中设置很多属性方法可以实现复杂的功能
在配置中可以设置el的属性,el属性代表的是此实例的作用范围
在配置中同过设置data属性来为实例绑定数据
mvc/mvvm
mvc 分为三层,其实M层是数据模型层,它是真正的后端数据在前端js中的一个映射模型,他们的关系是:数据模型层和视图层有映射关系,model改变,view展示也会更改,当view产生用户操作或会反馈给controller,controller更改model,这个时候view又会进行新的数据渲染
这是纯纯的MVC的模式,但是很多框架都会有一些更改
前端mvc框架,如angularjs,backbone:
会发现,用户可以直接操作controller(例如用户更改hash值,conrtoller直接监听hash值变化后执行逻辑代码,然后通知model更改)
控制器可以直接操作view,如果,让某一个标签获得进入页面获得焦点,不需要model来控制,所以一般会直接操作(angularJS,指令)
view可以直接操作model (数据双向绑定)
MVP:
view和model不能直接通信,所有的交互都由presenter来做,其他部分的通信都是双向的
view较薄 ,presenter较为厚重
MVVM:
MVVM和MVP及其相似,只是view和viewmodel的通信是双向绑定,view的操作会自动的像viewmodel通过
v-for
在vue中可以通过v-for来循环数据的通知循环dom,语法是item in/of items,接收第二个参数是索引 (item,index) of items,还可以循环键值对,第一个参数是value,第二个是key,第三个依然是索引
v-on
在vue中还有v-on来为dom绑定事件,在v-on:后面加上要绑定的事件类型,值里可以执行一些简单javascript表达式:++ -- = ...
可以将一些方法设置在methods里,这样就可以在v-on:click的值里直接写方法名字可以,默认会在方法中传入事件对象,当写方法的时候加了()就可以传参,这个时候如果需要事件对象,那就主动传入$event
v-on绑定的事件可以是任意事件,v-on:可以缩写为@
为什么在 HTML 中监听事件?
你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:
- 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
- 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
- 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。
响应式原理
因为vue是mvvm的框架,所以当数据变化的时候,视图会立即更新,视图层产生操作后会自动通知vm来更改model,所以我们可以实现双向数据绑定,而其中的原理就是实例会将设置的data逐个遍历利用Object.defineProperty给数据生成getter和setter,当数据变化地方时候setter会监听到并且通知对应的watcher工具进行逻辑运算会更新视图
声明式渲染
在vue中,我们可以先在vue实例中声明数据,然后通过{{}}等方式渲染在dom中
function foo(){// 第16行
getName = function(){console.log(1)}
return this
}
foo.getName = function(){console.log(2)}
foo.prototype.getName = function(){console.log(3)}
var getName = function(){console.log(4)}
function getName(){console.log(5)}
foo.getName()//2
//foo是一个函数,也可以说是一个对象,所以它也可以挂载一些属性和方法,18行在其上挂载了一个getName方法
//执行的结果是
getName()//4
//21行有一个全局函数,全局函数声明提前后被20行的getName覆盖,所以输出4
foo().getName()//1
//foo()执行完成后,将全局的getName也就是window.getName给更改后返回this,而在这里this执行的就是window,所以最后执行的就是window.getName,所以输出1
getName()//1
//在上面已经更改全局的getName,所以依然是1
new foo.getName()//2
//new 操作符在实例化构造器的时候,会执行构造器函数,也就是说,foo.getName会执行,输出2
new foo().getName()//3
//new操作符的优先级较高,所以会先new foo()得到一个实例,然后再执行实例的getName方法,这个时候,实例的构造器里没有getName方法,就会执行构造器原型上的getName方法
new new foo().getName()//3
//先执行new foo()得到一个实例,然后在new 这个实例的getName方法,这个时候会执行这个方法,所以输出3
//除了本地对象的方法,其他的函数都能new
响应式原理(mvvm)
//ES5中有Object.defineProperty()可以,为某一个对象的属性创建出setter和getter,setter和getter其实是两个工具函数,分别会在数据被更改或者被使用的时候触发
// 准备给data设置一个msg属性,这个属性改变的时候,页面中的显示也会改变
// var data = {msg:‘hello world‘}
// a.innerHTML = data.msg
// inp.oninput = function () {
// data.msg = this.value
// a.innerHTML = data.msg
// }
//M
var data = {msg:‘hello world‘}
//VM
new Bue({
data:data
})
//vm将model的数据显示在view上,当用户参数操作,会自动通知viewmodel(事件的处理程序本身就是写在viewmodel中的),这个时候viewmodel就去更改model,数据更改之后,数据的setter会触发,viewmodel会通知view进行更新
function Bue(options) {
var data = options.data//真正的数据
var _data = {}//专门搞出来的数据
//为搞出来的数据设置getter和setter
let that = this
this.watcher = function (newval) {
document.getElementById("a").innerHTML = newval
}
Object.defineProperty(_data,‘msg‘,{
get:function(){//会设置数据的值,会在使用的时候触发,返回的值是多少,数据就是多少
console.log(‘getter‘)
return data.msg
},
set:function(newval){//数据被更改的时候会触发set,这个时候再通知viewmodel去控制view层改变
that.watcher(newval)
}
})
document.getElementById("a").innerHTML = _data.msg
inp.oninput = function () {
_data.msg = this.value//更改数据
}
}
vue响应式原理:
//将数据挂载在vue的实例上的时候,Vue会对这些数据进行遍历处理,创建watcher,通过监听setter和getter来通知watcher,watcher进行计算后更新view
//数据更改,view更改,view更改,数据更改,这个mvvm里的一个特性(响应式数据绑定),体现它的效果是数据双向绑定
//这个特性在vue是通过对数据进行Object.defineProperty处理来实现的,实现的原理vue起了个名字叫响应式原理