0%

在HTML里,我们会使用input标签去处理密码。
就像这样:

1
<input type="password">

如果你使用它,你会在输入时字符会变成这样的小圆点 •••••••

那是因为浏览器试图帮助提高安全性。如果它没有这样做,那么有人可能会从你的身边偷看你正在输入的内容。这应该比查看手指在键盘上按下的键更容易。

但是现在 UX 已经发生了一些变化,并且更常见的选项是:

秘密

我觉得显示/隐藏密码是个很通用的场景。这样我们就可以确保正确输入,并且不会遭受打错字的痛苦。

所以! 该怎么办?

1: 使用 type=”password”, 然后使用JavaScript切换到 type=”text”

这就是现在大家通常会做的事情,因为它现在实际上适用于所有浏览器。

1
2
3
4
5
6
const input = document.querySelector(".password-input");
if (input.getAttribute("type") === "password") {
input.setAttribute("type", "text");
} else {
input.setAttribute("type", "password");
}

这里的问题是除了你必须为此更改输入类型有点奇怪之外,还有是对密码管理器工具失效。

2: 在CSS使用 -webkit-text-security

这不是一个特别通用的方案,因有些浏览器不支持这个属性。

1
2
3
4
5
6
input[type="password"] {
-webkit-text-security: square;
}
form.show-passwords input[type="password"] {
-webkit-text-security: none;
}

3: 在CSS使用 input-security

现在有个关于input security提案,我没可以切换input-security的值。我觉得这是一个比较好的提案,但是现在大多数浏览器还不支持,所以严格意义上说,我还只能用方案1。

1
2
3
form.show-passwords input[type="password"] {
input-security: none;
}

新版Node.js

模块是导出一个或多个值的 JavaScript 文件。导出的值可以是变量、对象或函数。

ES6 导入语法允许导入从不同 JavaScript 文件导出的模块。在 React 和 React Native 应用程序中使用模块是一种常见的模式。语法由以下 ES 模块标准组成:

1
import XXX from 'xxx';

ES 模块是使用模块的 ECMAScript 标准。Node.js 使用 CommonJS 标准来导入模块。这种标准的语法可以这样写:

1
const XXX = require('xxx');

Node js 不直接支持 ES6 导入。尝试import在 JS 文件中编写语法:

1
import { ApolloServer, gql } from 'apollo-server';

使用npm start或运行Node.js服务器npm run dev

Node Error

此错误的解决方案位于上述错误代码段的第一行,现在是 Node.js 推荐的方法。设置 “type”: “module”package.json文件。

1
2
3
{
"type": "module"
}

但是这个方案只适用于最新的 Node.js 和14.x.x+。

低于 14 的 Node.js

这个问题的另一个解决方案是使用Babel。它是一个 JavaScript 编译器,允许使用最新的语法编写 JS。Babel 不是一个框架或平台,所以它可以用在任何用 JavaScript 编写的项目中,因此也可以用在 Node.js 项目中。

首先从终端窗口安装以下开发依赖项:

1
npm i -D @babel/core @babel/preset-env @babel/node

然后在名为 Node.js 项目的根目录创建一个文件babel.config.json并添加以下内容:

1
2
3
{
"presets": ["@babel/preset-env"]
}

该包@babel/node是一个 CLI 程序,它在运行之前使用 Babel 预设和插件编译 Node.js 项目中的 JS 代码。这意味着它会babel.config.json在执行 Node 项目之前读取并应用任何提及的配置。

更换node用babel-node在执行服务器startdev脚本。

使用npm run dev脚本运行 Node 服务器的示例:

1
2
3
4
5
{
"scripts": {
"dev": "nodemon --exec babel-node server.js"
}
}

前言

在开发人员的日常生活中,检查CSS并不常见,但有时不得不这样做。也许这是性能评估网页的一部分,为了找出关键的CSS并减少未使用的选择器。也许是为提高访问性,代码库中使用各种颜色对比突出。

无论情况如何,每当那一时刻到来时,我通常都会使用本文中将要介绍的一些工具。但在此之前,让我们首先看看“检查”CSS意味着什么。

检查CSS很困难

一般来说,代码检查涉及分析代码以发现bug或其他不正常的地方,例如可能的性能问题。对于大多数编程语言来说,审核代码的概念相对简单:它是否有效。但是CSS是一种特殊的语言,在这种语言中,错误大多会被浏览器忽略。事实上,你可以通过许多不同的方式实现相同的风格。至少可以说,这使得CSS的检查有点棘手。

通过为您喜欢的代码编辑器使用扩展或设置检查器或代码检查器,可以防止发现这些错误。但这不是我想在这里展示的,这还不够。我们仍然可能会使用太多的颜色、排版定义或z-index,所有这些都可能导致CSS代码库混乱、不可维护、不稳定。

为了真正检查CSS,我们需要更深入地挖掘并找到那些是最佳的做法。为了找到这些做法,我们可以使用以下工具。

浏览器开发工具

让我们看看用于CSS检查的Chrome 开发工具。

如果您喜欢手动检查CSS代码,可以使用Inspect工具。通过使用它,我们可以看到应用到特定元素的CSS代码。使用“检查箭头”,我们甚至可以看到关于颜色、字体、大小和可访问性的更多详细信息。

浏览器开发工具

CSS Overview

检查 CSS 是非常基础的,一切都需要手动完成。让我们看看一些更高级的 DevTools 功能。

CSS Overview就是其中之一。要启用 CSS Overview工具,请转到“设置”,单击“实验”,然后启用“CSS Overview”选项。要打开 CSS Overview面板,您可以使用 CMD+Shift+P 快捷键,输入“CSS Overview”,然后选择“显示 CSS Overview”。这个工具总结了 CSS 属性,如颜色、字体、对比度、未使用的声明和媒体查询。我通常使用这个工具来简单判断CSS代码的好坏。例如,如果有“50 级灰度”或太多的排版定义,这意味着风格指南没有得到遵循。

Coverage panel

覆盖面板
覆盖率工具显示页面上使用的代码量和百分比。要查看它,可以使用 CMD+Shift+P 快捷键,键入“coverage”,选择“Show Coverage”,然后单击“refresh”图标。

也可以通过在 URL 过滤器输入中键入“.css”来仅过滤 CSS 文件。我通常使用这个工具来了解网站使用的技术。例如,如果我看到覆盖率非常高,我可以假设 CSS 文件是为每个页面单独生成的。它可能不是关键数据,但有时它有助于理解网站的缓存策略。

Coverage panel

Rendering Panel

渲染面板是另一个有用的工具。要打开渲染面板,再次使用 CMD+Shift+P,这次输入“rendering”,然后选择“Show Rendering”选项。这个工具有很多选项,但我最喜欢的是:

  • Paint flashing — 在发生重绘事件时显示绿色矩形。我用它来识别渲染时间过长的区域。
  • Layout Shift Regions — 当布局移动发生时 显示蓝色矩形。为了充分利用这些选项,我通常在“网络”选项卡下设置“慢速 3G”预设。我有时会录制我的屏幕,然后放慢视频速度以找到布局变化。

其他选项可能更有助于调试问题,例如模拟和禁用各种功能、强制使用首选颜色方案功能或打印介质类型以及禁用本地字体。

Rendering Panel

Performance Monitor

性能监视器
另一个用于检查性能 CSS 代码的工具是性能监视器。要启用它,再次使用 CMD+Shift+P,键入“performance monitor”,然后选择“显示性能监视器”选项。我通常使用这个工具来查看在与页面交互时或动画发生时触发了多少重新计算和布局。

Performance Monitor

Perfomance panel

“性能”面板显示页面加载期间所有浏览器事件的详细视图。要启用性能工具,请执行 CMD+Shift+P,键入“性能”,选择“显示性能”,然后单击“重新加载”图标。我通常启用“屏幕截图”和“Web Vitals”选项。对我来说最有趣的指标是 First Paint、First Contentful Paint、Layout Shifts 和 Largest Contentful Paint。还有一个饼图显示绘画和渲染时间。

总结

CSS无处不在,我们需要把它视为每个项目的一等公民。别人怎么看你的CSS并不重要,重要的是你怎么看它。如果你的CSS井然有序并且编写良好,那么您将花费更少的时间调试它,从而得以花更多的时间开发新功能。在理想的世界中,我们会教育每个人写好的CSS,但这需要时间。

让今天成为你开始关心CSS代码的日子。

我知道不是每个人都喜欢检查CSS。但是,如果在这些工具上运行代码,并试图改进CSS代码库的哪怕一部分,那么本文就完成了它的工作。

如果你知道任何其他工具,请在评论中告诉我。

前言

Azure DevOps 提供了项目管理和源代码管理的功能,它的自动化构建和发布可以让我们专注于业务逻辑,省去了一些CI/CD的繁杂琐事。

根据 Azure 的官方文档,

Microsoft Azure 具有充分的自由和灵活性,可以随时随地生成、管理和部署应用程序,帮助用户实现目标。使用你首选的语言、框架和基础结构(甚至可使用你自己的数据中心和其他云)解决大大小小的难题。

本文将介绍如何使用Azure DevOps创建React应用的构建和发布管道部署到 Azure App Service,快速上手Azure DevOps自动化部署

创建应用服务

要部署 React 应用,首先需要在 Azure 上创建应用服务。顾名思义,应用程序服务(Azure App Service)是用于构建、部署和扩展 Web 应用程序的平台。

以下是步骤:

  1. 如果尚未在 Azure 上创建帐户,则可以选择免费帐户。

App_Services

  1. 对于订阅,请选择您的免费订阅。为此应用程序创建一个新的 Resource Group。本文使用名为 react-example-deploy 的资源组。选择 Node 10.14 作为 Runtime Stack,选择 Windows 作为 Operating System。最后,请选择离您最近的地区或保持默认。

App_Service_Config

  1. 点击创建几分钟后,您的新应用服务将上线,您将看到这样的消息。你可以访问 {AppServiceName}.azurewebsites.net 来查看它的实际效果。现在是一个磨人页面,之后 React 应用程序将部署在同一个 URL 上。

Deployment_Complete

创建应用服务

在这里,我们将使用 Azure DevOps 在我们的应用程序中简化持续集成和持续部署。

创建 Azure DevOps 组织

如果你已经创建了 Azure DevOps 组织,请随意跳过。以下是创建 Azure DevOps 组织的步骤:

  1. 登录到 Azure DevOps.
  2. 点击 New organization.

New_Organization

  1. 你会被问到是否继续. 选择 继续.

Continue

  1. 然后您将被要求为您的组织提供一个唯一的名称。输入一个唯一的名称并点击继续。本文使用名为 ReactExampleDeploy 的组织。
    反应示例部署

ReactExampleDeploy

您的组织现已创建,可以通过 https://dev.azure.com/{yourorganization} 访问,其中 yourorganization 是您组织的名称。

Creating a Project创建项目

在 Azure DevOps 组织仪表板上,创建一个新项目。为您的项目指定一个唯一名称,然后点击创建项目

New_Project

推动 React 项目

您现在将 React 应用程序从您的本地机器推送到您刚刚通过命令行创建的项目。

  1. 在您的应用程序的根目录中,运行以下命令。
1
2
3
git init
git add .
git commit -m "Initial Commit"

bash

  1. 在您的项目仪表板上,转到 Repos。复制从命令行推送现有存储库下的代码并在命令行中运行相同的代码。可能会要求您登录 Azure 帐户以继续操作。把代码push到仓库。

Pushing Project

运行此命令后,您可以在 Repos → Files 下看到您的 React 项目。Pushed

现在你已将应用推送到 Azure DevOps 项目,下一步是创建用于构建工件的管道和用于部署 React 应用的发布管道。

创建构建工件管道

根据 Azure 的文档,“您可以使用 Azure Pipelines运行构建、执行测试并将代码(发布)自动部署到各种开发和生产环境。”

以下是创建构建工件管道的步骤。

  1. 单击 Pipelines 选项卡然后单击Create Pipeline.

Create a Pipeline

  1. 当被问到“你的代码在哪里?”时,选择使用经典编辑器选项。

Use the classic editor

  1. 选择 Azure Repos Git 作为源,将其他所有内容保留为默认值,然后点击Continue.

Azure Repos Git

  1. 当要求提供模板时,选择Empty job.

Empty_Job

  1. 单击 + 号

React CI

搜索“npm”并添加两次 npm 任务。

npm

你可能会问,为什么要两次?由于此任务用于node包,因此您需要另一个用于构建项目的任务;不存在默认任务,因此您需要为此创建自定义任务。

点击第二个npm任务,配置如下。

  • 将显示名称更改为 npm run build.
  • 将命令更改为自定义.
  • 在命令和参数中添加运行构建

npm run build

  1. 现在,搜索发布构建工件并将其添加到代理作业 1。

Publish build artifacts

单击 Publish build artifacts 然后修改 Path to publishbuild.

Path to publish

  1. 转到触发器选项卡并选择启用持续集成。您可以将其他所有内容保留为默认值。

CI

  1. 最后,单击 Save & queue 并再次点击 Save & queue

Save & queue

在运行管道模式中,将所有内容保留为默认值,然后点击保存并运行。

Save and run

几分钟后,管道将成功完成运行。您可以在 Pipelines 选项卡下检查以验证它。

创建发布管道

发布管道将部署在上一节中构建的工件。

以下是创建发布管道的步骤:

  1. 转到Pipelines** → Releases 然后单击 New pipeline.

New pipeline release

  1. 选择Azure App Service Deployment 然后点击 Apply.

Azure App Service Deployment

您将被要求为Stage命名。进入 Production 并关闭模态。

Production

  1. 现在点击 Add an artifact.

Add an artifact

对于 Source,选择您在上一节中创建的管道,即 React Deploy Example-CI。将其他所有内容保留为默认值,然后点击添加。

React Deploy Example-CI

  1. 要配置持续部署,请单击 Artifacts 中的闪电图标。

Ligthning

启用第一个禁用选项,在 Build 分支中输入 master,然后关闭模态框。

master

  1. Stages下面 点击 1 job, 1 task .

Stages

会弹出配置 Deploy Azure App Service.

Deploy Azure App Service

根据您的订阅选择 Azure 订阅。您可能需要单击授权并授权订阅。

Azure subscription

App service name

点击 Deploy Azure App Service, 然后在 Package or folder 输入:

1
$(System.DefaultWorkingDirectory)/_React Deploy Example-CI/drop

drop

  1. 最后点击保存

Save

Leave the modal that appears at default and hit OK.

OK

现在,单击 Create release,它将出现在 Save 按钮的右侧。

Create release

创建发布

Create

几分钟后,您的应用程序将部署在 {yourappservicename}.azurewebsites.net。

由于您已经配置了 CI/CD,您可以在本地机器上更新应用程序并将提交推送到 repo,这将触发新版本,并且您的 React 应用程序将被更新。

总结

在本文中,我们讨论了如何使用 CI/CD 将 React 应用程序部署到 Azure App Service 的过程。

下一步,可以去尝试探索 Azure 提供的不同功能。

以下是一些相关文档。

前言

什么是Portals?如何以及何时使用它
React v16 引入了一个称为Portals的新功能。 Portals 提供了一种快速简便的方法来将子组件渲染到存在于父组件的 DOM 层次结构之外的 DOM 节点中。 React 在单个 DOM 节点下渲染整个应用程序 - 应用程序根(root)。但是如果你想在根 DOM 节点之外渲染子节点怎么办?那是你使用Portals的时候。比如当父元素具有样式(如 z-index 将其推到页面的最前面或overflow: hidden)你又希望子元素在视觉上显示在其容器顶部时。

它是如何工作的

Portals可以位于 DOM 树中的任何位置,它在其他方面的行为都像一个普通的 React 子节点。无论子节点是否是Portals,诸如上下文之类的功能都完全相同,因为无论在 DOM 树中的位置如何,Portals仍然存在于 React 树中。这包括事件冒泡。即使那些元素不是DOM树中的祖先,从Portals内部触发的事件也将传播到包含React的树中的祖先。

用法

我建议它创建一个组件,然后在每次需要时使用。首先,我们需要在 index.html 中创建一个 DOM 元素(就像我们为附加应用程序而创建的根元素),这是所有Portals组件将被挂载的地方。

1
2
<div id="portal-components"></div>
<div id="root">

然后创建Portal组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { PureComponent } from 'react'
import ReactDOM from 'react-dom'

const rootElement = document.getElementById('portal-components')

class Portal extends PureComponent {
constructor(props) {
super(props)
this.el = document.createElement('div')
}

componentDidMount() {
rootElement.appendChild(this.el)
}

componentWillUnmount() {
rootElement.removeChild(this.el)
}

render() {
return ReactDOM.createPortal(
this.props.children,
this.el
)
}
}

export default Portal

最后这样使用它

1
2
3
<Portal>
{Everithing here is going to be attachaded outside the root DOM node}
</Portal>

注意

在使用Portals的时候,所有在组件中被渲染的子元素都会相对与屏幕绝对定位,我建议使用css:position: fixed来调整位置。

前言

React没有像其他框架比如(Ember、Vue 等)那样开箱即用的计算属性,所以我们如何以正确的方式实现这个功能呢?最常见的做法是如果是类组件,在 render 方法中“计算”,或者是函数组件就是在主体中。

问题

每次渲染都会进行计算,这意味着即使需要计算的值没有改变,也会生成一个新变量。另外,如果我们将它作为 prop 传递给子组件并且不是原始类型(字符串、数字或布尔值),则子组件将重新渲染,因为它认为这是一个新值,这可能会导致性能问题。

解决方案

如果参数没有改变,将计算提取到一个函数并使用记忆化来防止被重新初始化,如果我们在做大量数据等昂贵的计算,这会给我们带来性能上的提升。

例子

类组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from 'react'
import memoize from 'lodash/memoize'
import MenuItem from './MenuItem'

class RenderSuggestion extends React.Component {

renderSuggestionStyles = (suggestionValue) => ({ pointerEvents: suggestionValue ? 'all' : 'none' })
renderSuggestionStylesMemo = memoize(this.renderSuggestionStyles)

render(){
const { suggestion, ...other } = this.props
return (
<MenuItem
{...other}
style={this.renderSuggestionStylesMemo(suggestion.value + 1)}
/>
)
}
}

函数组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react'
import memoize from 'lodash/memoize'
import MenuItem from './MenuItem'

const renderSuggestionStyles = suggestionValue => ({ pointerEvents: suggestionValue ? 'all' : 'none' })
const renderSuggestionStylesMemo = memoize(renderSuggestionStyles)

function RenderSuggestion({ suggestion, ...other }) {
return (
<MenuItem
{...other}
style={renderSuggestionStylesMemo(suggestion.value + 1)}
/>
)
}

在这里,如果我们不以正确的方式(没有记忆化)使用计算属性,则当道具更改时,子组件(MenuItem)将不必要地重新渲染。

Reselect
解决此问题的另一种很酷的方法是使用 reselect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React from 'react'
import { createSelector } from "reselect";
import MenuItem from './MenuItem'

class RenderSuggestion extends React.Component {

renderSuggestionStyles = createSelector(
(suggestionValue) => ({ pointerEvents: suggestionValue ? 'all' : 'none' })
)

render(){
const { suggestion, ...other } = this.props
return (
<MenuItem
{...other}
style={this.renderSuggestionStyles(suggestion.value + 1)}
/>
)
}
}

前言

在调试iOS表单的时候,发现点击输入框之后,屏幕会随着检点位置自动放大。但是在安卓中是不会的有这个问题的。

解决办法

<input />的字体大小为16px或更大,则iOS上的Safari将正常聚焦到输入中。但是,当font-size等于或小于15px时,上述问题再次发生。大概是因为Safari认为该字体太小,希望用户看清楚自己在做什么。因此它会放大以帮助你使用辅助功能。所以如果你不想要这个效果,请使用足够大的字体。

总结

总的说,我还是喜欢这个功能。它可以帮助人们看清自己在做什么,并且不建议使用超小字体。

前言

React.createRef和React.useRef都可以用来创建可变对象,这个对象包含current属性,可以用来保存和引用一些值,并且修改这个属性不会触发组件更新。
接下来聊它们的不同。

useRef vs createRef

useRef仅能用在FunctionComponent,createRef仅能用在ClassComponent。
首先hooks不能用在ClassCompnent中, createRef在FunctionComponent是无效的,因为FunctionComponent每次更新createRef都会重新初始化,所以ref会不断改变,看下面代码

1
2
3
4
5
function App() {
// 错误用法,ref.current永远是null
const ref = React.createRef();
return <div ref={ref} />;
}

useRef的用法

1
2
3
4
5
6
7
function App() {
// ref.current 可以保存div的dom实例
const ref = React.useRef();
return <div>
<div ref={ref}>hello world</div>
</div>
}

也可以使用callback ref保存dom实例。但是这个方法会有个小问题,官方文档也有说明。

1
2
3
4
5
6
7
class App extends React.Component {
render() {
return (
<input type="text" ref={el => this.inputRef = el} />
)
}
}

总结

useRef有两种用例:

  1. 直接访问DOM节点以强制执行DOM操作
  2. 在组件实例的整个生命周期中,在所有渲染器中保持一个值
    与useEffect,useState和useCallback结合使用时,可以保留以前的状态。

最后,不要滥用 Ref,Mutable 引用越多,对 React 来说可维护性一般会越差。

前言

如果你曾经不得不在网页上显示某种图标,那你和可能就使用或看过Font Awesome。 Font Awesome是一个很棒的图标库,它还提供了一个不错的React组件,所以在React程序中使用非常简单。

准备

为了快速搭建项目,我们使用create-react-app

安装 Font-Awesome

真棒字体
启动React应用程序后,我们需要安装Font Awesome提供的库:

1
2
3
4
5
6
#SVG渲染库
npm我 --save fortawesome / fontawesome-svg-core
#Font Awesome提供的图标集
npm install --save fortawesome / free-solid-svg-icons
#我们将使用的实际React组件
npm install --save fortawesome / react-fontawesome

这将安装所有必要的部件,接下来就可以使用了。还可以安装许多其他样式不同的图标集,包括Pro图标。这里我们只使用纯风格的免费图标。

注意:要使用Pro图标,需要一个付费的Pro帐户。

使用图标

现在,让我们打开App.js文件。它只包含JSX create-react-app提供的样板。我们先删除标头标签中的所有内容,保留有些样式,以便后续开发。

我们将需要导入我们安装的FontAwesomeIcon组件和一个SVG Icon进行渲染,然后使用fa-rocket图标。

SVG图案一般用于在图图形对象内部定义形状,创建一个新形状并用图案填充它。一个SVG元素或是位图图像,都可以通过元素在x轴或y轴方向以固定的间隔平铺。
下面会展示几个的简单SVG形状的。这个列表可能会随着时间的推移而增长,但是要想拥有一个全面的集合,可以在这基础上创造新图案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import './App.css';

// Font Awesome Imports
import { faRocket } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

function App() {
return (
<div className="App">
<FontAwesomeIcon icon={faRocket} />
</div>
);
}

export default App;

设置图标库

如果我们要使用大量图标,要怎么做呢?
其实我们不须要在要使用它们的任何地方重新导入,Font Awesome提供了一种创建图标库的方法,该图标库在导入后可在全球范围内使用。
要进行设置,我们首先创建一个名为fontawesome.js的新文件。我们将库设置添加到此文件中。

1
2
3
4
5
6
7
8
9
10
// Import the library
import { library } from '@fortawesome/fontawesome-svg-core'
// Import whichever icons you want to use
import { faRocket, faHome } from '@fortawesome/free-solid-svg-icons'

// Add the icons to your library
library.add(
faRocket,
faHome
)

注意:你也可以从“ @ fortawesome / free-solid-svg-icons”中将*作为图标导入; 并将它们映射到您的库中以获取所有图标,但是打包之后非常大! 最好只选择需要的那些。

这就是库的所有设置!唯一改变的是渲染组件时我们如何指定图标。 让我们看下App.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

import './App.css';
// NOTICE we don't need to import the individual icons!
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

function App() {
return (
<div className="App">
<header className="App-header">
<FontAwesomeIcon icon={['fa', 'rocket']} />
<br/>
<FontAwesomeIcon icon={['fa', 'home']} />
</header>
</div>
);
}

export default App;

总结

现在,你可以在整个应用中随意使用图标了。

我强烈建议配置Font Awesome文档中介绍的其他选项和属性去配置图标库,然后再使用这些图标!

前言

在编写表单时经常会出现区号字段,因为区号是一串数字,所以开始想到要用<input type="number">,但是可能会有其他问题。

用法

1
<input type="number">

之所以会使用*type=”number”,是这样可以利用浏览器的自动校验,并在移动设备上触发用户体验更好的更有用的基于数字的键盘。
但是这样的问题是,对于区号来说
type=”number”*是有问题的,因为区号可以有(例如,浙江杭州0571)。 所以可以使用的。

1
<input type="text" inputmode="numeric" pattern="^/d$">

有人提到试图劫持type=“tel”,但这有其缺点,例如拒绝正确格式化的4位数区号。

因此,虽然区号看起来像数字,但最好还是将其视为字符串。