组件框架是构建应用程序的工具,使用户界面和逻辑被分割成独立的可重用组件。今天的组件框架包括React、Vue、Angular、Ember、Svelte等。
Vue和React利用了常见的框架概念,如处理状态、道具、参照物、生命周期钩子、事件等。这两个框架在今天的web开发中被广泛使用。它们以可重用组件的形式使用几乎相似的模式来构建UI,但在这篇博文中,你将了解到组件框架的概念,以及它们在Vue中是如何完成的,与它们在React中是如何完成的相比。
安装和设置
让我们先来比较一下这两个框架的安装过程。
Vue
要安装Vue CLI(命令行界面),可以使用以下命令:
npm install -g @vue/cli
要检查版本,在终端运行以下命令:
vue --version
要创建一个新项目,运行以下命令:
vue create project_name
cd project_name
npm run serve
React
要安装React,在你的终端上运行以下命令:
npm install -g create-react-app
要创建一个新的项目,运行下面的命令:
npx create-react-app project_name
cd project_name
npm run start
Props
组件框架使用props将数据从父组件传递给子组件,这对两者来说都是一种重要的技术。
Vue
在Vue中,道具可以使用引号作为字符串传递,也可以使用v-bind 指令作为变量传递,也可以只写成一个: 。
传递道具给子组件
// passing props from to Modal component
<template>
<Modal :isOpen="pageLoaded" title="Survey Form" />
</template>
在子组件中访问props
// Modal Component
<template>
<form v-if="isOpen">
<p>{{ title }} </p>
<!-- ...other form elements -->
</form>
</template>
<script setup>
const props = defineProps({
isOpen: Boolean,
title: String
});
</script>
React
在React中,道具也是用引号作为字符串传递的,或者像这样用大括号作为变量传递。
传递道具
<div>
<Modal isOpen={pageLoaded} title="Survey Form" />
</div>
访问道具
function Modal({isOpen, title}) {
return (
{isOpen &&
<form>
<p>{ title }</p>
// ...other form elements
</form>
);
}
事件
组件可以监听特定的事件,如鼠标事件(如点击、鼠标悬停等)和键盘事件(如按键下降、按键上升等),事件处理在这两个框架中也是必要的。
Vue
在Vue中,事件是使用v-on 指令创建的,也可以写成@ ,比如说:
<template>
<button @click="displayName"> Show Name </button>
<template>
<script setup>
function displayName() {
alert('Lawrence Franklin');
}
</script>
React
在React中,事件是通过典型的JavaScript内联事件方法创建的,如onClick、onKeyDown、onKeyUp等:
function NameAlert() {
const displayName = () => {
alert('Lawrence Franklin');
}
return (
<button onClick="displayName"> Show Name </button>
);
}
状态
组件框架使用状态来管理组件内的反应性。状态在各组件之间实时更新。处理整个网站的全局状态是一个关键问题。
Vue
在Vue中,可以使用ref() 或reactive() 方法来创建状态,除了使用.value 属性来访问ref,而直接使用reactive(它们已经被解开了),这两者的作用是一样的。这些方法有助于在组件中创造反应性:
<template>
<div>
<p>{{ firstname }}</p>
<p>{{ lastname }}</p>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue';
const firstname = ref('Franklin');
console.log(firstname.value);
const lastname = reactive('Lawrence');
console.log(lastname);
</script>
可以使用watch() 和watchEffect() 方法来观察反应性的值。这些方法跟踪反应性数值的变化,并在每次这些数值变化时运行一个回调函数。这些方法之间的唯一区别是,watchEffect() 最初运行一次,然后开始观察变化:
import { watch, watchEffect } from 'vue';
// watch
watch( firstname, () => alert('firstname changed!');
// watchEffect
watchEffect(lastname, () => alert('lastname changed');
React
React使用useState() 钩子来跟踪组件中的状态变化并创建副作用:
import { useState } from 'react';
function ShowName() {
const [firstName, setFirstName] = useState('Franklin');
const [lastName, setLastName] = useState('Lawrence');
console.log(firstName, lastName);
return (
<div>
<p>{ firstname }</p>
<p>{ lastname }</p>
</div>
)
}
为了监听状态变化,React使用useEffect() 钩子。这个钩子接受一个回调函数和一个依赖关系的数组,每当这些依赖关系的值发生变化时,它就会触发回调函数。依赖关系可以是任何数据类型。这里有一个例子:
import { useEffect } from 'React';
useEffect(() => {
console.log('name updated!');
}, [firstName, lastName]);
开源会话回放
OpenReplay是一个开源的会话回放套件,让你看到用户在你的网络应用上做了什么,帮助你更快地排除问题。OpenReplay是自我托管的,可以完全控制你的数据。
参考文献
有时你需要直接处理DOM元素,比如添加一些动画,将输入字段设置为焦点或模糊,等等。要做到这一点,大多数组件框架都为你提供了一个引用功能(Vue和React利用ref ),它可以用来引用DOM元素。
Vue
在Vue中,用ref 关键字编写的模板ref被用在DOM元素上,并像这样访问:
<template>
<input type="text" ref="name" />
</template>
<script setup>
import { ref } from 'vue';
const name = ref(null);
handleBtnClick(() => {
name.value.focus();
}
</script>
React
在React中,Refs的使用方式有点不同。他们使用ref 关键字和useRef() 钩子来引用DOM元素,然后像这样使用.current 属性来访问这些元素:
import { useRef } from 'react';
function MyName() {
const name = useRef(null);
handleBtnClick(() => {
name.current.focus();
});
return (
<input type="text" ref="name" />
<button onClick={handleBtnClick}> Start typing </button>
)
}
双向数据绑定
数据可以(而且通常是)以 "双向 "方式绑定,这意味着数据可以以两种方式更新。这用于表单输入字段,如input 元素、select 元素、textarea 元素、checkbox element ,等等。输入值可以通过元素改变,也可以通过代码改变,它们是同步的,也就是说,一种方式(如代码)的改变会更新另一种方式(如输入框)的值。
Vue
Vue使用v-model 指令来创建一个双向的绑定,就像这样:
<template>
<input v-model="searchQuery" />
</template>
<script setup>
import { ref } from 'vue';
const searchQuery = ref('');
// searchQuery.value can be updated here, and it reflects in the input field instantly
</script>
React
React使用称为控制输入的东西来双向绑定数据,像这样:
import { useState } from 'react';
function MyComponent() {
[searchQuery, setSearchQuery] = useState('');
const handleChange = (event) => {
setSearchQuery(event.target.value);
}
return (
<input value={searchQuery} onChange={handleChange}/>
);
}
动态渲染
有时,组件会根据某些条件进行渲染。换句话说,组件可以根据指定条件的结果来动态渲染。
Vue
Vue使用v-if,v-else 和v-show 指令来根据指定的条件动态地渲染一个组件。下面的例子说明了这个概念:
<template>
<div>
<p v-if="isLoggedIn"> Welcome </p>
<p v-else> Please Login </p>
<button v-show="!isLoggedIn">Login</button>
</div>
</template>
React
React利用JavaScript的条件,如if 、&& ,或三元操作符来动态渲染一个组件。下面是一个例子来说明这个问题:
function MyComponent() {
return (
{isLoggedIn ?
<p>Welcome</p> :
<p> Please Login </p>
}
{!isLoggedIn && <button> Login </button>}
);
}
传递子元素
有时你想把子元素传递给其他组件,而不仅仅是道具。像Vue和React这样的组件框架为你提供了实现这一目的的方法。
Vue
Vue使用槽来传递子元素。下面是一个你如何使用它们的例子。
模态组件,这是接收子元素的组件 :
// Modal.vue
<template>
<div>
<h1>Welcome</h1>
<slot><slot>
</div>
</template>
UserPage组件,这是传递子元素的父组件:
// UserPage.vue
<template>
<div>
<h1>Survey Form</h1>
<Modal>
<p>Kindly fill out this survey...</p>
<input type="text" />
<button>Submit</button>
</Modal>
</div>
</template>
React
React为你提供了children prop值,类似于Vue的slots来传递子元素。这里有一个例子。
模态组件,这是接收子元素的组件 :
function Modal( {children} ) {
return (
<div>
<h1>Welcome</h1>
{ children }
</div>
);
}
UserPage组件,这是传递子元素的父组件:
function UserPage() {
return (
<div>
<h1>Survey Form</h1>
<Modal>
<p>Kindly fill out this survey...</p>
<input type="text" />
<button>Submit</button>
</Modal>
</div>
);
}
总结
到此为止,你已经学会了组件框架中使用的大部分概念,如状态、道具、组件、事件等。你也学到了这些概念如何在Vue与React中实现。鉴于这些概念在各个组件框架中都普遍使用,一旦你熟悉了这些概念的工作方式,从一个框架过渡到另一个框架就相对容易了。
