-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2d0969d
Showing
12 changed files
with
6,287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "vue-lite", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"build": "webpack", | ||
"dev": "webpack serve --open" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"devDependencies": { | ||
"webpack": "^5.73.0", | ||
"webpack-cli": "^4.10.0", | ||
"webpack-dev-server": "^4.9.3" | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html lang="ch"> | ||
<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>vue-lite-dev</title> | ||
<script src="./vue-lite.js"></script> | ||
</head> | ||
<body> | ||
<h1>hello vue-lite</h1> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { ref } from "./reactive/ref"; | ||
import { effect } from "./reactive/effect"; | ||
import { computed } from "./reactive/computed"; | ||
|
||
const num = window.num = ref(0); | ||
const c = window.c = computed({ | ||
get(){ | ||
return num.value * 2; | ||
}, | ||
set(newVal){ | ||
num.value = newVal / 2; | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { isFunction } from "../utils"; | ||
import { effect, track, trigger } from "./effect"; | ||
|
||
export function computed(getterOrOption) { | ||
let getter, setter; | ||
if(isFunction(getterOrOption)){ | ||
getter = getterOrOption; | ||
setter = () => { | ||
console.warn('computed is readonly'); | ||
} | ||
} | ||
else{ | ||
getter = getterOrOption.get; | ||
setter = getterOrOption.set; | ||
} | ||
return new ComputedImpl(getter, setter); | ||
} | ||
|
||
class ComputedImpl { | ||
constructor(getter, setter) { | ||
this._value = undefined; | ||
this._dirty = true; | ||
this.setter = setter; | ||
this.effect = effect(getter, { | ||
lazy: true, | ||
scheduler: () => { | ||
this._dirty = true; | ||
trigger(this, 'value'); | ||
} | ||
}); // accept effectFn | ||
} | ||
|
||
get value() { | ||
if (this._dirty) { | ||
this._value = this.effect(); // first time | ||
this._dirty = false; | ||
track(this, 'value'); | ||
} | ||
return this._value; | ||
} | ||
|
||
set value(newVal) { | ||
this.setter(newVal); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const effectFnStack = []; | ||
let activeEffectFn = null; | ||
|
||
export function effect(fn, options = {}) { | ||
const effectFn = () => { | ||
try { | ||
effectFnStack.push(effectFn); | ||
activeEffectFn = effectFn; | ||
return fn() | ||
} finally { | ||
effectFnStack.pop(); | ||
activeEffectFn = effectFnStack[effectFnStack.length - 1]; | ||
} | ||
} | ||
|
||
if (!options.lazy) { | ||
effectFn(); | ||
} | ||
|
||
effectFn.scheduler = options.scheduler; | ||
|
||
return effectFn; | ||
} | ||
|
||
// effectFn 存储 | ||
const effectMap = new WeakMap(); | ||
|
||
// effect 捕获器 | ||
export function track(target, property) { | ||
|
||
if (!activeEffectFn) { | ||
return | ||
} | ||
|
||
let depsMap = effectMap.get(target); | ||
if (!depsMap) { | ||
effectMap.set(target, (depsMap = new Map())); | ||
} | ||
|
||
let deps = depsMap.get(property); | ||
if (!deps) { | ||
depsMap.set(property, (deps = new Set())); | ||
} | ||
|
||
deps.add(activeEffectFn); | ||
} | ||
|
||
// effect 触发器 | ||
export function trigger(target, property) { | ||
const depsMap = effectMap.get(target); | ||
if (!depsMap) return; | ||
|
||
const deps = depsMap.get(property); | ||
if (!deps) return; | ||
|
||
deps.forEach(effectFn => { | ||
if (effectFn.scheduler) { | ||
effectFn.scheduler(); | ||
} | ||
else { | ||
effectFn() | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { isObject, hasChanged, isArray } from "../utils"; | ||
import { track, trigger } from "./effect"; | ||
|
||
const proxyMap = new WeakMap(); | ||
|
||
export function reactive(target){ | ||
if(!isObject(target)){ | ||
return target; | ||
} | ||
|
||
if(isReactive(target)){ | ||
return target; | ||
} | ||
|
||
if(proxyMap.has(target)){ | ||
return proxyMap.get(target); | ||
} | ||
|
||
const proxy = new Proxy(target, { | ||
get(target, property){ | ||
if(property === '__isReactive'){ | ||
return true; | ||
} | ||
const res = Reflect.get(...arguments); | ||
track(target, property); | ||
|
||
return isObject(res) ? reactive(res) : res; | ||
}, | ||
|
||
set(target, property, value){ | ||
const oldVal = target[property]; | ||
const oldLength = target.length; | ||
const res = Reflect.set(...arguments); | ||
if(hasChanged(oldVal, value)){ | ||
trigger(target, property); | ||
} | ||
if(isArray(target) && hasChanged(oldLength, target.length)){ | ||
trigger(target, 'length'); | ||
} | ||
return res | ||
} | ||
}) | ||
|
||
proxyMap.set(target, proxy); | ||
return proxy; | ||
} | ||
|
||
export function isReactive(target){ | ||
return !!(target && target.__isReactive); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { hasChanged, isObject } from "../utils"; | ||
import { track, trigger } from "./effect"; | ||
import { reactive } from "./reactive"; | ||
|
||
export function ref(value) { | ||
if(isRef(value)){ | ||
return value; | ||
} | ||
return new RefImpl(value); | ||
} | ||
|
||
export function isRef(value) { | ||
return !!(value && value.__isRef); | ||
} | ||
|
||
class RefImpl { | ||
constructor(value) { | ||
this.__isRef = true; | ||
this._value = convert(value); | ||
} | ||
|
||
get value() { | ||
track(this, 'value'); | ||
return this._value; | ||
} | ||
|
||
set value(newVal) { | ||
if(hasChanged(newVal, this._value)){ | ||
this._value = convert(newVal); | ||
trigger(this, 'value'); | ||
} | ||
} | ||
} | ||
|
||
function convert(value) { | ||
return isObject(value) ? reactive(value) : value; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export function isObject(target){ | ||
return typeof target === 'object' && target !== null; | ||
} | ||
|
||
export function hasChanged(oldVal, val){ | ||
return oldVal !== val && !(Number.isNaN(oldVal) && Number.isNaN(val)); | ||
} | ||
|
||
export function isArray(target){ | ||
return Array.isArray(target); | ||
} | ||
|
||
export function isFunction(target){ | ||
return typeof target === 'function'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const path = require('path'); | ||
|
||
module.exports = { | ||
mode: 'development', | ||
entry: './src/index.js', | ||
output: { | ||
filename: 'vue-lite.js', | ||
path: path.resolve(__dirname, 'dist'), | ||
clean: true | ||
}, | ||
devServer:{ | ||
static:{ | ||
directory: path.join(__dirname, 'src/examples'), | ||
}, | ||
compress: true, | ||
port: 9000 | ||
} | ||
} |