本系列是一个教程,下面贴下目录~
1.手把手教你从零写一个简单的 VUE
2.手把手教你从零写一个简单的 VUE--模板篇

今天给大家带来的是实现一个简单的类似 VUE 一样的前端框架,VUE 框架现在应该算是非常主流的前端数据驱动框架,今天我们来从零开始写一个非常简单的 VUE 框架,主要是让大家知道最核心的 vue 部分是怎么运转起来的。包括数据绑定,模板处理,以及页面渲染,数据驱动视图等几个部分,代码在文章末尾给出来,下面我们开始~

VUE 是怎么运转起来的

在正式动手之前,我们先来了解下 vue 是怎么运转起来的,vue 从核心来说,是一个通过数据去驱动页面渲染的框架,也就是说通过改变数据的状态,可以控制页面中渲染的逻辑,比如展示数据,切换样式,这些的核心都是通过对数据改变的监听,从而将数据发生改变的对应的视图进行更新渲染,这是整个框架的核心运行机制。因此我们制作的简单 vue 框架,主要是围绕着怎么监听,怎么渲染,怎么更新这个流程去做的,旨在让大家知道 vue 怎么跑起来的,其余的 vue 组件,指令,插件等内容将在后面的文章中写出。

设计

首先我们要知道我们要做一个简单数据驱动视图前端框架,它包括以下几个部分:

  1. 能够编译简单的模板
  2. 能够监听数据变化
  3. 数据变化的时候,能够关联对应的视图并同步的更新视图

根据上面列举的需求,我们需要程序抽象以下几个部分:

  1. 存储数据的$data,用于保存数据,渲染视图
  2. 与每个模板对应的Node对象,对象包含对应模板的渲染函数,还有渲染函数需要使用的数据集合
  3. 对数据进行监听关联的Watcher类,用于关联数据和对应的模板,监听数据变化

开始编码

首先介绍下项目用的工具及框架,项目使用rollup进行项目模块化构建,使用ES6进行编码。下面开始正式编码。
首先我给框架起了个简单的名字,叫QV,这个对象会暴露到全局中,进行实例化,实例化代码如下:

在实例化的时候传给了对象 eltemplatedata等数据,其中el是模板在页面的挂载点,template 是获取模板的选择器,分别对应body<app></app>标签和script标签中的模板,data 是定义的数据对象。

数据处理

QV类的构造函数中,我们会对传入的配置进行处理,首先我们会对数据进行格式化,使得其在被Watcher正常监控。格式化数据的代码如下:

可以看到formatData方法在原来的data上面又挂载了一个_od_属性,然后将原始数据进行格式化,每个数据分别包含value(数据值),linkNodes(被使用的节点值),mounted(是否已经被格式化过),通过对数据进行预处理,方便后面的数据监控绑定

模板节点处理

模板的能力是一个前端框架的重要组成部分,vue将模板转化为AST(抽象语法树),然后去解析其中的语法,比如{{}}v-for v-if等等,模板解析的总体思路如下:

  1. 将模板字符串通过正则表达式等方法进行切割,切割点为模板定义的关键字
  2. 将切割完的字符串进行分析,可以生成AST(抽象语法树)或者是直接进行处理操作
  3. 将分析完的东西进行字符串拼接,通过new Function生成模板函数

本例子只做流程的说明,所以模板很简单,只有赋值语法,如下:

可以看到模板中只有{{}}的赋值语法,插入变量为a、sdf、ccc的语法
那么这个是怎么进行解析的呢,代码如下:

下面重点讲一讲这个函数,可以看到函数的开头定义了一个正则表达式 /{{[ \t]*([\w\W]*?)[ \t]*}}/g,用于匹配和分割用{{}}界定的变量,通过 exec的运行,匹配出来的结果如下:

可以看到a,sdf,ccc都被匹配出来了,然后通过slice进行分割后重建,变成一段模板函数字符串,如下:

然后再通过new Function将上面的字符串变成一个函数,方法如下

其中的new Function("od",$t)中的od是这个函数的参数,可以在函数中使用
最后生成的模板函数如下:

这样子就完成了模板函数的开发,而且还将模板用的变量进行抽取,标记这个模板用到了哪些变量

监听器

监听器作为连接数据和视图更新的纽带,是vue的核心部分,vue是使用Object.defineProperty对数据进行处理后实现数据监听的,本程序也是使用这个核心方法进行数据监听的,核心代码如下:

下面我具体说下这段代码:
之前格式化数据的时候在原始数据里面添加了_od_字段,是用在数据监控时候的,Object.defineProperty可以设置get set属性,分别在对应的数据被获取或者被修改的时候会进行回调,因此如果直接操作原始数据,会导致监控程序发生死循环,因此通过_od_的拷贝数据进行操作,能够避免这种情况,可以看到get函数会直接返回_od_里面对应属性的value,而set函数我做了一个优化节流,对于连续修改数据只发生一次更新,将使用到这个数据的Node对象进行update操作

程序最核心的方法已经开发完成了,演示下结果,直接打开页面,可以看到下面的视图

可以看到程序将数据a sdf ccc赋值给模板,然后替换页面的app节点,渲染到页面上
接下来我们通过实例直接修改data
qv.$data.a = "change data a"
可以看到页面会更新成为

下面说下重新渲染的流程:

  1. 数据修改之后触发了Object.definePropertyset方法,方法检测到设置数据与原数据不同,回去获取linkNodes属性,里面包含了使用这个数据的Node节点,然后分别调用Node节点的update方法
  2. update方法被调用之后,Node会重新获取data去生成dom元素,然后替换现有的模板元素,至此完成一次更新

结语

这篇文章的例子旨在跟大家说明Vue是怎么运作的,希望可以帮助到大家在日常使用的时候遇到一些坑,可以从根本原理上面去找原因,当然这个demo 离Vue还是非常不完整的,缺少了各种模板语法,指令,事件绑定,组件系统,只是把核心的流程展现出来,希望大家喜欢

最后附上源码 点我点我,喜欢的话给个 star 呗~~

手把手教你从零写一个简单的 VUE的更多相关文章

  1. 手把手教你从零写一个简单的 VUE--模板篇

    教程目录1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 Hello,我又回来了,上一次的文章教会了大家如何书写一个简单 VUE,里面实现了VUE 的数据驱动视图 ...

  2. 手把手教你用vue-cli构建一个简单的路由应用

    上一章说道:十分钟上手-搭建vue开发环境(新手教程)https://www.jianshu.com/p/0c6678671635 开发环境搭建好之后,那么开始新添加一些页面,构建最基本的vue项目, ...

  3. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...

  4. 【良心保姆级教程】java手把手教你用swing写一个学生的增删改查模块

    很多刚入门的同学,不清楚如何用java.swing去开发出一个系统? 不清楚如何使用java代码去操作数据库进行增删改查一些列操作,不清楚java代码和数据库(mysql.sqlserver)之间怎么 ...

  5. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  6. 如何写一个简单的http服务器

    最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...

  7. 如何写一个简单的shell

    如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...

  8. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  9. 一步一步写一个简单通用的makefile(三)

    上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...

随机推荐

  1. Java 类方法和类变量

    目录 一.类变量 1.如果定义类变量 2.如何访问类变量 3.类变量的使用注意事项和细节 二.类方法 1.类方法的形式 2.类方法的调用 3.类方法经典使用场景 4.类变量和类方法 三.main方法 ...

  2. JAVA——转义字符

    目录 1.Java转义字符 2.Java中的注释 2.1Java 中的注释类型 2.2文档注释 3.Java代码规范 4.Java开发注意事项和细节说明 1.Java转义字符 在控制台,输入 tab ...

  3. linux su、sudo、sudo su、sudo -i的用法和区别

    sudo : 暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.不过有时间限制,Ubuntu默认一次时长15分钟. su : 切换到某某用户模式,提 ...

  4. Spring Cloud Ribbon 中的 7 种负载均衡策略

    负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而我们今天的主角 Ribbon 就属于后者--客户端负载均衡器. 服务端负载均衡器的问题是,它提供了更强的流量控制权,但 ...

  5. 3、myql的逻辑架构和sql的执行流程

    msyql逻辑架构 逻辑架构的解析 逻辑架构图如下(序号代表的是:服务器处理客户端请求的流程) 1.1connectors connectors是指使用不同语言的客户端与mysql server服务器 ...

  6. Scipy的stats模块包含了多种概率分布的随机变量,随机变量分为连续和离散两种。+忽略程序中警告信息+np.newaxis解释

  7. Springboot项目 配置数据库连接属性后,启动项目报错

    Springboot项目 配置数据库连接属性后,启动项目报错,错误如下: 错误原因分析: 1.连接信息配置错误 当使用properties为配置文件时,如图所示,上面的 spring.datasour ...

  8. ArcMap操作随记(3)

    1.地图四要素: 图名.图例.比例尺.指北针 2.[栅格计算器].[加权叠加]和[加权总和]的不同 [栅格计算器]的结果是浮点型小数 [加权叠加]工具,输入栅格必须为整型.若成本栅格涉及重分类,最好用 ...

  9. WPF 布局之综合实例

    WPF 布局之综合实例 <Window x:Class="UniFormGridDemo.MainWindow" xmlns="http://schemas.mic ...

  10. Django基础七之CBV装饰器和中间件

    Django基础七之CBV装饰器和中间件 目录 Django基础七之CBV装饰器和中间件 1. CBV加装饰器 2. Django中间件 2.1 Django中间件介绍 2.2 自定义中间件 2.2. ...