/ div >
Toptal, LLC版权所有
< / div >< / div >< / div >\n\n\n\n上面的代码包含三个部分:
\n\nscript
标签, 这是一个可选的JavaScript块与变量和函数声明,应该在组件内使用.
style
标记,它是另一个可选块. It’s much like a common HTML style 标签 except for one important difference. The rules described inside this block are scoped to only this component. 将样式应用于 p
元素不会影响页面上的所有段落. 这是非常棒的,因为您不必提出类名,并且您永远不会意外地覆盖另一个规则.
The last 和 the only required block is a template block - in this case, an h1
标签. 它是组件的表示/视图. 它与样式和脚本块紧密绑定,因为它们决定了视图的样式和行为.
苗条的 is a library trying to bring modularity into the front-end game. 它不仅在分离不同组件方面保持了模块化,而且在隔离逻辑方面也保持了模块化, 视图, 还有模板.
\n\nReturning to the log-in form we’re building, let’s create a new 文件 LoginForm.苗条的
在 src
载有以下内容的资料夹:
\n\n\n\n
\n\nIt’s a dumb styled component that we’ll make smarter later. 要在我们的站点上看到这个组件,我们应该在根组件- 应用程序中渲染它. 让我们编辑 src /应用程序.苗条的
它看起来是这样的:
\n\n\n\n\n \n \n
\n\n如果所有操作都正确且应用程序仍在运行,那么我们的表单将出现在 localhost: 5000
. Let’s level up our 苗条的 skills by making the form smarter.
苗条的中的任何组件都可以拥有自己的状态. 状态是一个特殊变量或一组特殊变量,可以在模板内部使用. 为什么我要说"特别"? 每当这样的变量被更改时,模板就会收到通知,并以最新的状态呈现内容. This allows the application to react to 用户 interactions very fast.
\n\n我们会申报 电子邮件
和 密码
state 变量s w在这里 the form values for the appropriate fields will be stored. 这意味着我们的 电子邮件
和 密码
变量s will always be in sync with the form values, 因此,我们将随时准备提交这些值,而不必担心提交值与表单中的实际值之间存在任何差异.
\n\n\n\n\n\n
\n\n状态变量看起来像普通的JavaScript变量,但要使它们与表单值同步(将它们绑定到表单字段), 这是必须使用的 绑定:价值
指令. 还有一些不熟悉的东西:
:提交| preventDefault
是防止默认事件行为的简写吗. 这样比写要舒服得多 e.preventDefault ()
每一次.
{#if isLoading}正在登录...{:其他}登录🔒{/if}
是苗条的模板语法的一部分. 因为模板块中没有JS,所以有一个特殊的语法来使用if、循环等.
最后,让我们使用可用的选项,通过使用状态向表单添加验证. It can be achieved by creating another state 变量 错误
, which will be filled with 错误 when the form is 提交ted with invalid values.
\n\n\n\n\n
\n\n\n\n表格差不多填好了. The only thing that remains is a success mess年龄 upon successful authentication.
\n\nLet’s create a state 变量 for tracking successful submissions which is 假
默认情况下. After successful submission of a form, the value of this 变量 should be set to 真正的
.
let isSuccess = 假;\n
\n\n处理表单提交的函数也应该按照切换的逻辑进行修改 isSuccess
手术成功后.
const h和leSubmit = () => {\n 错误= {};\n 如果电子邮件.长度=== 0){\n 错误.电子邮件 = \"Field should not be empty\";\n }\n 如果密码.长度=== 0){\n 错误.密码 = \"Field should not be empty\";\n }\n 如果(对象.键(错误).长度=== 0){\n isLoading = 真正的;\n //模拟网络请求\n setTimeout(() => {\n isLoading = 假;\n isSuccess = 真正的;\n //授权用户\n }, 1000);\n }\n};\n
\n\n此修改使表单在提交完成后立即进入成功状态.
\n\n但是,如果检查开发服务器,则不会发现表单的行为有任何变化. We changed the code but haven’t touched the template yet. 我们需要向模板添加指令,以便在用户成功登录时显示成功消息. 苗条的’s template syntax allows us to implement that easily:
\n\n\n
\n\nWe have sorted out everything about the internal component’s state. Now it’s time to go through the external dependencies called properties, or “props”. Props是传递给组件的输入或参数,用于向组件描述应该出现的内容或组件应该如何表现.
\n\nDeclaration of a 财产 looks similar to the state, except for the 关键word 出口
.
\n\nThe answer is {answer}
\n
\n\n\n\n\n
\n\n这都是关于属性的. 声明和传递-所有你需要知道的使用道具.
\n\nBut how do these properties apply to the log-in form component? 通过将提交函数提取到属性中,Props可以使我们的登录表单更加通用. 它将允许您将此组件与您需要的任何提交操作(向测试服务器请求)一起使用, 请求到实际的服务器, 等.). 这个道具将被调用 提交
并且将是一个函数,如果提交操作成功,则返回已解决的承诺,如果有错误,则返回已拒绝的承诺. 让我们用上面给出的例子来声明这个道具:
出口让提交;\n
\n\nThe submission h和ler 在 log-in form should also be edited to use the new 提交
财产.
const h和leSubmit = () => {\n 错误= {};\n 如果电子邮件.长度=== 0){\n 错误.电子邮件 = \"Field should not be empty\";\n }\n 如果密码.长度=== 0){\n 错误.密码 = \"Field should not be empty\";\n }\n 如果(对象.键(错误).长度=== 0){\n isLoading = 真正的;\n 提交({电子邮件, 密码})\n .then(() => {\n isSuccess = 真正的;\n isLoading = 假;\n })\n .catch(err => {\n 错误.Server = err;\n isLoading = 假;\n });\n }\n};\n
\n\n组件似乎准备好了. 然而, 如果您返回表单并尝试提交它, you’ll notice that the state of the button has not changed from loading. 另外,在控制台中有一个异常: 未捕获的TypeError: 提交不是一个函数
. Of course, we declared the prop but forgot to pass it. Let’s declare a function in the app component 和 pass it to the log-in form.
const 提交 = ({ 电子邮件, 密码 }) =>\n new Promise((resolve, reject) => setTimeout(resolve, 1000));\n
\n\n\n \n \n
\n\n现在表单按预期工作了. It can both show 错误 和 inform the 用户 if the login has been successful.
\n\n\n\nIt seems that everything necessary to build an application is listed. With the properties 和 the inner state, we’re ready to go. 不过,这只是部分正确. These two general points make it possible to design high-complexity SPAs. 然而,如果您尝试在许多不同的组件之间共享数据,您会发现这非常困难.
\n\n最简单的例子是拥有全局可访问的 用户
变量. A lot of components should change their behavior related to the 用户, 取决于用户的角色, 年龄, 状态, 等. 然而, 通过使用props将用户传递给应用中的每个组件来重复我们自己并不是DRY.
苗条的对此有一个解决方案 上下文API.
\n\n\n\n\n上下文API为组件之间提供了一种“对话”机制,而无需像传递道具一样传递数据和函数或调度大量事件. 这是一个高级功能,但很有用.
\n
Let’s add the 用户 context to the log-in form we’re designing. 创建文件 用户Context.js
在 src
载有以下内容的资料夹:
出口 const 关键 = \"用户Context\";\n导出const initialValue = null;\n
\n\n关键
上下文的唯一标识符是否作为应用程序可能具有无限数量的必须保持可访问的不同上下文. initialValue
is just a default value for the context before it’s set.
The next step is to add the context to our application. 导航到 应用程序.苗条的
文件和添加2个import语句:
进口{ onMount, setContext } from \"苗条的\";\n进口{\n 键作为用户ContextKey,\n initialValue为用户ContextInitialValue\n} from \"./用户Context\";\n
\n\nLooking at the code above you may wonder what we are importing from the 苗条的
包. onMount
is a helper function requiring a callback function as an argument. 这个回调将在当前组件挂载时执行(在加载组件的最开始)。. setContext
是上下文的setter函数吗. It requires the 关键 to the context 和 a new value as its arguments.
让我们使用 onMount
为上下文设置默认值的函数:
onMount(() => {\n setContext (用户ContextKey 用户ContextInitialValue);\n});\n
\n\n然后修改 提交
设置用户上下文的函数:
const 提交 = ({ 电子邮件, 密码 }) =>\n new Promise((resolve, reject) => {\n setTimeout(() => {\n setContext (用户ContextKey, {\n name: \"Foo\",\n lastName: \"Bar\",\n 电子邮件: \"foo@bar.com\"\n });\n 解决();\n }, 1000);\n });\n
\n\n就是这样. 成功的提交会将用户上下文更改为一个假的用户对象,该对象可以通过上下文getter来访问 getContext
:
\n
\n\n苗条的 is a powerful tool capable of high performance 和 with a flexible API. 除了本文介绍的基本功能外,苗条的还有以下功能:
\n\n总而言之,苗条的是一个很好的库,可以满足构建spa的所有需求,甚至更多. It can compete with the biggest players in the market, 和 even win. What it could use right now, though, is support in the 前端开发人员的 社区.
\n\nNote: All the code in this article can be found in the teimurjan / 苗条的-login-form
GitHub库. 可以使用登录表单的演示 在这里.