theme | background | class | highlighter | lineNumbers | info | drawings | |
---|---|---|---|---|---|---|---|
seriph |
text-center bg-blend-darken |
shiki |
true |
## Slidev Starter Template
Presentation slides for developers.
Learn more at [Sli.dev](https://sli.dev)
|
|
Press Space for next page
<script setup lang="ts">
const final = {
x: 0,
y: 0,
rotate: 0,
scale: 1,
opacity: 1,
transition: {
delay: 100,
duration: 1000,
}
}
</script>
To create a web app nowadays, the concept became more complicated. We, the developers must follow the standards of SPA, SSR, routing and navigation, performance, .... etc
That's why the idea of creating a framework came up! let's explore the following features:
- 📝 Hot Module Replacement (HMR) - Auto-reflects the DOM changes and updates.
- 🎨 Component design pattern (component system) - Helps for the separation of concerns during development process
- 🧑💻 Single Page Application (SPA) Routing - consumes the browser router API for faster and efficient navigation
- 🤹 Large scale state management - For handling the data inputs and outputs in a single place and achieve client side data persistence
- 📤 Build system - For scaffolding the app for production version
<style> h1 { background-color: #2B90B6; background-image: linear-gradient(45deg, #4EC5D4 10%, #146b8c 20%); background-size: 100%; -webkit-background-clip: text; -moz-background-clip: text; -webkit-text-fill-color: transparent; -moz-text-fill-color: transparent; } </style>
HTML
<section id="app" class="card"></section>
<nav>
<a href="#/">Home</a> -
<a href="#/page1">Page 1</a> -
<a href="#/page2">Page 2</a> -
</nav>
const HomeComponent = {
render: () => {
return `
<section>
<h1>Home</h1>
<p>This is Home page</p>
</section>
`;
}
};
::right::
const Page1Component = {
render: () => {
return `
<section>
<h1>Page 1</h1>
<p>This is Page 1</p>
</section>
`;
}
};
const Page2Component = {
render: () => {
return `
<section>
<h1>Page 2</h1>
<p>This is Page 2</p>
</section>
`;
}
};
// Routes
const routes = [
{ path: "/", component: HomeComponent },
{ path: "/page1", component: Page1Component },
{ path: "/page2", component: Page2Component }
];
// Using Hash approach
const parseLocation = hash => hash.slice(1).toLowerCase() || "/";
const findComponentByPath = path =>
routes.find(r => r.path.match(new RegExp(`^\\${path}$`, "gm"))) || false;
const router = () => {
console.log(document.location)
const path = parseLocation(document.location.hash);
const { component = ErrorComponent } =
findComponentByPath(path, routes) || {};
document.getElementById("app").innerHTML = component.render();
};
window.addEventListener("hashchange", router);
window.addEventListener("load", router) || router();
<iframe src="https://codepen.io/nasr3090/full/KKdRJrQ" width="100%" height="100%" />
Our DOM
const vdom = h('div', { class: 'red' }, [
h('span', null, 'hello')
])
mount(vdom, document.getElementById('app'))
The render function
function h(tag, props, children) {
return { tag, props, children }
}
::right::
Mounting
function mount(vnode, container) {}
hello
function mount(vnode, container) {
const el = vnode.el = document.createElement(vnode.tag)
// Props
if (vnode.props) {
for (const key in vnode.props) {
const value = vnode.props[key]
// Assuming that all props are attributes for simplicity
el.setAttribute(key, value)
}
}
// Children
if (vnode.children) {
if (typeof vnode.children === 'string') {
el.textContent = vnode.children
} else {
vnode.children.forEach(child => {
mount(child, el)
})
}
}
container.appendChild(el)
}
::right::
<script setup lang="ts"> const final = { x: 0, y: 0, rotate: 0, scale: 1, transition: { type: 'spring', damping: 10, stiffness: 20, mass: 2 } } </script>