Vue 浅谈前端js框架vue

Vue

Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,由于它有一个特性是虚拟DOM,从性能上碾轧angularJS,这个时候,vue1.0悄悄javascript

的问世了,它的优雅,轻便也吸引了一部分用户,开始收到关注,16年中旬,VUE2.0问世,这个时候vue无论从性能上,仍是从成本上都隐隐超过了react,火的一塌糊涂,这个时候,angularcss

开发团队也开发了angular2.0版本,而且改名为angular,吸取了react、vue的优势,加上angular自己的特色,也吸引到不少用户,目前已经迭代到5.0了。html

学习vue是如今前端开发者必须的一个技能。前端

前端js框架到底在干吗,为何要用

js框架帮助开发者写js逻辑代码,在开发应用的时候js的功能划分为以下几点:vue

  1. 渲染数据java

  2. 操做dom(写一些效果)react

  3. 操做cookie等存储机制apiwebpack

在前端开发中,如何高效的操做dom、渲染数据是一个前端工程师须要考虑的问题,并且当数据量大,流向较乱的时候,如何正确使用数据,操做数据也是一个问题angularjs

而js框架对上述的几个问题都有本身趋于完美的解决方案,开发成本下降。高性能高效率。惟一的缺点就是须要使用必定的成原本学习。web

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的模式,可是不少框架都会有一些更改

前端mvc框架,如angularjs,backbone:

前端MVC

会发现,用户能够直接操做controller(例如用户更改hash值,conrtoller直接监听hash值变化后执行逻辑代码,而后通知model更改)

控制器能够直接操做view,若是,让某一个标签得到进入页面得到焦点,不须要model来控制,因此通常会直接操做(angularJS,指令)

view能够直接操做model (数据双向绑定)

MVP:

mvp

view和model不能直接通讯,全部的交互都由presenter来作,其余部分的通讯都是双向的

view较薄 ,presenter较为厚重

MVVM:

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 有几个好处:

  1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
  2. 由于你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码能够是很是纯粹的逻辑,和 DOM 彻底解耦,更易于测试。
  3. 当一个 ViewModel 被销毁时,全部的事件处理器都会自动被删除。你无须担忧如何本身清理它们。
模板语法

在vue中,咱们使用mustache插值({{}})来将数据渲染在模板中

使用v-once指令能够控制只能插入一次值,当数据变化的时候,模板对应的视图不更新

使用v-html指令能够解析html格式的数据

在html标签属性里不能使用mustache插值,这个时候给元素添加动态属性的时候使用v-bind来绑定属性,能够缩写成:

在使用v-bind绑定class和内联样式的时候,vue作了一些优化,可使用对象语法和数组的语法来控制

防止表达式闪烁:

  1. v-cloak

    给模板内的元素添加v-cloak属性后,元素在vue没有加载完的时候就有这个属性,当vue加载完成后这个属性就消失了,因此咱们能够给这个属性设置css样式为隐藏

    <style>
     [v-cloak]{
         visibility: hidden;
     }
     </style>
  2. v-text/v-html

    v-text会指定将模板内元素的textContent属性替换为指令值所表明的数据,也能够用于防止闪烁
    v-html能够解析标签,更改元素的innerHTML,性能比v-text较差

  3. v-pre

    跳过元素和其子元素的编译过程,能够用来显示mustache

vue-resource

这是一款vue的插件,能够用来进行数据交互,支持的请求方式:GET/POST/JSONP/OPTIONS...

这个插件官方宣布不在更新维护,也就是说尽可能不要使用

计算属性、监听
有的时候咱们须要在模板中使用数据a,这个时候就须要用到表达式,可是有的地方咱们须要对a数据进行一些简单的处理后才能使用,那么咱们就会在表达式中写一些js逻辑运算

```
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
```
这样咱们的维护就会很是困难,也不便于阅读


那め咱们就能够在methods里设置一个方法,在模板的表达式中使用这个方法

```
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
    return this.message.split('').reverse().join('')
}
}
```

可是这个时候,只要vm中有数据变化,这个变化的数据可能和咱们关注的数据无关,可是vm都会从新渲染模板,这个时候表达式中的方法就会从新执行,大大的影响性能


这个时候其实咱们可使用监听器里完成:

在vm实例中设置watch属性,在里面经过键值对来设置一些监听,键名为数据名,值能够是一个函数,这个函数在数据改变以后才会执行,两个参数分别是性格前的值和更改后的值
a: function (val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal)
    }
值还能够是一个方法名字,当数据改变的时候这个方法会执行

当数据为object的时候,object的键值对改变不会被监听到(数组的push等方法能够),这个时候须要设置深度监听:
c: {
        deep:true,
        handler:function (val, oldVal) {
            console.log('new: %s, old: %s', val, oldVal)
        }
    },
监听的handler函数前面的这几种写法都是在数据变化的时候才会执行,初始化的时候不会执行,可是若是设置immediate为true就能够了
num:{
        immediate:true,
        handler:function(val){
            this.nums = val*2
        }
    }
咱们在回到上面的问题,用监听器加上immediate属性就能够作到该效果,可是你们能够看到的是逻辑稍稍有点复杂

watch还能够经过实例对象直接使用:vm.$watch,返回一个取消监听的函数,这个函数执行以后会取消监听


咱们通常都会用到一个叫计算属性的东西来解决:

计算属性就是在实例配置项中经过computed来为vm设置一个新的数据,而这个新数据会拥有一个依赖(一条已经存在的数据),当依赖发送变化的时候,新数据也会发送变化

与方法的方式相比,它性能更高,计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会从新求值。相比之下,每当触发从新渲染时,调用方法将总会再

次执行函数。

与watch相比,写起来简单,逻辑性更清晰,watch通常多用于,根据数据的变化而执行某些动做,而至于这些动做是在干什么其实无所谓,而计算属性更有针对性,根据数据变化而更改

另外一个数据

计算属性也拥有getter和setter,默认写的是getter,设置setter执行能够当此计算属性数据更改的时候去作其余的一些事情,至关于watch这个计算属性
xm:{
        get:function(){//getter 当依赖改变后设置值的时候
            return this.xing+'丶'+this.ming
        },
        set:function(val){//setter 当自身改变后执行
            this.xing = val.split('丶')[0]
            this.ming = val.split('丶')[1]
        }
    }
过滤器

vue中能够设置filter(过滤器)来实现数据格式化,双花括号插值和 v-bind 表达式中使用

vue1.0的有默认的过滤器,可是在2.0的时候所有给去掉了

因此在vue中若是想要使用过滤器就须要自定义

自定义的方法有两种:全局定义和局部定义,全局定义的过滤器在任意的实例、组件中均可以使用,局部定义就是在实例、组件中定义,只能在这个实例或组件中使用

  1. 全局定义

    Vue.filter(name,handler)

    name是过滤器的名字,handler是数据格式化处理函数,接收的第一个参数就是要处理的数据,返回什么数据,格式化的结果就是什么

    在模板中经过 | (管道符) 来使用,在过滤器名字后面加()来传参,参数会在handler函数中第二个及后面的形参来接收

<p>{{msg | firstUpper(3,2)}}</p>

    Vue.filter('firstUpper',function (value,num=1,num2) {
        console.log(num2)
        return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase()
    })
  1. 局部定义

    在实例、组件的配置项中设置 filters,键名为过滤器名,值为handler

    filters:{
         firstUpper:function (value,num=1,num2) {
         console.log(num2)
         return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase()
         }
     }

注意:

过滤器只能在mustache插值、v-bind里使用,其余的指令等地方都不能用
条件渲染

在Vue中可使用v-if来控制模板里元素的显示和隐藏,值为true就显示,为false就隐藏

v-if控制的是是否渲染这个节点

当咱们须要控制一组元素显示隐藏的时候,能够用template标签将其包裹,将指令设置在template上,等等vm渲染这一组元素的时候,不会渲染template

当有else分支逻辑的时候,能够给该元素加上v-else指令来控制,v-else会根据上面的那个v-if来控制,效果与v-if相反,注意,必定要紧挨着

还有v-else-if指令能够实现多分支逻辑

<input type="text" v-model="mode">  
      <template  v-if="mode=='A'">
        <h1>1.title</h1>
        <p>个人第一个P标签</p>  
      </template>
     <template  v-else-if="mode=='B'">
        <h1>2.title</h1>
        <p>个人第二个P标签</p>
     </template>
     <template  v-else-if="mode=='C'">
        <h1>3.title</h1>
        <p>个人第三个P标签</p>
     </template>
     <template  v-else>
       
        <p>很差意思,输入有误</p>
     </template>

须要注意的另外一个地方是:Vue 会尽量高效地渲染元素,一般会复用已有元素而不是从头开始渲染。这样确实能使Vue变得更快,性能更高,可是有的时候咱们须要让实例去更新dom而不是

复用,就须要给dom加上不一样的key属性,由于vue在判断到底渲染什么的时候,包括哪些dom能够复用,都会参考key值,若是dom表现基本一致,符合复用的条件,可是key值不一样,依然不会复

Vue还提供了v-show指令,用法和v-if基本同样,控制的是元素的css中display属性,从而控制元素的显示和隐藏 , 不能和v-else配合使用,且不能使用在template标签上,由于template不

会渲染,再更改它的css属性也不会渲染,不会生效

v-if vs v-show

v-if 是“真正”的条件渲染,由于它会确保在切换过程当中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:若是在初始渲染时条件为假,则什么也不作——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——无论初始条件是什么,元素老是会被渲染,而且只是简单地基于 CSS 进行切换。
通常来讲,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。所以,若是须要很是频繁地切换,则使用 v-show 较好;若是在运行时条件不多改变,则使用 v-if 较好。

mixin

在Vue中,咱们能够经过定义多个mixin来实现代码抽离复用,便于维护,提高页面的逻辑性

要注意的是:data属性不要使用mixin,由于从逻辑上来讲,每个实例、组件的数据都应该是独立的

一个mixin其实就是一个纯粹的对象,上面挂载着抽离出来的配置,在某一个实例中,经过mixins选项(数组)导入后,此实例就拥有导入的mixin的配置

且导入的配置不会覆盖原有的,而是合并到一块儿

虚拟dom

频繁且复杂的dom操做一般是前端性能瓶颈的产生点,Vue提供了虚拟dom的解决办法

虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操做。这句话,也许过于抽象,却基本概况了虚拟DOM的设计思想

(1) 提供一种方便的工具,使得开发效率获得保证

(2) 保证最小化的DOM操做,使得执行效率获得保证

也就是说,虚拟dom的框架/工具都是这么作的:

  1. 根据现有的真实dom来生成一个完整的虚拟dom树结构
  2. 当数据变化,或者说是页面须要从新渲染的时候,会从新生成一个新的完整的虚拟dom
  3. 拿新的虚拟dom来和旧的虚拟dom作对比(使用diff算法),。获得须要更新的地方以后,更新内容

这样的话,就能大量减小真实dom的操做,提升性能

组件化

模块化就是将系统功能分离成独立的功能部分的方法,通常指的是单个的某一种东西,例如js、css

而组件化针对的是页面中的整个完整的功能模块划分,组件是一个html、css、js、image等外链资源,这些部分组成的一个聚合体

优势:代码复用,便于维护

划分组件的原则:具备大量的布局结构的,或者是独立的逻辑的,都应该分红组件

组件应该拥有的特性:可组合,可重用,可测试,可维护

组件

在vue中,咱们经过Vue.extend来建立Vue的子类,这个东西其实就是组件

也就是说Vue实例和组件的实例有差异可是差异不带,由于毕竟一个是父类一个是子类

通常的应用,会拥有一个根实例,在根实例里面都是一个一个的组件

由于组件是要嵌入到实例或者父组件里的,也就是说,组件能够互相嵌套,并且,全部的组件最外层必须有一个根实例,因此组件分为:全局组件和局部组件

全局组件在任意的实例、父级组件中都能使用,局部组件只能在建立本身的父级组件或者实例中使用

组件经过不一样的注册方法成为全局、局部组件

建立组件:

Vue.extend(options)

全局注册:

var App = Vue.extend({
        template:"<h1>hello world</h1>"
    })
    Vue.component('my-app',App)

组件经过template来肯定本身的模板,template里的模板必须有根节点,标签必须闭合

组件的属性挂载经过:data方法来返回一个对象做为组件的属性,这样作的目的是为了每个组件实例都拥有独立的data属性

响应式原理

由于vue是mvvm的框架,因此当数据变化的时候,视图会当即更新,视图层产生操做后会自动通知vm来更改model,因此咱们能够实现双向数据绑定,而其中的原理就是实例会将设置的data逐

个遍历利用Object.defineProperty给数据生成getter和setter,当数据变化地方时候setter会监听到而且通知对应的watcher工具进行逻辑运算会更新视图

声明式渲染

在vue中,咱们能够先在vue实例中声明数据,而后经过{{}}等方式渲染在dom中

相关文章
相关标签/搜索