MySQL中间件之ProxySQL(8):SQL语句的重写规则极速赛车ProxySQL(8):

联系方式:QQ:2747044651 网址http://zhengtuwl.com
的根元素“#mvvm-app”内只有一个文本节点#text,#text的内容为{{name}}。我们就以下面这个模板详细了解一下VUE框架的大体实现流程。
<div id="mvvm-app">
{{name}}
</div>
<script src="./js/observer.js"></script>
<script src="./js/watcher.js"></script>
<script src="./js/compile.js"></script>
<script src="./js/mvvm.js"></script>
<script>
let vm = new MVVM({
el: "#mvvm-app",
data: {
name: "hello world"
},
})

</script>
? 1
? 2
? 3
? 4
? 5
? 6
? 7
? 8
? 9
? 10
? 11
? 12
? 13
? 14
? 15
? 16
? 17

复制代码
数据代理
1、什么是数据代理
在vue里面,我们将数据写在data对象中。但是我们在访问data里的数据时,既可以通过vm.data.name访问,也可以通过vm.name访问。这就是数据代理:在一个对象中,可以动态的访问和设置另一个对象的属性。
2、实现原理
我们知道静态绑定(如vm.name = vm.data.name)可以一次性的将结果赋给变量,而使用Object.defineProperty()方法来绑定则可以通过set和get函数实现赋值的中间过程,从而实现数据的动态绑定。具体实现如下:
复制代码
let obj = {};
let obj1 = {
name: ‘xiaoyu’,
age: 18,
}
//实现origin对象代理target对象
function proxyData(origin,target){
Object.keys(target).forEach(function(key){
Object.defineProperty(origin,key,{//定义origin对象的key属性
enumerable: false,
configurable: true,
get: function getter(){
return target[key];//origin[key] = target[key];
},
set: function setter(newValue){
target[key] = newValue;
}
})
})
}
复制代码
vue中的数据代理也是通过这种方式来实现的。
复制代码
function MVVM(options) {
this.options=options||;vardata=this.data=this.options=options||;vardata=this.data=this.options.data;
var _this = this;//当前实例vm
// 数据代理
// 实现 vm._data.xxx -> vm.xxx
Object.keys(data).forEach(function(key) {
_this._proxyData(key);
});
observe(data, this);
this.$compile = new Compile(options.el || document.body, this);
? 1
? 2
? 3
? 4
? 5
? 6
? 7
? 8
}
MVVM.prototype = {
_proxyData: function(key) {
var _this = this;
if (typeof key == ‘object’ && !(key instanceof Array)){//这里只实现了对对象的监听,没有实现数组的
this._proxyData(key);
}
Object.defineProperty(_this, key, {
configurable: false,
enumerable: true,
get: function proxyGetter() {
return _this._data[key];
},
set: function proxySetter(newVal) {
_this._data[key] = newVal;
}
});
},
};
复制代码
实现Observe
1、双向数据绑定
数据变动  —>  视图更新
视图更新  —>  数据变动
要想实现当数据变动时视图更新,首先要做的就是如何知道数据变动了,可以通过Object.defineProperty()函数监听data对象里的数据,当数据变动了就会触发set()方法。所以我们需要实现一个数据监听器Observe,来对数据对象中的所有属性进行监听,当某一属性数据发生变化时,拿到最新的数据通知绑定了该属性的订阅器,订阅器再执行相应的数据更新回调函数,从而实现视图的刷新。
当设置this.name = ‘hello vue’时,就会执行set函数,通知订阅器里的订阅者执行相应的回调函数,实现数据变动,对应视图更新。
复制代码
function observe(data){
if (typeof data != ‘object’) {
return ;
}
return new Observe(data);
}
function Observe(data){
this.data = data;
this.walk(data);
}
Observe.prototype = {
walk: function(data){
let _this = this;
for (key in data) {
if (data.hasOwnProperty(key)){
let value = data[key];
if (typeof value == ‘object’){
observe(value);
}
_this.defineReactive(data,key,data[key]);
}
}
},
defineReactive: function(data,key,value){
Object.defineProperty(data,key,{
enumerable: true,//可枚举
configurable: false,//不能再define
get: function(){
console.log(‘你访问了’ + key);return value;
},
set: function(newValue){
console.log(‘你设置了’ + key);
if (newValue == value) return;
value = newValue;
observe(newValue);//监听新设置的值
}
})
}
}
复制代码
2、实现一个订阅器
要想通知订阅者,首先得要有一个订阅器(统一管理所有的订阅者)。为了方便管理,我们会为每一个data对象的属性都添加一个订阅器(new Dep)。
订阅器里存着的是订阅者Watcher(后面会讲到),由于订阅者可能会有多个,我们需要建立一个数组来维护。一旦数据变化,就会触发订阅器的notify()方法,订阅者就会调用自身的update方法实现视图更新。
复制代码
function Dep(){
this.subs = [];
}
Dep.prototype = {
addSub: function(sub){this.subs.push(sub);
},
notify: function(){
this.subs.forEach(function(sub) {
sub.update();
})
}
}
复制代码
每次响应属性的set()函数调用的时候,都会触发订阅器,所以代码补充完整。
复制代码
Observe.prototype = {
//省略的代码未作更改
defineReactive: function(data,key,value){
let dep = new Dep();//创建一个订阅器,会被闭包在key属性的get/set函数内,因此每个属性对应唯一一个订阅器dep实例
Object.defineProperty(data,key,{
enumerable: true,//可枚举
configurable: false,//不能再define
get: function(){
console.log(‘你访问了’ + key);
return value;
},
set: function(newValue){
console.log(‘你设置了’ + key);
if (newValue == value) return;
value = newValue;
observe(newValue);//监听新设置的值
dep.notify();//通知所有的订阅者
}
})
}
}
复制代码
实现Complie
compile主要做的事情是解析模板指令,将模板中的data属性替换成data属性对应的值(比如将{{name}}替换成data.name值),然后初始化渲染页面视图,并且为每个data属性添加一个监听数据的订阅者(new Watcher),一旦数据有变动,收到通知,更新视图。
遍历解析需要替换的根元素el下的HTML标签必然会涉及到多次的DOM节点操作,因此不可避免的会引发页面的重排或重绘,为了提高性能和效率,我们把根元素el下的所有节点转换为文档碎片fragment进行解析编译操作,解析完成,再将fragment添加回原来的真实dom节点中。
注:文档碎片本身也是一个节点,但是当将该节点append进页面时,该节点标签作为根节点不会显示html文档中,其里面的子节点则可以完全显示。
Compile解析模板,将模板内的子元素#text添加进文档碎片节点fragment。
复制代码
function Compile(el,vm){
this.vm=vm;//vm为当前实例this.vm=vm;//vm为当前实例this.el = document.querySelector(el);//获得要解析的根元素
if (this.el){
this.fragment=this.nodeToFragment(this.fragment=this.nodeToFragment(this.el);
this.init();
this.el.appendChild(this.el.appendChild(this.fragment);
}
}
Compile.prototype = {
nodeToFragment: function(el){
let fragment = document.createDocumentFragment();
let child;

原文地址:http://blog.51cto.com/13914456/2156323

时间: 2024-08-02 03:20:50

MySQL中间件之ProxySQL(8):SQL语句的重写规则极速赛车ProxySQL(8):的相关文章

mysql 删除重复数据的sql语句

CREATE TABLE tmp AS SELECT id FROM get_review_url WHERE (no,title,name,content) IN (SELECT no,title,name,content FROM get_review_url GROUP BY no,title,name,content HAVING COUNT(*) > 1) AND id NOT IN (SELECT MIN(id) FROM get_review_url GROUP BY no,tit

如何在mysql查找效率慢的SQL语句

如何在mysql查找效率慢的SQL语句呢?这可能是困然很多人的一个问题,MySQL通过慢查询日志定位那些执行效率较低的SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysqld 会写一个包含所有执行时间超过long_query_time 秒的SQL语句的日志文件,通过查看这个日志文件定位效率较低的SQL .下面介绍MySQL中如何查询慢的SQL语句 一.MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句 1,slow_query_log 这

在MySQL命令行中使用SQL语句的规则

规则1: SQL语句必须以分号(;)或者(\G)结束 分号(;)是SQL语句的结束标志.如果遗忘了分号,而直接按下回车键时,在MySQL客户端上将显示如下 mySQL> SELECT * FROM customer -> 因为没有以分号结束,客户端认为SQL语句并没有结束,显示[->]等待用户继续输入命令,直到以分号结束.有些数据库中,支持省略最后的分号的情况. 规则2: 保留关键字不区分大小写 保留关键字是SQL中事先定义好的关键字,如上面检索语句中的SELECT.FROM等就属于保留

如何查找MySQL中查询慢的SQL语句

本文导读:如何在mysql查找效率慢的SQL语句呢?这可能是困然很多人的一个问题,MySQL通过慢查询日志定位那些执行效率较低的SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysqld 会写一个包含所有执行时间超过long_query_time 秒的SQL语句的日志文件,通过查看这个日志文件定位效率较低的SQL .下面介绍MySQL中如何查询慢的SQL语句 一.MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句 1,slow_query_

MySQL表横纵转置Sql语句

id, student, course, mark 1,  张三,    语文,  90 2,  李四,    语文,  80 3,  张三,    数学,  70 4,  李四,    数学,  80 现在想用转置表的方法转成二维表输出,要求格式是: student, 语文, 数学 张三,    90,  70 李四,    80,  80 select student,     sum(if(course='语文',mark,0)) as 语文,     sum(if(course='数学'

MySql命令行命令和SQL语句

一.常用mysql命令行命令 1.启动MYSQL服务 net start mysql 停止MYSQL服务 net stop mysql 2.netstat -na|findstr 3306 查看被监听的端口,findstr用于查找后面的端口是否存在 3.在命令行中登录MYSQL控制台,即使用MYSQL COMMEND LINE TOOL 语法格式 mysql -user=root  -password=123456  db_name 或者简写格式 mysql -uroot -p123456 db

Navicat for MySQL界面下如何用SQL语句创建表?

Navicat for MySQL界面下如何用SQL语句创建表?下面小编就告诉你.首先打开 Navicat,选择一个数据库,点击"查询",在右侧点击"创建查询",输入SQL语句,点击"执行"就可以了,示例SQL: CREATE TABLE `test`.`users` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `age` int(10) DEF

2.MySQL用户管理,常用SQL语句,MySQL数据库备份与恢复

[toc] MySQL用户管理,重用SQL语句,MySQL数据库备份与恢复 一.MySQL用户管理 1.创建一个普通用户并授权 首先启动mysql,然后进入 [[email protected] ~]# /etc/init.d/mysqld start Starting MySQL... SUCCESS! [[email protected] ~]# mysql -uroot -pxavilinux Warning: Using a password on the command line in

MySQL客户端工具以及常用SQL语句

Mysql客户端工具: 在用yum安装的maiadb-server的时候,在/etc/my.cnf.d下有一个名为client.cnf的文件,编辑此文件,在此文件的[client]下添加用户名和密码就可以不用输入口令登录 vim /etc/my.cnf.d/client.cnf [client] user=root # 登录数据库使用的用户名 password=mysql #登录数据库使用的密码 大部分常用SQL语句 1 创建用户并查看(SQL语句); create user [email pr