前言

vue.js是一套构建用户界面的渐进式框架,vue.js的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。

vue通过DOM事件操作和指令来进行视图层和模型层的相互通讯,会为每一处需要动态更新的DOM节点创建一个指令对象。每当一个指令对象观测的数据变化时,它便会对所绑定的目标节点执行相应的DOM操作。基于指令的数据绑定使得具体的DOM操作都被合理地封装在指令定义中,业务代码只需要涉及模板和对数据状态的操作即可,这使得应用的开发效率和可维护性都大大提升。

因此,数据绑定,组件是整个vue的核心。响应的数据绑定就是数据驱动视图的概念。它让你在写 Web 应用介面时,只需要关注两件事:数据如何展示和数据如何变化。一旦数据发生变化时,比如用户输入,或者 ajax 请求返回后数据发现修改,对应的视图介面会自动的进行更新。

原理

vue.js是MVVM的架构,如图:

从图中可以看出视图层和模型层的相互传递,通过用户操作来绑定一些DOM事件来重新渲染到视图层。具体的内部架构如下图:

开始

一、 数据绑定:

实现方式:数据绑定即是视图层和模型层的双向绑定。即数据的改变驱动了视图的自动更新。

通过ViewModel控制,修改数据,从而控制View的展示,实现MVVM的思想。

里面的两个属性getter和setter,在这两个函数内部实现依赖的收集和触发,而且完美支持嵌套的对象结构。对于数组,则通过包裹数组的可变方法(比如push)来监听数组的变化。这使得操作Vue.js的数据和操作原生对象几乎没有差别。

  • Obejct.defineProperty 【提供getter 和 setter】
  • Observer 【提供getter 和 setter】—— 订阅者模式,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知,用来实时事件处理系统。
  • watcher 【提供getter 和 setter】 —— 模板和 Observer 对象结合在一起的纽带
  • Dep 【负责收集watcher】
  • Directive 【处理Vue模板指令】

    observe -> 触发setter -> watcher -> 触发update -> Directive -> 触发update -> 指令(如上图流程所示)

<span>Hello, this is {{name}}</span>
<script>
var app = new Vue({
el : '#app',
data : {
name: 'i3yuan'
}
}) </script>

new Vue 执行时做了什么

function Vue(option) {
var data = option.data
this.data = data
// 挂载 getter 和 setter
observe(data, this)
var id = option.el
// 编译 模板
var dom = new Compile(document.querySelector(id), this)
// 把编译好的模板挂载到 #app 上
document.querySelector(id).appendChild(dom)
}
//observe构造函数
function observe(obj, vm) {
Object.keys(obj).forEach(key => {
defineReactive(vm, key, obj[key])
})
}
//defineReactive
function defineReactive(vm, key, val) {
// 为每个变量分配一个 dep实例
var dep = new Dep()
// 配置getter和setter并且挂载到vm上
Object.defineProperty(vm, key, {
get() {
if ( Dep.target ) {
// JS的浏览器单线程特性, 保证整个全局变量在同一时间内, 只有一个监听器使用
dep.addSub(Dep.target)
}
return val
},
set(newVal) {
if ( newVal == val ) return;
val = newVal;
// 作为发布者发出通知
dep.notify()
}
})
} //Dep构造函数
function Dep() {
// 存放watcher
this.subs = []
} Dep.prototype = {
// 添加watcher, 也就是添加订阅
addSub(sub) {
this.subs.push(sub)
},
// 通知所有watcher
notify() {
this.subs.forEach(sub => {
sub.update()
})
}
} function Compile(node, vm) {
if(node) {
this.$frag = this.nodeToFragment(node, vm)
return this.$frag
}
} //watcher构造函数
function Watcher(vm, node, name, type) {
// 单例, 使用原因未知
Dep.target = this
// 姓名
this.name = name;
// 呵呵哒 uid
this.id = ++uid;
// 与变量相关的Node节点
this.node = node;
// vm 实例
this.vm = vm;
// 变量类型 nodeValue || value
this.type = type;
// 触发自己原型上的update方法
this.update()
// Watcher 实例创建结束就把单例置空
Dep.target = null
} Watcher.prototype = {
update() {
this.get()
if(!batcher) {
// bastcher 单例
batcher = new Batcher()
}
// 加入队列
batcher.push(this)
},
// 获取新值挂到自己的实例上
get() {
this.value = this.vm[this.name] // 触发getter
}
}

整个流程:

new Vue –> Observe 挂载 setter 和 getter –> Compile 编译模板 –> 为每个指令分配一个watcher –> 创建时会调用一次watcher.update 将自己加入到batcher的队列 –>
并且此时会触发 getter 将watcher加入dep –> batcher 统一来处理watcher后初始化自己 –> 当用户修改某个变量时 –> dep通知watcher –> watcher又被加入batcher处理 –> watcher 更新dom 

二、视图组件:

组件,相信大部分开发人员在开发现代框架的时候都或多或少的遇到一些组件,可想而知,现代框架已经走向了组件化的道路,虽然不同的主流框架都有不同封装组件的方式,但是核心思想都差不多一样。通过分离页面,使得整个页面由很多个组件构成,给我们的第一个印象就是,就像我们平时使用到的MVC中的分视图,或者子视图,但是又不一样,虽然组件是一部分,但是却是自己的一个整体,和其他组件相互独立,高内聚低耦合,可以通过自定义标签的形式来使用。

因此,在开发中, 把整一个网页的拆分成一个个区块,每个区块我们可以看作成一个组件。网页由多个组件拼接或者嵌套组成:

// 定义一个名为 Mycomponent  的新组件
Vue.component('Mycomponent', {
// 模板
template: '<div>{{msg}} {{privateMsg}}</div>',
// 接受参数
props: {
msg: String
},
// 私有数据,需要在函数中返回以避免多个实例共享一个对象
data: function () {
return {
privateMsg: 'component!' }
}
})
<Mycomponent msg="i3yuan"></Mycomponent>

组件的核心选项:

1 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。

2 初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。

3 接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。

4 方法(methods):对数据的改动操作一般都在组件的方法内进行。

5 生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。

6 私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。

注意事项

  • 组件注册一定要在实例化Vue对象之前,否则会报错
  • 属性名为components,s千万别忘了
  • 不管是全局组件还是局部组件,data都必须是一个函数,且return不能换行
  • 因为this指向的问题,建议用es5的方式写方法

总结

1.通过官方文档的学习和总结,认识到了vue的框架和通讯方式,以视图组件和数据绑定为核心构建完整的渐进式的框架。

2.从上述的两大核心的描述,我们大体理解了Vue的构建方式,通过基本的指令控制DOM,实现提高应用开发效率和可维护性。

3.下一节我们将对Vue视图组件的核心概念进行详细说明。

Vue学习系列(一)——初识Vue.js核心的更多相关文章

  1. Node.js实战项目学习系列(1) 初识Node.js

    前言 一直想好好学习node.js都是半途而废的状态,这次沉下心来,想好好的学习下node.js.打算写一个系列的文章大概10几篇文章,会一直以实际案例作为贯穿的学习. 什么是node Node.js ...

  2. Vue学习系列(二)——组件详解

    前言 在上一篇初识Vue核心中,我们已经熟悉了vue的两大核心,理解了Vue的构建方式,通过基本的指令控制DOM,实现提高应用开发效率和可维护性.而这一篇呢,将对Vue视图组件的核心概念进行详细说明. ...

  3. Vue学习系列(三)——基本指令

    前言 在上一篇中,我们已经对组件有了更加进一步的认识,从组件的创建构造器到组件的组成,进而到组件的使用,.从组件的基本使用.组件属性,以及自定义事件实现父子通讯和巧妙运用插槽slot分发内容,进一步的 ...

  4. Vue学习系列(四)——理解生命周期和钩子

    前言 在上一篇中,我们对平时进行vue开发中遇到的常用指令进行归类说明讲解,大概已经学会了怎么去实现数据绑定,以及实现动态的实现数据展示功能,运用指令,可以更好更快的进行开发.而在这一篇中,我们将通过 ...

  5. Vue学习第一天:Vue.js指令系统

    1. 如何使用Vue.js? 1.1 直接引入 - <script src="./statics/vue.min.js"></script> - 引入之后在 ...

  6. 【Vue 学习系列 - 01】- 环境搭建(Win7)

    1. 根据系统下载Node.js 下载地址:http://nodejs.cn/download 2. 安装Node.js 点击安装Node.js,在安装目录D:\Program Files\nodej ...

  7. Vue学习记录第一篇——Vue入门基础

    前面的话 Vue中文文档写得很好,界面清爽,内容翔实.但文档毕竟不是教程,文档一上来出现了大量的新概念,对于新手而言,并不友好.个人还是比较喜欢类似于<JS高级程序设计>的风格,从浅入深, ...

  8. 前端框架Vue------>第一天学习、Vue学习的路径、Vue官网(1)

    文章目录 1.学习目标 2.前端知识体系 2.1 前端三要素 2.2.MVVM 3.第一个Vue程序 4.Vue实例的生命周期 vue的官方文档:https://cn.vuejs.org/ 1.学习目 ...

  9. Vue学习笔记十三:Vue+Bootstrap+vue-resource从接口获取数据库数据

    目录 前言 SpringBoot提供后端接口 Entity类 JPA操作接口 配置文件 数据库表自动映射,添加数据 写提供数据的接口 跨域问题 前端修改 效果图 待续 前言 Vue学习笔记九的列表案例 ...

随机推荐

  1. BALNUM - Balanced Numbers(数位dp)

    题目链接:http://www.spoj.com/problems/BALNUM/en/ 题意:问你在[A,B]的闭区间内有几个满足要求的数,要求为每个出现的奇数个数为偶数个,每个出现的偶数个数为奇数 ...

  2. CF1005C Summarize to the Power of Two 暴力 map

    Summarize to the Power of Two time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  3. redis数据库学习

    0 使用理由 0.1 高性能 纯内存操作,比在硬盘操作数据的速度有极大提升 0.2 高并发 承受请求比直接操作数据库大得多 0.3 单线程 至于redis单线程的原因.有点意思.CPU不是Redis的 ...

  4. 【Offer】[23] 【链表中环的入口结点】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 一个链表中包含环,如何找出环的入口结点?  思路分析 判断链表中是否有环:用快慢指针的方法,慢指针走一步,快指针走两步,如果快指针追上 ...

  5. 卸载VMware

    最近使用ubuntu的时候操作不当直接卡死了,然后强制关闭VMware软件,之后再打开时出现本文中的 “Vmware启动ubuntu 出现错误 ”这个情况,具体请看链接:https://www.cnb ...

  6. JSP学习笔记(6)—— 自定义MVC框架

    仿照SpringMVC,实现一个轻量级MVC框架,知识涉及到了反射机制.注解的使用和一些第三方工具包的使用 思路 主要的总体流程如下图所示 和之前一样,我们定义了一个DispatchServlet,用 ...

  7. tomcat下载镜像地址

    镜像地址:http://mirrors.cnnic.cn/apache/tomcat/ typora编写makedown文件 羚羊云api开发:http://doc.topvdn.com/api/in ...

  8. web性能优化实践

    一.SQL查询优化 1.循环中有多次查询sql,改为在循环外一次查询后再处理 2.循环多次插入,改为组装好数据后批量插入 3.梳理业务逻辑能一次查完的,绝不分多次查 4.索引用起来 5.分页查询 二. ...

  9. springboot之全局处理异常封装

    springboot之全局处理异常封装 简介 在项目中经常出现系统异常的情况,比如NullPointerException等等.如果默认未处理的情况下,springboot会响应默认的错误提示,这样对 ...

  10. 最近学习到的Lambda表达式

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 中秋去了躺上海,在外滩上打了个卡: 紧接着学了一下J ...