作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.< / div >< / div >
Teimur是一名全栈开发人员,主要使用JavaScript、Go和Python. 他在Docker和Jenkins CI/CD方面也很有经验.
上面的代码包含三个部分:
script 标签, 这是一个可选的JavaScript块与变量和函数声明,应该在组件内使用.
script
style 标记,它是另一个可选块. 除了一个重要的区别之外,它与普通的HTML样式标签非常相似. 该块中描述的规则仅适用于该组件. 将样式应用于 p 元素不会影响页面上的所有段落. 这是非常棒的,因为您不必提出类名,并且您永远不会意外地覆盖另一个规则.
style
p
最后一个也是唯一需要的块是模板块——在本例中是一个 h1 标签. 它是组件的表示/视图. 它与样式和脚本块紧密绑定,因为它们决定了视图的样式和行为.
h1
苗条的是一个试图将模块化引入前端游戏的库. 它不仅在分离不同组件方面保持了模块化,而且在隔离逻辑方面也保持了模块化, 视图, 还有模板.
回到我们正在构建的登录表单,让我们创建一个新文件 LoginForm.苗条的 在 src 载有以下内容的资料夹:
LoginForm.苗条的
src
👤 Email Log in 🔒
这是一个愚蠢风格的组件,我们稍后会让它变得更聪明. 要在我们的站点上看到这个组件,我们应该在根组件- 应用程序中渲染它. 让我们编辑 src /应用程序.苗条的 它看起来是这样的:
src /应用程序.苗条的
如果所有操作都正确且应用程序仍在运行,那么我们的表单将出现在 localhost: 5000. 让我们通过使表单更智能来提升我们的苗条技能.
localhost: 5000
苗条的中的任何组件都可以拥有自己的状态. 状态是一个特殊变量或一组特殊变量,可以在模板内部使用. 为什么我要说"特别"? 每当这样的变量被更改时,模板就会收到通知,并以最新的状态呈现内容. 这使得应用程序能够非常快速地对用户交互做出反应.
我们会申报 电子邮件 和 密码 将存储相应字段的表单值的状态变量. 这意味着我们的 电子邮件 和 密码 变量将始终与表单值保持同步, 因此,我们将随时准备提交这些值,而不必担心提交值与表单中的实际值之间存在任何差异.
电子邮件
密码
👤 Email {#if isLoading}正在登录...{:其他}登录🔒{/if}
状态变量看起来像普通的JavaScript变量,但要使它们与表单值同步(将它们绑定到表单字段), 这是必须使用的 绑定:价值 指令. 还有一些不熟悉的东西:
绑定:价值
:提交| preventDefault 是防止默认事件行为的简写吗. 这样比写要舒服得多 e.preventDefault () 每一次.
:提交| preventDefault
e.preventDefault ()
{#if isLoading}正在登录...{:其他}登录🔒{/if} 是苗条的模板语法的一部分. 因为模板块中没有JS,所以有一个特殊的语法来使用if、循环等.
{#if isLoading}正在登录...{:其他}登录🔒{/if}
最后,让我们使用可用的选项,通过使用状态向表单添加验证. 它可以通过创建另一个状态变量来实现 错误,当表单以无效值提交时,它将被错误填充.
错误
👤 Email {#if isLoading}正在登录...{:其他}登录🔒{/if} {#如果对象.键(错误).length > 0} {#每个对象.键(错误)作为字段} {field}: {错误[field]} {/每个} {/if}
表格差不多填好了. 唯一剩下的是在身份验证成功时的成功消息.
让我们创建一个状态变量来跟踪成功的提交 假 默认情况下. 成功提交表单后,该变量的值应设置为 真正的.
假
真正的
let isSuccess = 假;
处理表单提交的函数也应该按照切换的逻辑进行修改 isSuccess 手术成功后.
isSuccess
const h和leSubmit = () => { 错误= {}; 如果电子邮件.长度=== 0){ 错误.电子邮件 = "字段不能为空"; } 如果密码.长度=== 0){ 错误.密码 = "字段不能为空"; } 如果(对象.键(错误).长度=== 0){ isLoading = 真正的; //模拟网络请求 setTimeout(() => { isLoading = 假; isSuccess = 真正的; //授权用户 }, 1000); } };
此修改使表单在提交完成后立即进入成功状态.
但是,如果检查开发服务器,则不会发现表单的行为有任何变化. 我们修改了代码,但还没有修改模板. 我们需要向模板添加指令,以便在用户成功登录时显示成功消息. 苗条的的模板语法允许我们轻松实现:
{#如果isSuccess} 🔓 您已成功登录. {:其他} 👤 Email {#if isLoading}正在登录...{:其他}登录🔒{/if} {#如果对象.键(错误).length > 0} {#每个对象.键(错误)作为字段} {field}: {错误[field]} {/每个} {/if} {/if}
我们已经整理了关于内部组件状态的所有内容. 现在我们来看看外部依赖项,也就是属性或道具. Props是传递给组件的输入或参数,用于向组件描述应该出现的内容或组件应该如何表现.
属性的声明与状态类似,只是关键字不同 出口.
出口
The answer is {answer}
这都是关于属性的. 声明和传递-所有你需要知道的使用道具.
但是这些属性如何应用于登录表单组件呢? 通过将提交函数提取到属性中,Props可以使我们的登录表单更加通用. 它将允许您将此组件与您需要的任何提交操作(向测试服务器请求)一起使用, 请求到实际的服务器, 等.). 这个道具将被调用 提交 并且将是一个函数,如果提交操作成功,则返回已解决的承诺,如果有错误,则返回已拒绝的承诺. 让我们用上面给出的例子来声明这个道具:
提交
出口让提交;
登录表单中的提交处理程序也应该编辑为使用new 提交 财产.
const h和leSubmit = () => { 错误= {}; 如果电子邮件.长度=== 0){ 错误.电子邮件 = "字段不能为空"; } 如果密码.长度=== 0){ 错误.密码 = "字段不能为空"; } 如果(对象.键(错误).长度=== 0){ isLoading = 真正的; 提交({电子邮件, 密码}) .then(() => { isSuccess = 真正的; isLoading = 假; }) .catch(err => { 错误.Server = err; isLoading = 假; }); } };
组件似乎准备好了. 然而, 如果您返回表单并尝试提交它, 您会注意到按钮的状态在加载后没有改变. 另外,在控制台中有一个异常: 未捕获的TypeError: 提交不是一个函数. 当然,我们申报了道具,但忘记通过了. 让我们在app组件中声明一个函数,并将其传递给登录表单.
未捕获的TypeError: 提交不是一个函数
const 提交 = ({ 电子邮件, 密码 }) => new Promise((resolve, reject) => setTimeout(resolve, 1000));
现在表单按预期工作了. 它既可以显示错误,也可以通知用户登录是否成功.
似乎列出了构建应用程序所需的一切. 有了性质和内部状态,我们就可以开始了. 不过,这只是部分正确. 这两点使得设计高复杂性spa成为可能. 然而,如果您尝试在许多不同的组件之间共享数据,您会发现这非常困难.
最简单的例子是拥有全局可访问的 用户 变量. 许多组件应该改变与用户相关的行为, 取决于用户的角色, 年龄, 状态, 等. 然而, 通过使用props将用户传递给应用中的每个组件来重复我们自己并不是DRY.
用户
苗条的对此有一个解决方案 上下文API.
上下文API为组件之间提供了一种“对话”机制,而无需像传递道具一样传递数据和函数或调度大量事件. 这是一个高级功能,但很有用.
让我们将用户上下文添加到正在设计的登录表单中. 创建文件 用户Context.js 在 src 载有以下内容的资料夹:
用户Context.js
出口 const 关键 = "用户Context"; 导出const initialValue = null;
关键 上下文的唯一标识符是否作为应用程序可能具有无限数量的必须保持可访问的不同上下文. initialValue 只是在设置之前上下文的默认值吗.
关键
initialValue
下一步是将上下文添加到应用程序中. 导航到 应用程序.苗条的 文件和添加2个import语句:
应用程序.苗条的
从“苗条的”导入{onMount, setContext}; 进口{ 键作为用户ContextKey, initialValue为用户ContextInitialValue } from“./ 用户Context”;
查看上面的代码,您可能想知道我们正在从 苗条的 包. onMount 辅助函数需要回调函数作为参数吗. 这个回调将在当前组件挂载时执行(在加载组件的最开始)。. setContext 是上下文的setter函数吗. 它需要上下文的键和一个新值作为参数.
苗条的
onMount
setContext
让我们使用 onMount 为上下文设置默认值的函数:
onMount(() => { setContext (用户ContextKey 用户ContextInitialValue); });
然后修改 提交 设置用户上下文的函数:
const 提交 = ({ 电子邮件, 密码 }) => new Promise((resolve, reject) => { setTimeout(() => { setContext (用户ContextKey, { 名称:“Foo”, 姓:“酒吧”, 电子邮件:“foo@bar.com” }); 解决(); }, 1000); });
就是这样. 成功的提交会将用户上下文更改为一个假的用户对象,该对象可以通过上下文getter来访问 getContext:
getContext
苗条的是一个功能强大的工具,具有高性能和灵活的API. 除了本文介绍的基本功能外,苗条的还有以下功能:
总而言之,苗条的是一个很好的库,可以满足构建spa的所有需求,甚至更多. 它可以与市场上最大的玩家竞争,甚至获胜. 但是,它现在可以使用的是 前端开发人员的 社区.
注意:本文中的所有代码都可以在 teimurjan / 苗条的-login-form GitHub库. 可以使用登录表单的演示 在这里.
teimurjan / 苗条的-login-form
苗条的在构建阶段被编译成纯JavaScript, 因此,应用程序不需要依赖项就可以启动.
一个苗条的组件可能包含三个部分:脚本、样式和模板. 前两个, 哪些修改组件的外观和行为, 是可选的, 模板部分是必需的.
苗条的在模板块中提供了一个增强版的HTML,带有变量等额外特性, 有条件的块, 循环块, async-await块, 和更多的.
你可以使用苗条的的Context API来共享数据——这是一种组件连接的机制,无需将数据作为属性传递或调度大量事件.
苗条组件允许拥有内部状态或接受外部属性. 只要状态或属性的一部分发生了变化,模板就会立即做出反应.
位于 比什凯克,Chuy省,吉尔吉斯斯坦
成员自 2018年5月1日