简介: (A Brief Intro:)

In this tutorial, I’m going to build a plain Stencil app with a working analog clock. I will throw in a little Ionic for convenience as well, but that’s not the focus here. This tutorial will cover some of the more important basics to know about Stencil.

在本教程中,我将使用正常的模拟时钟构建一个普通的Stencil应用程序。 为了方便起见,我还将介绍一点Ionic,但这不是这里的重点。 本教程将介绍一些有关Stencil的重要基础知识。

While this is a low-level intro to Stencil, I’m going to assume that you’ve at least scanned the Stencil docs and have a basic idea of what JSX and Stencil are all about. You should probably be familiar with Typescript or at least ES6 as well.

虽然这是Stencil的低级介绍,但我将假设您至少已经扫描了Stencil文档,并对JSX和Stencil的用途有了基本了解。 您可能应该熟悉Typescript或至少还熟悉ES6。

较长的介绍: (A Longer Intro:)

In a previous post, I said I’d be “migrating” toward React because it’s outstripped Ionic. That’s a daunting proposition after 3 years in the Ionic realm. And what if React gets taken over in another year? Fortunately, the folks at Ionic are completely aware of this reality. Which is why they built stencil.js.

在上一篇文章中,我说过我将“迁移”到React,因为它超越了Ionic。 在离子领域三年后,这是一个令人生畏的提议。 如果React在另一年被接管怎么办? 幸运的是,Ionic的人们已经完全意识到了这一现实。 这就是为什么他们构建stencil.js。

Stencil uses Typescript and JSX as a super powerful, lightweight, non-framework. Stencil can be added to any other framework or used on its own to accomplish much of what someone would use Angular or React for.

Stencil使用Typescript和JSX作为超强大,轻巧的非框架。 模板可以添加到任何其他框架中,也可以单独使用以完成某人使用Angular或React的工作。

It’s also quick and easy to learn compared to larger frameworks. So it’s a great way to get used to the JSX/Web Component way of thinking. And if you want to migrate to React from Angular, or vice versa, Stencil can smooth your path.

与较大的框架相比,它也很容易上手。 因此,这是习惯JSX / Web Component思维方式的好方法。 而且,如果您想从Angular迁移到React,反之亦然,Stencil可以使您的道路顺畅。

Going forward I’ll be using Stencil in my personal projects. And Ionic 4 Components are now built on Stencil. So it’s a logical choice to future-proof your apps, whether you stay with Ionic/Angular or move to another framework.

展望未来,我将在个人项目中使用Stencil。 现在,Ionic 4组件基于Stencil构建。 因此,无论您使用Ionic / Angular还是迁移到其他框架,这都是对应用程序进行过时验证的合理选择。

As a side note for the JSX beginners. I find it’s easiest to forget about making everything into perfect Components and just write HTML. Then when I see a bit of HTML I’m going to use more than once or that I want to do something special, I’ll move it into its own Component.

作为JSX初学者的补充说明。 我发现忘记将所有内容变成完美的组件并只编写HTML是最容易的。 然后,当我看到一些HTML时,我将使用不止一次,或者我想做一些特殊的事情,将其移至其自己的Component中。

入门: (Getting Started:)

First off:

首先:

npm init stencil

Select component and use analog-clock-components as your project name, then:

选择component并使用analog-clock-components作为项目名称,然后:

cd analog-clock-components
npm install --save @ionic/core
npm start

If it all went to plan, you should see the default “Home” page pop up.

如果一切按计划进行,您应该会看到默认的“主页”页面弹出。

计时: (Making the Clock:)

I hate it when tutorials weigh you down with a bunch of information that isn’t critical to the core concepts. So that’s exactly what I’m going to do! I’ll be making the clock with SVG. But hey, it beats yet another fucking todo list example. And I promise to keep it simple.

当教程中的大量信息对核心概念不是很关键时,我会感到讨厌。 这就是我要做的! 我将使用SVG进行时钟。 但是,嘿,它击败了另一个他妈的待办事项清单示例。 我保证保持简单。

Watch out! Your Stencil component tags MUST have 2 or more words or your app will enigmatically fail with something like “clock” is not a valid custom element name!

小心! 您的Stencil组件标签必须包含2个或更多的单词,否则您的应用将因诸如“clock” is not a valid custom element name类的错误而失败!

Add a clock-face folder in the src/components directory like so:clock-face/clock-face.tsx and add the following contents.

src/components目录中添加一个Clock-face文件夹,如下所示: clock-face/clock-face.tsx并添加以下内容。

<script src="https://gist.github.com/leetheguy/8d3e5686ca097353d1fdf09ee1bbdc33.js"></script>import { Component } from '@stencil/core';@Component({tag: 'clock-face'
})
export class ClockFace {render() {return (<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><circle cx="100" cy="100" r="95" stroke-width="10px" stroke="black" fill="transparent"/><line id="hour-hand" x1="100" y1="100" x2="100" y2="60" stroke="black" stroke-width="10" stroke-linecap="round"/><line id="minute-hand" x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="8" stroke-linecap="round"/><line id="second-hand" x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="2" stroke-linecap="round"/></svg>);}
}

Then add analog-clock/analog-clock.tsx.

然后添加analog-clock/analog-clock.tsx

import { Component } from '@stencil/core';@Component({tag: 'analog-clock',
})
export class AnalogClock {render() {return [<div><clock-face/></div>];}
}

And now replace the my-component tag in index.html with <analog-clock\>

现在,将<analog-clock\> index.htmlmy-component标签替换为<analog-clock\>

You may have to restart the app, but you should now see this as your home page:

您可能必须重新启动应用程序,但是现在应该将其作为主页:

That bit of SVG was pretty painless, just a circle and a couple lines with a bit of style for aesthetics. The style can and should be applied with CSS in a non-trivial app.

SVG一点也不费力,只是一个圆圈和几行,带有一些美学风格。 该样式可以并且应该在非平凡的应用程序中与CSS一起应用。

Notice that I’ve used the <svg> tag as the root of this component. Neat! So far this clock is only right twice a day, so let’s add a few props to make it adjustable. I’m also going to add functions to convert time to degrees to rotate the hands. And I’m going to update the SVG to be able to rotate those hands.

注意,我已经使用<svg>标记作为该组件的根。 整齐! 到目前为止,这个时钟每天只有两次,所以,让我们添加一些道具使其可调。 我还将添加将时间转换为度数以旋转指针的函数。 而且我将更新SVG以能够旋转这些指针。

import { Component, Prop } from '@stencil/core';@Component({tag: 'clock-face'
})
export class ClockFace {@Prop() hour: number;@Prop() minute: number;@Prop() second: number;hourToDegrees(): number {return Math.floor(this.minute / 2) + (this.hour * 30);}minuteToDegrees(): number {return Math.floor(this.second / 10) + (this.minute * 6);}secondToDegrees(): number {return this.second * 6;}render() {return (<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><circle cx="100" cy="100" r="95" stroke-width="10" stroke="black" fill="transparent"/><line id="hour-hand" transform={`rotate(${this.hourToDegrees()}, 100, 100)`} x1="100" y1="100" x2="100" y2="60" stroke="black" stroke-width="10" stroke-linecap="round"/><line id="minute-hand" transform={`rotate(${this.minuteToDegrees()}, 100, 100)`} x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="8" stroke-linecap="round"/><line id="second-hand" transform={`rotate(${this.secondToDegrees()}, 100, 100)`} x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="2" stroke-linecap="round"/></svg>);}
}

And there we go. My component can now accept incoming variables via the @Prop() decorator and change how it’s displayed based on those variables. Let’s see this in action by updating the clock-face tag to <clock-face hour={12} minute={34} second={56}/> I’ve wrapped the numbers in curly brackets so they’ll be passed in as numbers instead of strings.

然后我们走了。 现在,我的组件可以通过@Prop()装饰器接受传入的变量,并根据这些变量更改其显示方式。 让我们通过将clock-face标记更新为<clock-face hour={12} minute={34} second={56}/>我将数字用大括号括起来,以便将它们传递进来作为数字而不是字符串。

滴答作响: (Making the Clock Tick:)

If you notice, the clock has no internal logic or time management abilities. It’s best to keep your components as simple as possible. Web Components are a bit like functional programming in that they should do just one thing. Stencil builds on the functional paradigm by making props immutable so that the component can’t affect anything outside of itself. They can fire off events, but that’s it.

如果您注意到,时钟没有内部逻辑或时间管理功能。 最好使您的组件尽可能简单。 Web组件有点像函数式编程,因为它们应该只做一件事。 模具通过使道具不可变来构建功能范式,从而使组件不会影响自身之外的任何东西。 他们可以触发事件,仅此而已。

Now I’m going to add getters to analog-clock.ts to get it to start ticking away.

现在,我将添加吸气剂到analog-clock.ts ,使其开始滴答作响。

import { Component } from '@stencil/core';@Component({tag: 'analog-clock',
})
export class AnalogClock {get hour(): number {let h: any = new Date().getHours();return h;}get minute(): number {let m: any = new Date().getMinutes();return m;}get second(): number {let s: any = new Date().getSeconds();return s;}render() {return (<div><clock-face hour={this.hour} minute={this.minute} second={this.second}/></div>);}
}

Wow! Look at that clock go… nowhere. The time is right, but it’s not ticking. If those of you following along at home are familiar with the Angular family, you may be expecting a ticking clock at this point. However, Stencil only re-renders upon certain conditions. This avoids the runaway train effect Angular developers know all too well. If you get a loop in your code or just have a lot of logic in a method that’s being called from HTML or a getter, your app can slow to a dead stop. It’s still possible for that to happen with Stencil, but it would almost have to be deliberate.

哇! 看着那钟走了……无处。 时间是对的,但没有滴答作响。 如果在家中跟随的那些人熟悉Angular家族,那么此时您可能会期待一个滴答作响的时钟。 但是,模具仅在某些条件下重新渲染。 这避免了Angular开发人员非常了解的火车失控效果。 如果您的代码中出现循环,或者从HTML或getter调用的方法中包含很多逻辑,则您的应用程序可能会停滞不前。 使用Stencil仍然有可能发生这种情况,但这几乎必须是故意的。

In order for Stencil to re-render, you have to use decorators like @Prop() or @State() to tell Stencil what data is important enough to cause the view to re-render. The state decorator is for managing internal variables, so I’m going to use that. I’m also going to tap into the Component lifecycle so that the timer doesn’t start until the component loads and so that it stops when the Component unloads.

为了重新渲染Stencil,必须使用@Prop()或@State()这样的修饰符来告诉Stencil哪些数据足够重要才能导致视图重新渲染。 状态装饰器用于管理内部变量,因此我将使用它。 我还将利用Component的生命周期,以使计时器在组件加载之前不会启动,并在组件卸载时停止计时。

import { Component, State } from '@stencil/core';@Component({tag: 'analog-clock',
})
export class AnalogClock {timer: number;@State() time: number = Date.now();componentDidLoad() {this.timer = window.setInterval(() => {this.time = Date.now();}, 250);}componentDidUnload() {clearInterval(this.timer);}get hour(): number {return new Date(this.time).getHours();}get minute(): number {return new Date(this.time).getMinutes();}get second(): number {return new Date(this.time).getSeconds();}render() {return (</div><clock-face hour={this.hour} minute={this.minute} second={this.second}/></div>);}
}

更改时区(一种): (Changing the Timezone (sort of):)

Next, I’m going to add a slider to allow me to pick a timezone. I’m not actually going to incorporate timezones though. It’s a complex feature that needs a whole other library (like moment.js for timezones) to manage properly. I’m just going to offset the hour by give-or-take 12 hours. It’s a kludgey fix, but it will illustrate how to get data back out of a component, which is a critical thing to know.

接下来,我将添加一个滑块以允许我选择时区。 我实际上并不会合并时区。 这是一项复杂的功能,需要整个其他库( 例如timezone的moment.js )才能正确管理。 我只是通过允许或取消12小时来抵消时间。 这是一个繁琐的修复程序,但是它将说明如何从组件中取回数据,这是要了解的关键。

Now I’m going to add a time-zone-slider component just like I did with the analog clock, like so time-zone-slider/time-zone-slider.tsx.

现在,我将像添加模拟时钟一样添加一个时区滑块组件,就像time-zone-slider/time-zone-slider.tsx

import { Component, Prop, Event, EventEmitter } from '@stencil/core';
import '@ionic/core';@Component({tag: 'time-zone-slider'
})
export class TimeZoneSlider {@Prop() offset: number;@Event() timeZoneChanged: EventEmitter;positionChanged(event: CustomEvent) {this.timeZoneChanged.emit(event.detail.value)}render() {return (<ion-rangedebounce={500}max={12}min={-12}pin={true}snaps={true}step={1}value={this.offset}onIonChange={event => this.positionChanged(event)}><ion-label slot="start">-12</ion-label><ion-label slot="end">12</ion-label></ion-range>);}
}

Notice that I imported the @ionic/core library here. This may be overkill, especially in an app where you have no intention of using Ionic components. I just found this to be the easiest way to implement a slider so I could finish this tutorial before the end of the year.

注意,我在这里导入了@ionic/core库。 这可能是过大的,尤其是在您无意使用离子组件的应用程序中。 我只是发现这是实现滑块的最简单方法,因此我可以在年底之前完成本教程。

This component also has no internal logic. It doesn’t even manage its own state. It receives the offset as a @Prop(). And when the slider moves, it emits an @Event() to the parent, letting it know about the new value. It is then the parent’s responsibility to manage the state and update the child when the offset changes. Or the parent may also be passing in a value managed by the state of one of its ancestors.

该组件也没有内部逻辑。 它甚至不管理自己的状态。 它以@Prop()形式接收偏移量。 当滑块移动时,它会向父级发出一个@Event(),让其知道新值。 然后,当偏移量发生变化时,父母有责任管理状态并更新孩子。 或者,父级也可能传入由其祖先之一的状态管理的值。

import { Component, State, Listen } from '@stencil/core';@Component({tag: 'analog-clock',
})
export class AnalogClock {timer: number;@State() time: number = Date.now();@State() timeZone: number = 0;@Listen('timeZoneChanged')timeZoneChangedHandler(event: CustomEvent) {this.timeZone = event.detail;}componentDidLoad() {this.timer = window.setInterval(() => {this.time = Date.now();}, 250);}componentDidUnload() {clearInterval(this.timer);}get hour(): number {return new Date(this.time).getHours();}get minute(): number {return new Date(this.time).getMinutes();}get second(): number {return new Date(this.time).getSeconds();}render() {return (<div><clock-face hour={this.hour + this.timeZone} minute={this.minute} second={this.second}/><time-zone-slider offset={this.timeZone}/></div>     );}
}

In analog-clock, I just added a timeZone state manager. I also added the @Listen() decorator to the timeZoneChangedHandler function. That function updates the timeZone state. I changed the clock-face element to offset the hour based on the timeZone. Finally, I added the slider element and passed in the current timeZone, completing the loop.

在模拟时钟中,我刚刚添加了timeZone状态管理器。 我还将@Listen()装饰器添加到timeZoneChangedHandler函数。 该函数将更新timeZone状态。 我更改了clock-face元素以根据timeZone偏移小时。 最后,我添加了Slider元素并传入了当前的timeZone,完成了循环。

摘要: (Summary:)

I just touched on about 80% of what you need to know to get started using Stencil. We’ve covered creating and implementing Components and handling their lifecycles. We covered firing and listening for Events. We covered passing data to children Components with Props. And we covered handling internal Component State. That’s actually about half of the features listed in the Components section of the Stencil docs.

我刚谈到您开始使用Stencil时需要知道的大约80%。 我们已经介绍了创建和实现组件以及处理其生命周期的内容。 我们介绍了开火和收听事件。 我们介绍了通过道具向子组件传递数据的方法。 并且我们讨论了处理内部组件状态。 实际上,这大约是Stencil文档的Components部分中列出的功能的一半。

翻译自: https://www.freecodecamp.org/news/angular-ionic-react-vue-future-proof-your-app-with-stencil-js/

Angular / Ionic,React,Vue? 使用Stencil.js面向未来的应用程序!相关推荐

  1. AVG.js ——面向未来的文字冒险游戏框架

    AVG.js 是一款开源 Web 游戏框架,以成为新一代的 AVG 类游戏制作框架为目标,兼顾与之相近的其他游戏类型,例如解谜.卡牌等. 一. 1.安装 npm install -g avg-cli ...

  2. 我从Angular 2转向Vue.js, 也没有选择React

    译者按: 通过使用Angular的经历,作者已经完全转为Vue粉了!我们Fundebug目前还是用AngularJS 1,坦白说,学习曲线蛮陡的. 原文: Why we moved from Angu ...

  3. 2017html5框架排名,2017年最主流前端框架比较:Angular、React 和 Vue

    如果你是一名前端开发人员,或者是想要学习web前端开发技术的小伙伴,必须要了解的这三款最主流的前端框架.不仅可以帮助你拿到高薪,也能够提升你的编程思想. 目前前端开发技术主要可以分成四个方面: 1.前 ...

  4. Angular、React、Vue.js 等 6 大主流 Web 框架都有什么优缺点?

    来自:开源中国 协作翻译 链接:oschina.net/translate/web-frameworks-conclusions 原文:sitepen.com/blog/2017/11/10/web- ...

  5. Angular、React 当前,Vue.js 优劣几何?

    在过去一年里,前端开发发展迅速,前端工程师的薪资亦是水涨船高.2019 更是热度不减,而作为近年来尤为热门的前端框架,Vue.js 自是积累了大量关注.那么,Vue.js 是适合你的框架吗? 作者 | ...

  6. Angular、React、Vue.js 等 6 大主流 Web 框架都有什么优缺点

    在这篇文章中,我们将对这个系列中所提到的每款框架做一个总结,包括我们所认为的强项和弱项.另外,我们为你留下了一些值得思考的问题. 我是否需要使用框架? 如果不尝试回答这个问题就是我们的失职,这越来越成 ...

  7. angular js 使用pdf.js_胶水(框架) Stencil.js

    去年的同一时间,我写了那篇<前端下半场:构建跨框架的 UI 库>推荐了 Stencil.js,当时是在项目的试验期.而 Stencil.js 已经在今年(2019 )的 6 月份,推出了 ...

  8. Vue为什么能逆袭 Angular和React成为主流前端框架?

    作者 | Maja Nowak  译者 | 苏本如  责编 | 屠敏 来源:CSDN https://www.monterail.com/blog/reasons-why-vuejs-is-popul ...

  9. RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景?

    RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景? RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景? - 知乎 https://www ...

最新文章

  1. 20款效果非常棒的 jQuery 插件分享
  2. 高并发01_synchronized
  3. QML 实现图片帧渐隐渐显轮播
  4. java 读取 excel poi_java poi怎么获取excel单元格的内容?
  5. 李航书上隐马尔科夫模型案例的实验结果复现
  6. python的convert_python编程开发之类型转换convert实例分析
  7. Spring Boot 中使用MyBatis Mapper方式(xml)
  8. 二叉树的构建--BST
  9. [Ubuntu] change mouse scrolling between standard and natural
  10. opencv出错:error: (-213:The function/feature is not implemented) Unknown/unsupported array type
  11. 软件产品功能思维导图
  12. Java项目:宠物店管理系统(java+JSP+JavaScript+Bootstrap+Mysql)
  13. Firefox国际版上登录本地服务
  14. win10 串口驱动下载链接
  15. poi ppt html,POI之PPT如何添加表格简单实例
  16. 如何批量下载央视CNTV的节目视频
  17. 适合计算机的音乐,好听的适合做电脑开机音乐的歌
  18. 关于eWebEditor-在线HTML编辑器控…
  19. 如何使用计算机上合并计算方法,excel合并计算的方法步骤详解
  20. 评:日本的“泡沫”代价

热门文章

  1. 案例 TreeView动态控制节点 c# 1614264758
  2. 学习日报 1026 使用属性升级MyBank
  3. django-csrftoken跨站请求伪造
  4. jquery-ui寺
  5. BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块
  6. Request 部分功能
  7. 【按位dp】文盲的学习方法
  8. centos6/7 yum安装mysql客户端和rpm包方式安装方式
  9. 一起Polyfill系列:让Date识别ISO 8601日期时间格式
  10. 怎样通过FineReader 的“文本”窗口检查文本