JSFiddle - React, Tailwind, and code Playground
by nerdycap007
HTML
<div id="app">
<h1>Enter your message in the box</h1>
<p id="message"></p><br>
<input id="messageInput" placeholder="Enter message"
oninput="methods.changeMessage()" />
</div>
CSS
#app {
padding: 20px;
}
h1 {
font-size: 20px;
}
JavaScript
let data = {
message: ""
}
let methods = {
changeMessage: function() {
data.message = document.getElementById("messageInput").value;
}
}
// Code that has to run when a
// reactive property changes it's value.
let target = null
class Dep {
constructor() {
this.subscribers = []
}
depend() {
// Saves target function into subscribers array
if (target && !this.subscribers.includes(target)) {
this.subscribers.push(target);
}
}
notify() {
// Replays target functions saved in the subscribers array
this.subscribers.forEach(sub => sub());
}
}
Object.keys(data).forEach(key => {
let internalValue = data[key]
// Each property gets a dependency instance
const dep = new Dep()
Object.defineProperty(data, key, {
get() {
console.log(`Getting value, ${internalValue}`)
dep.depend() // Saves the target function into the subscribers array
return internalValue
},
set(newVal) {
console.log(`Setting the internalValue to ${newVal}`)
internalValue = newVal
dep.notify() // Reruns saved target functions in the subscribers array
}
})
})
let renderFunction = () => {
// Function that renders HTML code.
document.getElementById("message").innerHTML = data.message;
}
let watcher = function(func) {
// Here, a watcher is a function that encapsulates the code
// that needs to recorded/watched.
// PS: It just runs once, because after that, the target code is stored
// in the subscriber's list of the Dep() instance.
target = func // Then it assigns the function to target
target() // Run the target function
target = null // Reset target to null
}
watcher(renderFunction)