前言
最近一直在使用Svelte,加上自己一直在写React和Vue,所以想总结一下这三个框架中的一些通用能力,看看同一种功能在不同框架中的写法如何。
如果你是其中一个框架的拥趸,正想快速上手其他框架;亦或是还未接触过框架的新手,相信看完这篇文章,能够有一定的收获。
各框架版本:
- React: 18.2.0
- Vue: 3.4.0
- Svelte: 4.2.8
本来想写“十分钟,快速上手”,但过于标题党,遂放弃。
数据
React
useState
返回一个数组,数组第一个值便是存储的状态。
import { useState } from "react";
export default function Page() {
const [count] = useState(0);
return (
<div>变量:{count}</div>
);
}
Vue
使用ref
或reactive
来存储数据。
<template>
<div>变量:{{ count }}</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
Svelte
非常简单,跟平时的使用一样。
<script>
let count = 0;
</script>
<div>变量:{ count }</div>
方法
React
useState
返回数组中的第二个值是一个方法,用来更新数据。
import { useState } from "react";
export default function Page() {
const [count, setCount] = useState(0);
const updateCount = () => {
setCount(count + 1);
};
return (
<div>
count: {count}
<button onClick={updateCount}>+1</button>
</div>
);
}
Vue
需要注意ref
声明的变量需要用xxx.value来访问和操作。
<template>
<div>
count: {{count}}
<button @click="updateCount">+1</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const updateCount = () => {
count.value++;
}
</script>
Svelte
也是非常简单。不过和vue一样,在更新数组时需要用一些骚操作。
<script>
let count = 0;
const updateCount = () => {
count++;
}
</script>
<div>
count: {count}
<button on:click={updateCount}>+1</button>
</div>
条件判断
React
通过逻辑运算符&&
或者三元表达式来判断显示
import { useState } from "react";
export default function Page() {
const [gender, setGender] = useState("");
const changeGender = (e) => {
setGender(e.target.value);
};
return (
<section>
请选择性别:
<section>
<input
id="male"
type="radio"
value="male"
name="gender"
checked={gender === "male"}
onChange={changeGender}
/>
<label htmlFor="male">男</label>
</section>
<section>
<input
id="female"
type="radio"
value="femail"
name="gender"
checked={gender === "female"}
onChange={changeGender}
/>
<label htmlFor="female">女</label>
</section>
{gender && (
<section>
你好,
{gender === "male" ? (
<span>先生</span>
) : (
<span>女士</span>
)}
</section>
)}
</section>
);
}
Vue
通过v-if
,v-else-if
,v-else
指令来判断显示。
<template>
<section>
请选择性别:
<section>
<input
id="male"
type="radio"
value="male"
name="gender"
:checked="gender === 'male'"
@change="changeGender"
/>
<label for="male">男</label>
</section>
<section>
<input
id="female"
type="radio"
value="femail"
name="gender"
:checked="gender === 'female'"
@change="changeGender"
/>
<label for="female">女</label>
</section>
<section v-if="gender">
<section>
你好,
<span v-if="gender === 'male'">先生</span>
<span v-else>女士</span>
</section>
</section>
</section>
</template>
<script setup>
import { ref } from "vue";
const gender = ref("");
const changeGender = (e) => {
gender.value = e.target.value;
};
</script>
Svelte
通过{#if}{:else}{/if}
来判断显示
<script>
let gender = '';
const changeGender = (e) => {
gender = e.target.value;
}
</script>
<section>
请选择性别:
<section>
<input
id="male"
type="radio"
value="male"
name="gender"
checked={gender === "male"}
on:change={changeGender}
/>
<label for="male">男</label>
</section>
<section>
<input
id="female"
type="radio"
value="femail"
name="gender"
checked={gender === "female"}
on:change={changeGender}
/>
<label for="female">女</label>
</section>
{#if gender}
<section>
你好,
{#if gender === 'male'}
<span>先生</span>
{:else}
<span>女士</span>
{/if}
</section>
{/if}
</section>
循环判断
React
通过map方法来展示列表
import { useState } from "react";
export default function Page() {
const [list] = useState([1, 2, 3]);
return (
<ul>
{list.map((item, index) => {
return <li key={index}>item - {item}</li>;
})}
</ul>
);
}
Vue
通过v-for
来展示列表
<template>
<ul>
<li v-for="(item, index) in list" :key="index">item - {{ item }}</li>
</ul>
</template>
<script setup>
import { reactive } from "vue";
const list = reactive([1, 2, 3]);
</script>
Svelte
通过{#each}{/each}
来展示列表
<script>
const list = [1,2,3];
</script>
<ul>
{#each list as item, index}
<li>item - {item}</li>
{/each}
</ul>
后文
篇幅限制,本次介绍只会选取部分内容进行介绍。而且如果我把所有内容都放在一篇文章,读者读起来也有一点负重前行的感觉。
所以,针对以上三种框架的不同写法,笔者专门准备了一个github项目rvs。项目里通过qiankun来连接三个分别由React、Vue和Svelte编写的子应用项目。
项目通过章节来介绍同一种能力在三个框架的不同写法,同时会展示出具体的代码。
如果觉得对您有帮助,欢迎Star!
祝大家周末愉快!(可惜我还在加班……)