React & TailwindCSS

关于 Node.js, NPM, React, TailwindCSS, Next.js 的一切

Project v0 Released!

Remember to checkout and start the project!

复习

  • 什么是 HTML?
  • 什么是 CSS?
  • 什么是 JavaScript?

复习

CSS 和排版

  • 还记得我们之前做的聊天软件界面吗 https://play.tailwindcss.com/OUUQFgwJMR?file=css
  • 我们复制了很多个 div 来实现多个聊天气泡
  • 如果我们要实现一个可以动态修改内容不同的聊天气泡列表,我们可能需要复制更多的 div
  • 然后一个个找到要修改的元素……

传统 HTML 的大麻烦

传统 HTML 的大麻烦

  • 在 Web 1.0 时代,我们使用 HTML 来描述网页的结构
  • 这时的互联网还很简单,网页内容相对固定
  • 但是随着互联网的发展,网页内容变得越来越多样化
  • 我们希望网页内容可以动态变化
  • 于是我们引入了 Javascript 来操作 DOM
  • https://play.tailwindcss.com/IzstdqILRM

Note

DOM: Document Object Model

  • 它是加载在浏览器中的文档模型,可以将文档表示为节点树,或称 DOM 树
  • 它是一个树状结构,每个节点都是一个对象,表示文档中的一个元素

More at MDN

操作 DOM

  • 获取 DOM 节点
    • document.getElementById('message'): 获取 id 为 message 的节点
    • document.getElementsByClassName('message'): 获取 class 为 message 的所有节点
    • document.getElementsByTagName('div'): 获取标签为 div 的所有节点
    • document.querySelector('#message'): 获取 id 为 message 的节点
    • document.querySelectorAll('.message'): 获取 class 为 message 的所有节点
  • 修改 DOM 的节点内容
    • element.innerHTML: 修改节点内的 HTML 内容
    • element.textContent: 修改节点内的文本内容
    • element.style.color: 修改节点内的样式
    • element.style.backgroundColor: 修改节点内的样式
    • element.style.fontSize: 修改节点内的样式
    • element.style.fontWeight: 修改节点内的样式
    • element.style.fontFamily: 修改节点内的样式
修改这里
// 修改 innerHTML
const message = document.getElementById('message');
message.innerHTML = 'Hello, World!';
// 添加 attribute
const message = document.getElementById('message');
message.setAttribute('class', 'bg-red-500 text-white');
// https://play.tailwindcss.com/IzstdqILRM
// 创建消息容器
const messageContainer = document.createElement('div');
messageContainer.classList.add('message-container', 'message', 'right'); // 默认发送方是自己 (right)
 
// 创建气泡
const bubble = document.createElement('div');
bubble.classList.add('bubble');
bubble.textContent = messageText;
 
// 创建头像
const avatar = document.createElement('img');
avatar.classList.add('avatar');
avatar.src = 'https://via.placeholder.com/40/3366FF/FFFFFF?text=我'; // 我的头像
avatar.alt = '我的头像';
 
// 组合消息元素
messageContainer.appendChild(bubble);
messageContainer.appendChild(avatar);
 
// 添加到聊天区域
chatArea.appendChild(messageContainer);
 
// 清空输入框
messageInput.value = '';

操作 DOM

  • 仍然过于麻烦
  • 能否有一种方式,让我们可以封装成一个 <Message /> 组件,然后复用这个组件?
    • Fake HTML Tag!!!
<div>
    <NavBar />
    <div>
        <Message content="Hello, World!" />
        <Message content="Cont'd" />
        <Message content="End!s" />
    </div>
    <TextArea />
</div>

React

  • A JavaScript Library for building user interfaces
  • React Loco
  • "Create user interfaces from components"
  • Official Site
  • Fake HTML Tag === React Components

组件

  • React 的 Logo是一个原子
  • 质子组成了原子,原子组成了分子
  • 在 React 中,我们的组件组成了组件,最后封装在最大的 <App /> 组件中
  • App
  • React 是一个框架,它允许你将网站拆分成可重用的组件。
  • 每个组件都类似于你定义的“自定义 HTML 标签”。
  • 组件是一系列 HTML/CSS/JavaScript 的抽象。
  • 组件可以构建成树状层次结构。

组件的结构

  • 例如,我们想实现一个消息气泡的组件
  • Message
  • 可以变成这样的骨架
  • Message
  • 假设你已经完成了排版布局等操作,接下来我们只给这个组件填充数据就好
  • 如何传递?

title: 通过 Props 传递数据

  • 在组件中,我们通过 props 来传递数据
  • props 由父元素传递给子元素,是一个单向的数据流
  • 例如,我们的 <MessagesArea /> 组件里面包含了我们的 <Message /> 组件
  • 我们只需要在 <MessagesArea /> 组件中传递 messages 这个 props<Message /> 组件
  • <Message /> 组件中,我们就可以通过 props 来获取 messages 这个数据
<Message message="..." sender="..." time="..." avatar="..." />