Vue学习系列(一)——初识Vue.js核心
前言
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核心的更多相关文章
- Node.js实战项目学习系列(1) 初识Node.js
前言 一直想好好学习node.js都是半途而废的状态,这次沉下心来,想好好的学习下node.js.打算写一个系列的文章大概10几篇文章,会一直以实际案例作为贯穿的学习. 什么是node Node.js ...
- Vue学习系列(二)——组件详解
前言 在上一篇初识Vue核心中,我们已经熟悉了vue的两大核心,理解了Vue的构建方式,通过基本的指令控制DOM,实现提高应用开发效率和可维护性.而这一篇呢,将对Vue视图组件的核心概念进行详细说明. ...
- Vue学习系列(三)——基本指令
前言 在上一篇中,我们已经对组件有了更加进一步的认识,从组件的创建构造器到组件的组成,进而到组件的使用,.从组件的基本使用.组件属性,以及自定义事件实现父子通讯和巧妙运用插槽slot分发内容,进一步的 ...
- Vue学习系列(四)——理解生命周期和钩子
前言 在上一篇中,我们对平时进行vue开发中遇到的常用指令进行归类说明讲解,大概已经学会了怎么去实现数据绑定,以及实现动态的实现数据展示功能,运用指令,可以更好更快的进行开发.而在这一篇中,我们将通过 ...
- Vue学习第一天:Vue.js指令系统
1. 如何使用Vue.js? 1.1 直接引入 - <script src="./statics/vue.min.js"></script> - 引入之后在 ...
- 【Vue 学习系列 - 01】- 环境搭建(Win7)
1. 根据系统下载Node.js 下载地址:http://nodejs.cn/download 2. 安装Node.js 点击安装Node.js,在安装目录D:\Program Files\nodej ...
- Vue学习记录第一篇——Vue入门基础
前面的话 Vue中文文档写得很好,界面清爽,内容翔实.但文档毕竟不是教程,文档一上来出现了大量的新概念,对于新手而言,并不友好.个人还是比较喜欢类似于<JS高级程序设计>的风格,从浅入深, ...
- 前端框架Vue------>第一天学习、Vue学习的路径、Vue官网(1)
文章目录 1.学习目标 2.前端知识体系 2.1 前端三要素 2.2.MVVM 3.第一个Vue程序 4.Vue实例的生命周期 vue的官方文档:https://cn.vuejs.org/ 1.学习目 ...
- Vue学习笔记十三:Vue+Bootstrap+vue-resource从接口获取数据库数据
目录 前言 SpringBoot提供后端接口 Entity类 JPA操作接口 配置文件 数据库表自动映射,添加数据 写提供数据的接口 跨域问题 前端修改 效果图 待续 前言 Vue学习笔记九的列表案例 ...
随机推荐
- ui、li模拟下拉框
转载:原文地址:https://www.jianshu.com/p/e303e0298e9e 效果图: HTML: <div class="rank_top"> < ...
- 【Nginx】四层负载均衡配置
一.概述 二.配置 2.1 环境准备 2.2 安装及配置 1).下载Nginx 2).下载nginx_tcp_proxy_module 插件 3).编译Nginx 4).修改Nginx.conf配置文 ...
- eclipse的properties文件中文被转码问题
如图所示:首次在properties里打中文注释,结果一输入中文就自动被转码,于是查看了一下项目的编码是UTF-8的,而eclipse中默认的properties文件编码是ISO的,所以修改一下即可 ...
- Go语言基础之基本数据类型
Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. 基本数据类型 整型 整型 ...
- JSP四大作用域属性范围
JSP四大作用域分别为:page, request ,session, application . 第一个作用域是page,他只在当前页面有效,也就是用户请求的页面有效,当当前页面关闭或转到其他页面时 ...
- Apollo源码解析-搭建调试环境
准备工作 本地运行时环境 JDK :1.8+ MySQL :5.6.5+ Maven :3.6.1 IDE :IntelliJ IDEA Apollo的表结构对timestamp使用了多个defaul ...
- 浅谈PHP反序列化漏洞原理
序列化与反序列化 序列化用途:方便于对象在网络中的传输和存储 0x01 php反序列化漏洞 在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等. 常见的序列化格式: ...
- Python 开发植物大战僵尸游戏
作者:楷楷 链接:https://segmentfault.com/a/1190000019418065 开发思路 完整项目地址: https://github.com/371854496/pygam ...
- 多线程——Thread类
进程(Process):“正在执行的程序”,程序进入内存运行就变成了一个进程.一个进程会产生多个线程. 多线程(Multithread):一个进程中同时存在几个执行体.单线程是按照函数的顺序执行,多线 ...
- 全方位深度剖析PHP7底层源码(已完结)
第1章 课程介绍本章主要介绍课程要讲的知识点,以及课程要求等. 第2章 PHP7的新特性本章主要介绍PHP7的新特性,做基准测试,与PHP5对比验证PHP7的性能提升程度,引出对PHP7源码学习的必要 ...