Skip to content

Latest commit

 

History

History
376 lines (315 loc) · 8.23 KB

slides.md

File metadata and controls

376 lines (315 loc) · 8.23 KB
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)
persist

Why are there JS frameworks?

Presentation slides for developers
By: Nasr Galal
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>

Modern front-end?

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>

layout: two-cols clicks: 8

SPA Routing (JS)

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>
Home Component
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>
    `;
  }
};
<style> .footnotes-sep { @apply mt-20 opacity-10; } .footnotes { @apply text-sm opacity-75; } .footnote-backref { display: none; } </style>

SPA routing result

// 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%" />

layout: two-cols clicks: 4

vDOM

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

layout: center clicks: 11

The Mount

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::

meow


layout: center preload: false

Presentation Powered by

Slidev
<script setup lang="ts"> const final = { x: 0, y: 0, rotate: 0, scale: 1, transition: { type: 'spring', damping: 10, stiffness: 20, mass: 2 } } </script>