React, Vue3, Svelte three front-end framework syntax competition

ac8489dfa71289124e4c88d772e8481f.jpeg

f9c1192839ddd736a456ae1347d95f97.jpeg

React、Vue3、Svelte This article will compare the usage differences of the three popular components in terms of responsiveness, templates, life cycle, components, forms, and network requests  .

Reactive - state

React

import { useState } from "react";

export default function Name() {
  const [name] = useState("ConardLi");

  return <h1>Hello {name}</h1>;
}

View 3

<script setup>
import { ref } from "vue";
const name = ref("ConardLi");
</script>

<template>
  <h1>Hello {
    
    { name }}</h1>
</template>

Svelte

<script>
  let name = "ConardLi";
</script>

<h1>Hello {name}</h1>

Reactive - update status

React

import { useState } from "react";

export default function Name() {
  const [name, setName] = useState("ConardLi");
  setName("Jane");

  return <h1>Hello {name}</h1>;
}

View 3

<script setup>
import { ref } from "vue";
const name = ref("ConardLi");
name.value = "Jane";
</script>

<template>
  <h1>Hello {
    
    { name }}</h1>
</template>

Svelte

<script>
  let name = "ConardLi";
  name = "Jane";
</script>

<h1>Hello {name}</h1>

Reactive - State Computing

React

import { useState } from "react";

export default function DoubleCount() {
  const [count] = useState(10);
  const doubleCount = count * 2;

  return <div>{doubleCount}</div>;
}

View 3

<script setup>
import { ref, computed } from "vue";
const count = ref(10);
const doubleCount = computed(() => count.value * 2);
</script>

<template>
  <div>{
    
    { doubleCount }}</div>
</template>

Svelte

<script>
  let count = 10;
  $: doubleCount = count * 2;
</script>

<div>{doubleCount}</div>

template - minimal template

React

export default function HelloWorld() {
  return <h1>你好 code秘密花园</h1>;
}

View 3

<template>
  <h1>你好 code秘密花园</h1>
</template>

Svelte

<h1>你好 code秘密花园</h1>

template - style

React

import "./style.css";

export default function CssStyle() {
  return (
    <>
      <h1 className="title">I am red</h1>
      <button style={
    
    { fontSize: "17rem" }}>I am a button</button>
    </>
  );
}

View 3

<template>
  <h1 class="title">
    I am red
  </h1>
  <button style="font-size: 17rem">
    I am a button
  </button>
</template>

<style scoped>
.title {
  color: red;
}
</style>

Svelte

<h1 class="title">I am red</h1>
<button style="font-size: 17rem;">I am a button</button>

<style>
  .title {
    color: red;
  }
</style>

template-loop

React

export default function Colors() {
  const colors = ["red", "green", "blue"];
  return (
    <ul>
      {colors.map((color) => (
        <li key={color}>{color}</li>
      ))}
    </ul>
  );
}

View 3

<script setup>
const colors = ["red", "green", "blue"];
</script>

<template>
  <ul>
    <li
      v-for="color in colors"
      :key="color"
    >
      {
    
    { color }}
    </li>
  </ul>
</template>

Svelte

<script>
  const colors = ["red", "green", "blue"];
</script>

<ul>
  {#each colors as color}
    <li>{color}</li>
  {/each}
</ul>

Template - Event

React

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  function incrementCount() {
    setCount((count) => count + 17);
  }

  return (
    <>
      <p>Counter: {count}</p>
      <button onClick={incrementCount}>+17</button>
    </>
  );
}

View 3

<script setup>
import { ref } from "vue";
const count = ref(0);

function incrementCount() {
  count.value+=17;
}
</script>

<template>
  <p>Counter: {
    
    { count }}</p>
  <button @click="incrementCount">
    +17
  </button>
</template>

Svelte

<script>
  let count = 17;

  function incrementCount() {
    count++;
  }
</script>

<p>Counter: {count}</p>
<button on:click={incrementCount}>+1</button>

Template - Dom ref

React

import { useEffect, useRef } from "react";

export default function InputFocused() {
  const inputElement = useRef(null);

  useEffect(() => inputElement.current.focus(), []);

  return <input type="text" ref={inputElement} />;
}

View 3

<script setup>
import { ref, onMounted } from "vue";

const inputElement = ref();

onMounted(() => {
  inputElement.value.focus();
});
</script>

<template>
  <input ref="inputElement">
</template>

Svelte

<script>
  import { onMount } from "svelte";

  let inputElement;

  onMount(() => {
    inputElement.focus();
  });
</script>

<input bind:this={inputElement} />

Template - conditional judgment

React

import { useState } from "react";

const TRAFFIC_LIGHTS = ["red", "orange", "green"];

export default function TrafficLight() {
  const [lightIndex, setLightIndex] = useState(0);

  const light = TRAFFIC_LIGHTS[lightIndex];

  function nextLight() {
    if (lightIndex + 1 > TRAFFIC_LIGHTS.length - 1) {
      setLightIndex(0);
    } else {
      setLightIndex(lightIndex + 1);
    }
  }

  return (
    <>
      <button onClick={nextLight}>Next light</button>
      <p>Light is: {light}</p>
      <p>
        You must
        {light === "red" && <span>STOP</span>}
        {light === "orange" && <span>SLOW DOWN</span>}
        {light === "green" && <span>GO</span>}
      </p>
    </>
  );
}

View 3

<script setup>
import { ref, computed } from "vue";
const TRAFFIC_LIGHTS = ["red", "orange", "green"];
const lightIndex = ref(0);

const light = computed(() => TRAFFIC_LIGHTS[lightIndex.value]);

function nextLight() {
  if (lightIndex.value + 1 > TRAFFIC_LIGHTS.length - 1) {
    lightIndex.value = 0;
  } else {
    lightIndex.value++;
  }
}
</script>

<template>
  <button @click="nextLight">
    Next light
  </button>
  <p>Light is: {
    
    { light }}</p>
  <p>
    You must
    <span v-if="light === 'red'">STOP</span>
    <span v-else-if="light === 'orange'">SLOW DOWN</span>
    <span v-else-if="light === 'green'">GO</span>
  </p>
</template>

Svelte

<script>
  const TRAFFIC_LIGHTS = ["red", "orange", "green"];
  let lightIndex = 0;

  $: light = TRAFFIC_LIGHTS[lightIndex];

  function nextLight() {
    if (lightIndex + 1 > TRAFFIC_LIGHTS.length - 1) {
      lightIndex = 0;
    } else {
      lightIndex++;
    }
  }
</script>

<button on:click={nextLight}>Next light</button>
<p>Light is: {light}</p>
<p>
  You must
  {#if light === "red"}
    <span>STOP</span>
  {:else if light === "orange"}
    <span>SLOW DOWN</span>
  {:else if light === "green"}
    <span>GO</span>
  {/if}
</p>

Lifecycle - Initialization

React

import { useState, useEffect } from "react";

export default function PageTitle() {
  const [pageTitle, setPageTitle] = useState("");

  useEffect(() => {
    setPageTitle(document.title);
  }, []);

  return <p>Page title: {pageTitle}</p>;
}

View 3

<script setup>
import { ref, onMounted } from "vue";
const pageTitle = ref("");
onMounted(() => {
  pageTitle.value = document.title;
});
</script>

<template>
  <p>Page title: {
    
    { pageTitle }}</p>
</template>

Svelte

<script>
  import { onMount } from "svelte";
  let pageTitle = "";
  onMount(() => {
    pageTitle = document.title;
  });
</script>

<p>Page title is: {pageTitle}</p>

Lifecycle - Uninstall

React

import { useState, useEffect } from "react";

export default function Time() {
  const [time, setTime] = useState(new Date().toLocaleTimeString());

  useEffect(() => {
    const timer = setInterval(() => {
      setTime(new Date().toLocaleTimeString());
    }, 1000);

    return () => {
      clearInterval(timer);
    };
  }, []);

  return <p>Current time: {time}</p>;
}

View 3

<script setup>
import { ref, onUnmounted } from "vue";

const time = ref(new Date().toLocaleTimeString());

const timer = setInterval(() => {
  time.value = new Date().toLocaleTimeString();
}, 1000);

onUnmounted(() => {
  clearInterval(timer);
});
</script>

<template>
  <p>Current time: {
    
    { time }}</p>
</template>

Svelte

<script>
  import { onDestroy } from "svelte";

  let time = new Date().toLocaleTimeString();

  const timer = setInterval(() => {
    time = new Date().toLocaleTimeString();
  }, 1000);

  onDestroy(() => clearInterval(timer));
</script>

<p>Current time: {time}</p>

Components - Props

React

App.jsx

import UserProfile from "./UserProfile.jsx";

export default function App() {
  return (
    <UserProfile
      name="ConardLi"
      age={17}
      favouriteColors={["green", "blue", "red"]}
      isAvailable
    />
  );
}

UserProfile.jsx

import PropTypes from "prop-types";

export default function UserProfile({
  name = "",
  age = null,
  favouriteColors = [],
  isAvailable = false,
}) {
  return (
    <>
      <p>My name is {name}!</p>
      <p>My age is {age}!</p>
      <p>My favourite colors are {favouriteColors.join(", ")}!</p>
      <p>I am {isAvailable ? "available" : "not available"}</p>
    </>
  );
}

UserProfile.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
  favouriteColors: PropTypes.arrayOf(PropTypes.string).isRequired,
  isAvailable: PropTypes.bool.isRequired,
};

View 3

app.vue

<script setup>
import UserProfile from "./UserProfile.vue";
</script>

<template>
  <UserProfile
    name="ConardLi"
    :age="17"
    :favourite-colors="['green', 'blue', 'red']"
    is-available
  />
</template>

UserProfile.vue

<script setup>
const props = defineProps({
  name: {
    type: String,
    required: true,
    default: "",
  },
  age: {
    type: Number,
    required: true,
    default: null,
  },
  favouriteColors: {
    type: Array,
    required: true,
    default: () => [],
  },
  isAvailable: {
    type: Boolean,
    required: true,
    default: false,
  },
});
</script>

<template>
  <p>My name is {
    
    { props.name }}!</p>
  <p>My age is {
    
    { props.age }}!</p>
  <p>My favourite colors are {
    
    { props.favouriteColors.join(", ") }}!</p>
  <p>I am {
    
    { props.isAvailable ? "available" : "not available" }}</p>
</template>

Svelte

App.svelte

<script>
  import UserProfile from "./UserProfile.svelte";
</script>

<UserProfile
  name="ConardLi"
  age={17}
  favouriteColors={["green", "blue", "red"]}
  isAvailable
/>

UserProfile.svelte

<script>
  export let name = "";
  export let age = null;
  export let favouriteColors = [];
  export let isAvailable = false;
</script>

<p>My name is {name}!</p>
<p>My age is {age}!</p>
<p>My favourite colors are {favouriteColors.join(", ")}!</p>
<p>I am {isAvailable ? "available" : "not available"}</p>

Form - text box

React

import { useState } from "react";

export default function InputHello() {
  const [text, setText] = useState("你好 code秘密花园");

  function handleChange(event) {
    setText(event.target.value);
  }

  return (
    <>
      <p>{text}</p>
      <input value={text} onChange={handleChange} />
    </>
  );
}

View 3

<script setup>
import { ref } from "vue";
const text = ref("Hello World");
</script>

<template>
  <p>{
    
    { text }}</p>
  <input v-model="text">
</template>

Svelte

<script>
  let text = "Hello World";
</script>

<p>{text}</p>
<input bind:value={text} />

Form - checkbox

React

import { useState } from "react";

export default function IsAvailable() {
  const [isAvailable, setIsAvailable] = useState(false);

  function handleChange() {
    setIsAvailable(!isAvailable);
  }

  return (
    <>
      <input
        id="is-available"
        type="checkbox"
        checked={isAvailable}
        onChange={handleChange}
      />
      <label htmlFor="is-available">Is available</label>
    </>
  );
}

View 3

<script setup>
import { ref } from "vue";

const isAvailable = ref(true);
</script>

<template>
  <input
    id="is-available"
    v-model="isAvailable"
    type="checkbox"
  >
  <label for="is-available">Is available</label>
</template>

Svelte

<script>
  let isAvailable = false;
</script>

<input id="is-available" type="checkbox" bind:checked={isAvailable} />
<label for="is-available">Is available</label>

Form - Radio

React

import { useState } from "react";

export default function PickPill() {
  const [picked, setPicked] = useState("red");

  function handleChange(event) {
    setPicked(event.target.value);
  }

  return (
    <>
      <div>Picked: {picked}</div>

      <input
        id="blue-pill"
        checked={picked === "blue"}
        type="radio"
        value="blue"
        onChange={handleChange}
      />
      <label htmlFor="blue-pill">Blue pill</label>

      <input
        id="red-pill"
        checked={picked === "red"}
        type="radio"
        value="red"
        onChange={handleChange}
      />
      <label htmlFor="red-pill">Red pill</label>
    </>
  );
}

View 3

<script setup>
import { ref } from "vue";

const picked = ref("red");
</script>

<template>
  <div>Picked: {
    
    { picked }}</div>

  <input
    id="blue-pill"
    v-model="picked"
    type="radio"
    value="blue"
  >
  <label for="blue-pill">Blue pill</label>

  <input
    id="red-pill"
    v-model="picked"
    type="radio"
    value="red"
  >
  <label for="red-pill">Red pill</label>
</template>

Svelte

<script>
  let picked = "red";
</script>

<div>Picked: {picked}</div>

<input id="blue-pill" bind:group={picked} type="radio" value="blue" />
<label for="blue-pill">Blue pill</label>

<input id="red-pill" bind:group={picked} type="radio" value="red" />
<label for="red-pill">Red pill</label>

Form - Select

React

import { useState } from "react";

const colors = [
  { id: 1, text: "red" },
  { id: 2, text: "blue" },
  { id: 3, text: "green" },
  { id: 4, text: "gray", isDisabled: true },
];

export default function ColorSelect() {
  const [selectedColorId, setSelectedColorId] = useState(2);

  function handleChange(event) {
    setSelectedColorId(event.target.value);
  }

  return (
    <select value={selectedColorId} onChange={handleChange}>
      {colors.map((color) => (
        <option key={color.id} value={color.id} disabled={color.isDisabled}>
          {color.text}
        </option>
      ))}
    </select>
  );
}

View 3

<script setup>
import { ref } from "vue";

const selectedColorId = ref(2);

const colors = [
  { id: 1, text: "red" },
  { id: 2, text: "blue" },
  { id: 3, text: "green" },
  { id: 4, text: "gray", isDisabled: true },
];
</script>

<template>
  <select v-model="selectedColorId">
    <option
      v-for="color in colors"
      :key="color.id"
      :value="color.id"
      :disabled="color.isDisabled"
    >
      {
    
    { color.text }}
    </option>
  </select>
</template>

Svelte

<script>
  let selectedColorId = 2;

  const colors = [
    { id: 1, text: "red" },
    { id: 2, text: "blue" },
    { id: 3, text: "green" },
    { id: 4, text: "gray", isDisabled: true },
  ];
</script>

<select bind:value={selectedColorId}>
  {#each colors as color}
    <option value={color.id} disabled={color.isDisabled}>
      {color.text}
    </option>
  {/each}
</select>

Web App - Rendering

React

index.html

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
    <script type="module" src="./main.jsx"></script>
  </body>
</html>

App.jsx

export default function App() {
  return <h1>你好 code秘密花园</h1>;
}

Main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

ReactDOM.createRoot(document.getElementById("app")).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

View 3

index.html

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
    <script type="module" src="./main.js"></script>
  </body>
</html>

app.vue

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
    <script type="module" src="./main.js"></script>
  </body>
</html>

main.js

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

Svelte

index.html

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
    <script type="module" src="./app.js"></script>
  </body>
</html>

App.js

import App from "./App.svelte";

const app = new App({
  target: document.getElementById("app"),
});

export default app;

App.svelte

<h1>你好 code秘密花园</h1>

Web Application - Get Data

React

App.jsx

import useFetchUsers from "./useFetchUsers";

export default function App() {
  const { isLoading, error, data: users } = useFetchUsers();

  return (
    <>
      {isLoading ? (
        <p>Fetching users...</p>
      ) : error ? (
        <p>An error occured while fetching users</p>
      ) : (
        users && (
          <ul>
            {users.map((user) => (
              <li key={user.login.uuid}>
                <img src={user.picture.thumbnail} alt="user" />
                <p>
                  {user.name.first} {user.name.last}
                </p>
              </li>
            ))}
          </ul>
        )
      )}
    </>
  );
}

useFetchUsers.js

import { useEffect, useState } from "react";

export default function useFetchUsers() {
  const [data, setData] = useState();
  const [error, setError] = useState();
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    async function fetchData() {
      setIsLoading(true);
      try {
        const response = await fetch("https://conardli.top/api/?results=3");
        const { results: users } = await response.json();
        setData(users);
        setError();
      } catch (err) {
        setData();
        setError(err);
      }
      setIsLoading(false);
    }
    fetchData();
  }, []);

  return { isLoading, error, data };
}

View 3

app.vue

<script setup>
import useFetchUsers from "./useFetchUsers";

const { isLoading, error, data: users } = useFetchUsers();
</script>

<template>
  <p v-if="isLoading">
    Fetching users...
  </p>
  <p v-else-if="error">
    An error ocurred while fetching users
  </p>
  <ul v-else-if="users">
    <li
      v-for="user in users"
      :key="user.login.uuid"
    >
      <img
        :src="user.picture.thumbnail"
        alt="user"
      >
      <p>
        {
    
    { user.name.first }}
        {
    
    { user.name.last }}
      </p>
    </li>
  </ul>
</template>

useFetchUsers.js

import { ref } from "vue";

export default function useFetchUsers() {
  const data = ref();
  const error = ref();
  const isLoading = ref(false);

  async function fetchData() {
    isLoading.value = true;
    try {
      const response = await fetch("https://conardli.top/api/?results=3");
      const { results: users } = await response.json();
      data.value = users;
      error.value = undefined;
    } catch (err) {
      data.value = undefined;
      error.value = err;
    }
    isLoading.value = false;
  }
  fetchData();

  return { isLoading, error, data };
}

Svelte

App.svelte

<script>
  import useFetchUsers from "./useFetchUsers";

  const { isLoading, error, data: users } = useFetchUsers();
</script>

{#if $isLoading}
  <p>Fetching users...</p>
{:else if $error}
  <p>An error occured while fetching users</p>
{:else if $users}
  <ul>
    {#each $users as user}
      <li>
        <img src={user.picture.thumbnail} alt="user" />
        <p>
          {user.name.first}
          {user.name.last}
        </p>
      </li>
    {/each}
  </ul>
{/if}

useFetchUsers.js

import { writable } from "svelte/store";

export default function useFetchUsers() {
  const data = writable();
  const error = writable();
  const isLoading = writable(false);

  async function fetchData() {
    isLoading.set(true);
    try {
      const response = await fetch("https://conardli.top/api/?results=3");
      const { results: users } = await response.json();
      data.set(users);
      error.set();
    } catch (err) {
      data.set();
      error.set(err);
    }
    isLoading.set(false);
  }
  fetchData();

  return { isLoading, error, data };
}

Web Application - Routing Links

React

import Link from "next/link";

export default function Home() {
  return (
    <ul>
      <li>
        <Link href="/">Home</Link>
      </li>
      <li>
        <Link href="/about">About us</Link>
      </li>
    </ul>
  );
}

View 3

<template>
  <ul>
    <li>
      <NuxtLink to="/"> Home </NuxtLink>
    </li>
    <li>
      <NuxtLink to="/about"> About us </NuxtLink>
    </li>
  </ul>
</template>

Svelte

<ul>
  <li>
    <a href="/">Home</a>
  </li>
  <li>
    <a href="/about">About us</a>
  </li>
</ul>

Web Application - Routing

React

NextJS

|-- pages/
    |-- index.js // index page "/"
    |-- about.js // about page "/about"
    |-- 404.js // handle error HTTP 404 page not found
    |-- 500.js // handle error HTTP 500
    |-- _app.js // global app layout

View 3

Nuxt 3

|-- pages/
    |-- index.vue // index page "/"
    |-- about.vue // about page "/about"

Svelte

SvelteKit

|-- routes/
    |-- +page.svelte // index page "/"
    |-- about/
        |-- +page.svelte // about page "/about"
    |-- +error.svelte // handle HTTP errors 404, 500,...
    |-- +layout.svelte // global app layout

at last

Which one do you find most comfortable to use? Welcome to leave a message in the comment area!

Reference: https://component-party.dev/

Guess you like

Origin blog.csdn.net/Ed7zgeE9X/article/details/131820343