原文来源于:程序员成长指北;作者:ConardLi
如有侵权,联系删除
大家好,我是 考拉。
本文将会从响应式、模板、生命周期、组件、表单、网络请求等几个方面,来对比 React、Vue3、Svelte
三大流行组件的用法区别。
import { useState } from "react";
export default function Name() {
const [name] = useState("ConardLi");
return Hello {name}
;
}
Hello {{ name }}
Hello {name}
import { useState } from "react";
export default function Name() {
const [name, setName] = useState("ConardLi");
setName("Jane");
return Hello {name}
;
}
Hello {{ name }}
Hello {name}
import { useState } from "react";
export default function DoubleCount() {
const [count] = useState(10);
const doubleCount = count * 2;
return {doubleCount};
}
{{ doubleCount }}
{doubleCount}
export default function HelloWorld() {
return 你好 code秘密花园
;
}
你好 code秘密花园
你好 code秘密花园
import "./style.css";
export default function CssStyle() {
return (
<>
I am red
>
);
}
I am red
I am red
export default function Colors() {
const colors = ["red", "green", "blue"];
return (
{colors.map((color) => (
- {color}
))}
);
}
-
{{ color }}
{#each colors as color}
- {color}
{/each}
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
function incrementCount() {
setCount((count) => count + 17);
}
return (
<>
Counter: {count}
>
);
}
Counter: {{ count }}
Counter: {count}
import { useEffect, useRef } from "react";
export default function InputFocused() {
const inputElement = useRef(null);
useEffect(() => inputElement.current.focus(), []);
return ;
}
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 (
<>
Light is: {light}
You must
{light === "red" && STOP}
{light === "orange" && SLOW DOWN}
{light === "green" && GO}
>
);
}
Light is: {{ light }}
You must
STOP
SLOW DOWN
GO
Light is: {light}
You must
{#if light === "red"}
STOP
{:else if light === "orange"}
SLOW DOWN
{:else if light === "green"}
GO
{/if}
import { useState, useEffect } from "react";
export default function PageTitle() {
const [pageTitle, setPageTitle] = useState("");
useEffect(() => {
setPageTitle(document.title);
}, []);
return Page title: {pageTitle}
;
}
Page title: {{ pageTitle }}
Page title is: {pageTitle}
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}
;
}
Current time: {{ time }}
Current time: {time}
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,
};
App.vue
UserProfile.vue
My name is {{ props.name }}!
My age is {{ props.age }}!
My favourite colors are {{ props.favouriteColors.join(", ") }}!
I am {{ props.isAvailable ? "available" : "not available" }}
App.svelte
UserProfile.svelte
My name is {name}!
My age is {age}!
My favourite colors are {favouriteColors.join(", ")}!
I am {isAvailable ? "available" : "not available"}
import { useState } from "react";
export default function InputHello() {
const [text, setText] = useState("你好 code秘密花园");
function handleChange(event) {
setText(event.target.value);
}
return (
<>
{text}
>
);
}
{{ text }}
{text}
import { useState } from "react";
export default function IsAvailable() {
const [isAvailable, setIsAvailable] = useState(false);
function handleChange() {
setIsAvailable(!isAvailable);
}
return (
<>
>
);
}
import { useState } from "react";
export default function PickPill() {
const [picked, setPicked] = useState("red");
function handleChange(event) {
setPicked(event.target.value);
}
return (
<>
Picked: {picked}
>
);
}
Picked: {{ picked }}
Picked: {picked}
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 (
);
}
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(
);
index.html
App.vue
main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
index.html
App.js
import App from "./App.svelte";
const app = new App({
target: document.getElementById("app"),
});
export default app;
App.svelte
你好 code秘密花园
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 };
}
App.vue
Fetching users...
An error ocurred while fetching users
-
{{ user.name.first }}
{{ user.name.last }}
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 };
}
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 };
}
import Link from "next/link";
export default function Home() {
return (
-
Home
-
About us
);
}
-
Home
-
About us
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
Nuxt 3
|-- pages/
|-- index.vue // index page "/"
|-- about.vue // about page "/about"
SvelteKit
|-- routes/
|-- +page.svelte // index page "/"
|-- about/
|-- +page.svelte // about page "/about"
|-- +error.svelte // handle HTTP errors 404, 500,...
|-- +layout.svelte // global app layout