React、Vue3、Svelte 写法大 PK

原文来源于:程序员成长指北;作者:ConardLi

如有侵权,联系删除

大家好,我是 考拉。

React、Vue3、Svelte 写法大 PK_第1张图片

本文将会从响应式、模板、生命周期、组件、表单、网络请求等几个方面,来对比 React、Vue3、Svelte 三大流行组件的用法区别。

响应式 - 状态

React

import { useState } from "react";

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

  return 

Hello {name}

; }

Vue3


import { ref } from "vue";
const name = ref("ConardLi");



Svelte



Hello {name}

响应式 - 更新状态

React

import { useState } from "react";

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

  return 

Hello {name}

; }

Vue3


import { ref } from "vue";
const name = ref("ConardLi");
name.value = "Jane";



Svelte



Hello {name}

响应式 - 状态计算

React

import { useState } from "react";

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

  return 
{doubleCount}
; }

Vue3


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



Svelte



{doubleCount}

模板 - 最小模板

React

export default function HelloWorld() {
  return 

你好 code秘密花园

; }

Vue3


Svelte

你好 code秘密花园

模板 - 样式

React

import "./style.css";

export default function CssStyle() {
  return (
    <>
      I am red
      I am a button
    
  );
}

Vue3




.title {
  color: red;
}

Svelte

I am red
I am a button


模板 - 循环

React

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

Vue3


const colors = ["red", "green", "blue"];



Svelte



      {#each colors as color}     
  • {color}
  •   {/each}

模板 - 事件

React

import { useState } from "react";

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

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

  return (
    <>
      

Counter: {count}

      +17        ); }

Vue3


import { ref } from "vue";
const count = ref(0);

function incrementCount() {
  count.value+=17;
}



Svelte



Counter: {count}

+1

模板 - Dom ref

React

import { useEffect, useRef } from "react";

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

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

  return ;
}

Vue3


import { ref, onMounted } from "vue";

const inputElement = ref();

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



Svelte




模板 - 条件判断

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 (
    <>
      Next light
      

Light is: {light}

      

        You must         {light === "red" && STOP}         {light === "orange" && SLOW DOWN}         {light === "green" && GO}       

       ); }

Vue3


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++;
  }
}



Svelte



Next light

Light is: {light}

  You must   {#if light === "red"}     STOP   {:else if light === "orange"}     SLOW DOWN   {:else if light === "green"}     GO   {/if}

生命周期 - 初始化

React

import { useState, useEffect } from "react";

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

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

  return 

Page title: {pageTitle}

; }

Vue3


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



Svelte



Page title is: {pageTitle}

生命周期 - 卸载

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 

Current time: {time}

; }

Vue3


import { ref, onUnmounted } from "vue";

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

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

onUnmounted(() => {
  clearInterval(timer);
});



Svelte



Current time: {time}

组件 - Props

React

App.jsx

import UserProfile from "./UserProfile.jsx";

export default function App() {
  return (
    
  );
}

UserProfile.jsx

import PropTypes from "prop-types";

export default function UserProfile({
  name = "",
  age = null,
  favouriteColors = [],
  isAvailable = false,
}) {
  return (
    <>
      

My name is {name}!

      

My age is {age}!

      

My favourite colors are {favouriteColors.join(", ")}!

      

I am {isAvailable ? "available" : "not available"}

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

Vue3

App.vue


import UserProfile from "./UserProfile.vue";



UserProfile.vue


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,
  },
});



Svelte

App.svelte




UserProfile.svelte



My name is {name}!

My age is {age}!

My favourite colors are {favouriteColors.join(", ")}!

I am {isAvailable ? "available" : "not available"}

表单 - 文本框

React

import { useState } from "react";

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

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

  return (
    <>
      

{text}

              ); }

Vue3


import { ref } from "vue";
const text = ref("Hello World");



Svelte



{text}

表单 - 复选框

React

import { useState } from "react";

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

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

  return (
    <>
      
      Is available
    
  );
}

Vue3


import { ref } from "vue";

const isAvailable = ref(true);



Svelte




Is available

表单 - Radio

React

import { useState } from "react";

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

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

  return (
    <>
      
Picked: {picked}
             Blue pill              Red pill        ); }

Vue3


import { ref } from "vue";

const picked = ref("red");



Svelte



Picked: {picked}
Blue pill Red pill

表单 - 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 (
    
      {colors.map((color) => (
        
          {color.text}
        
      ))}
    
  );
}

Vue3


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 },
];



Svelte




  {#each colors as color}
    
      {color.text}
    
  {/each}

Web 应用 - 渲染

React

index.html



  
    
       

App.jsx

export default function App() {
  return 

你好 code秘密花园

; }

Main.jsx

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

ReactDOM.createRoot(document.getElementById("app")).render(
  
    
  
);

Vue3

index.html



  
    
       

App.vue



  
    
       

main.js

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

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

Svelte

index.html



  
    
       

App.js

import App from "./App.svelte";

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

export default app;

App.svelte

你好 code秘密花园

Web 应用 - 获取数据

React

App.jsx

import useFetchUsers from "./useFetchUsers";

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

  return (
    <>
      {isLoading ? (
        

Fetching users...

      ) : error ? (         

An error occured while fetching users

      ) : (         users && (           
                {users.map((user) => (                                                 

                      {user.name.first} {user.name.last}                 

                               ))}           
        )       )}        ); }

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 };
}

Vue3

App.vue


import useFetchUsers from "./useFetchUsers";

const { isLoading, error, data: users } = useFetchUsers();



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



{#if $isLoading}
  

Fetching users...

{:else if $error}   

An error occured while fetching users

{:else if $users}   
        {#each $users as user}       
  •                  

              {user.name.first}           {user.name.last}         

          
  •     {/each}   
{/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 应用 - 路由链接

React

import Link from "next/link";

export default function Home() {
  return (
    
          
  •         Home       
  •       
  •         About us       
  •     
  ); }

Vue3


Svelte

      
  •     Home   
  •   
  •     About us   

Web 应用 - 路由

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

Vue3

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

你可能感兴趣的:(react.js,vue.js,javascript)