# Simple-MVVM
**Repository Path**: skyOg/simple-mvvm
## Basic Information
- **Project Name**: Simple-MVVM
- **Description**: 一个简易的MVVM框架
- **Primary Language**: TypeScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-01-25
- **Last Updated**: 2025-01-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: TypeScript
## README
# 一个简易的 MVVM 框架
基于 `vue3` 的响应式原理实现的一个简易的 `MVVM` 模型
- 基本示例

框架主要实现的几个部分:
- reactivity: 响应式数据 使用 proxy 数据代理实现数据劫持。
- compiler: 模板编译,这里没有将模板字符串转换成为`AST`,而是直接获取 Element 将其处理成 render 函数。
- vnode: 虚拟 dom, 用于 diff 过程。
- mount: 实例挂载,调用 compiler 处理模版得到 render 函数,处理 setup 得到数据。
## 使用方法
### 安装依赖
```
yarn install / npm install
```
### 打包构建
生成 `bundle.js`
```
yarn build / npm run build
```
打包构建后打开根目录 `instance.html`即可
或直接访问网址预览 **https://skynu.xyz/**
### 测试
```
yarn test / npm run test
```
## 快速使用
```js
// 项目打包后,新建 html 文件, 引入打包后的 bundle.js 文件
// 引入后,解构文件中的对象 (这里的对象名称定义为 simpleMVVM)
const { reactive, ref, createApp } = simpleMVVM;
// 支持引入的模块有: reactive, ref, createApp, effect, compile, createElement, createText
// 支持元素的原生属性和事件, 以及动态属性如 :value
// 原生事件如 click、mouseenter。。。 用 @ 开头
// 指令: 暂时仅支持 v-show, 其余指令事件待补充扩展
```
- reactive / ref 响应式数据
```js
const { reactive, ref } = simpleMVVM;
let data = reactive({
name: "hello",
});
let name = ref("world");
console.log(`${data.name} ${name.value}`)
```
- effect 监控数据变化
```js
const { reactive, ref, effect } = simpleMVVM;
let data = reactive({
title: "hello",
});
let name = ref("world");
effect(function () {
console.log(`${data.title} ${name.value}`); // hello world
});
data.title = "Hello"; //Hello world
name.value = "World"; //Hello World
```
- compile 模板编译
```html
```
```js
const { compile } = simpleMVVM;
let node = document.querySelector('#app');
console.log(compile(node));
```
- createElement / createText 生成虚拟dom
```js
const { createElement, createText } = simpleMVVM;
const vdom = createElement("div", {
attrs: { id: "app" },
event: { click: "handleClick" },
});
console.dir(vdom);
const vnode = createElement("div", {}, [
createElement("h1", { attrs: { class: "h1" } }),
]);
console.dir(vnode);
```
- createApp 创建实例 (setup语法)
```html
```
```js
const { reactive, ref, createApp } = simpleMVVM;
const vm = createApp({
setup() {
let number = ref('hello world');
let data = reactive({
count: 0
});
return {
number,
data,
change: (e) => void (number.value = e.target.value),
clickHandler: () => void (data.count += 1),
}
}
})
vm.mount('#app');
```
## 代码结构
### reactivity
#### 使用 `proxy` 实现 `reactive`
```js
const proxyedReactiveMap = new WeakMap();
export const reactive = function (target: object) {
if (!isObject(target)) return target;
if (proxyedReactiveMap.has(target)) return proxyedReactiveMap.get(target);
let handler: ProxyHandler