1、MVVM
(1) 什么是MVVM
MVVM
本质上描述的是一种视图和逻辑之间的数据双向关联关系,专业术语中称为数据双向绑定模式
- 核心:结构分离(视图和数据分离)、双向同步(数据可以自动渲染,页面数据可以自动更新)
(2) MVVM
和 MVC
MVVM
是一种数据双向绑定模式,核心解决了数据和结构分离、数据双向同步的问题
MVC
是一种编程模式,核心解决了根据用户请求处理不同业务的逻辑问题,主要描述了请求分发
(3) 底层工作原理
Vue
中的一个重要特性就是数据的双向绑定,底层主要是通过数据劫持的方式实现的!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// let myName = "大牧老师"
// 需求1:当我改变myName变量的数据时,请同时打印一句话~数据被改变了
// 需求2:当我读取myName变量的数据时,请同时打印一句话~数据被读取了
// 原生语法中,没有提供可以监听变量数据的事件
// 数据劫持
// ① 临时存储数据的变量
let myNameTemp = "大牧老师"
// ② 数据劫持方式,声明可以监听的变量
// Object.defineProperty() 专门用于数据劫持的函数
// 参数1:挂载的对象
// 参数2:挂载的属性;将一个指定名称的属性挂载到一个指定的对象上
// 下面的代码,将myName变量挂载到window对象上
// 参数3:监听数据变化的对象,包含get()读取函数、set()设置函数
Object.defineProperty(window, 'myName', {
get() {
console.log('有用户读取myName变量的数据了')
return myNameTemp
},
set(val){
console.log('有用户改变myName变量的数据了')
myNameTemp = val
}
})
// 读取数据
console.log(myName) // 同时会触发 get()监听函数
// 设置数据
myName = "DAMU" // 同时会触发set()监听函数
</script>
</body>
</html>
(4) 自定义微型框架
自定义框架:myvue.js
/*
* @Author: damu 1007821300@qq.com
* @Date: 2022-06-08 10:58:44
* @LastEditors: damu 1007821300@qq.com
* @LastEditTime: 2022-06-08 11:13:06
* @FilePath: \code\myvue.js
* @Description:自定义vue框架
*
* Copyright (c) 2022 by damu 1007821300@qq.com, All Rights Reserved.
*/
class MyVue {
constructor(props) {
// 获取挂载节点的DOM对象
this.$el = document.querySelector(props.el)
this._html = this.$el.innerHTML
// 数据劫持的方式,挂载data数据
this.$data = {...props.data}
for(let key in props.data) {
Object.defineProperty(this, key, {
get() {
return this.$data[key]
},
set(val) {
this.$data[key] = val
// 一旦数据发生更新,从新渲染界面
this.render()
}
})
}
// 挂载methods函数
for(let key in props.methods) {
this[key] = props.methods[key]
}
// 创建好对象,挂载完数据后,调用并渲染页面
this.render()
}
/** 渲染数据的函数 */
render() {
// 定义一个正则表达式,查询需要替换的数据
let reg = /\{\{\s*(.*?\s*\(?\)?)\s*\}\}/ig
// 准备替换数据
let newHtml = this._html.replace(reg, (a, b) => {
console.log(a, b)
if(b.endsWith('()')) {
console.log(b, '这是要执行的函数')
return this[b.substring(0, b.length-2)]()
} else {
console.log(this[b.trim()], '这是要替换的变量')
return this[