【sciter】案例 TodoList 带你入门 sciter 组件化编程

编程入门 行业动态 更新时间:2024-10-11 05:21:51

【sciter】案例 TodoList <a href=https://www.elefans.com/category/jswz/34/1769690.html style=带你入门 sciter 组件化编程"/>

【sciter】案例 TodoList 带你入门 sciter 组件化编程

案例 TodoList 带你入门 sciter 组件化编程

下诉案例已基本覆盖 sciter 组件化编程所涉及到的内容,及注意细节

1、效果图




2、技术要点

  • JSX 组件化编程(类组件)
  • 组件间如何通信
  • 组件生命周期
  • 组件如何绑定事件
  • 如何处理组件中 this 指向
  • 模块化 CSS

3、如何使用

<div class="container"></div>
<script type="module">import { TodoList } from './component/index.js';document.$(`.container`).content(<TodoList />);
</script>

4、组件 TodoList 源码

export class TodoList extends Element {value;list = [];constructor(props) {super(); // 必写}// 组件挂载componentDidMount() { }// 组件销毁前componentWillUnmount() { }componentUpdate(newdata) {if (typeof newdata == "object") {Object.assign(this, newdata);}this.post(() => this.patch(this.render()));}render() {return (<div styleset={__DIR__ + "index.css#todolist"}><div class="header"><div class="info">To-Do List</div></div><div class="title">~Today I need to ~</div><div class="form"><div class="form-input"><input type="text" placeholder="Add new todo..." value={this.value} onchange={(event) => this.value = event.target.value} /><button onclick={this.submit}><span class="submit">Submit</span></button></div></div>{this.list.length == 0 && (<div class="empty-todos"><svg class="icon" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="clipboard-check" role="img" xmlns="" viewBox="0 0 384 512" data-v-132cabf7=""><path class="" fill="currentColor" d="M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm121.2 231.8l-143 141.8c-4.7 4.7-12.3 4.6-17-.1l-82.6-83.3c-4.7-4.7-4.6-12.3.1-17L99.1 285c4.7-4.7 12.3-4.6 17 .1l46 46.4 106-105.2c4.7-4.7 12.3-4.6 17 .1l28.2 28.4c4.7 4.8 4.6 12.3-.1 17z"></path></svg><span class="todos-text">Congrat, you have no more tasks to do</span></div>)}{this.list.length != 0 && (<List data={this.list}finshed={this.finshed}del={this.del}/>)}</div>);}// 提交submit = (event) => {const value = this.value.trim();if (value.length != 0) {this.list.unshift({id: Math.random(),text: value,state: false});thisponentUpdate({value: "",list: this.list});}}// 完成finshed = (data) => {const i = this.list.findIndex(item => item.id == data.id);if (i != -1) this.list[i].state = true;thisponentUpdate({ list: this.list });}// 删除del = (data) => {data.forEach(item1 => {const i = this.list.findIndex(item2 => item2.id == item1.id);this.list.splice(i, 1);});thisponentUpdate({ list: this.list });}
}

5、List 组件源码

class List extends Element {id; // 组件 idDom; // 组件 DOMdata = [];finshed; // 回调 del; // 回调key = 'All';constructor(props) {super();// 生成唯一 idthis.id = `list-${Math.ceil(Math.random() * 100)}`;this.data = props.data;this.finshed = props.finshed;this.del = props.del;}// 挂载前componentDidMount() {// 保存 list 组件的 Dom 元素this.Dom = document.querySelector(`#${this.id}`);}componentUpdate(newData) {if (typeof newdata == "object") {this.data = newData.data;this.key = newData.key;}this.post(() => this.patch(this.render()));}render(props, kids) {const activeLen = this.data.filter(item => item.state).length;const state = this.data.some(item => item.state);const len = this.data.length;return (<div styleset={__DIR__ + "index.css#list"} id={this.id}><ul class="list">{this.data.map(item => {return (/* key={Math.random()} 使其重新渲染 */<li class={item.state ? 'item active' : 'item'} onclick={this.itemFinshed.bind(this, item)} tag={item.id} key={Math.random()}><i class='state-icon'></i><span class='text'>{item.text} </span><i class='close-icon' onclick={() => this.itemDel(item)}></i></li>)})}</ul><div class="detail"><span>{len} item left</span><span class={this.key == 'All' ? 'state-active' : ''} onclick={this.itemFilter.bind(this, 'All')}>All</span><span class={this.key == 'Active' ? 'state-active' : ''} style={(state && activeLen != len) ? '' : 'display: none'} onclick={this.itemFilter.bind(this, 'Active')}>Active</span><span class={this.key == 'Completed' ? 'state-active' : ''} style={(state && activeLen != len) ? '' : 'display: none'} onclick={this.itemFilter.bind(this, 'Completed')}>Completed</span><span class={this.key == 'Clear completed' ? 'state-active' : ''} style={state ? '' : 'display: none'} onclick={this.clearCompleted.bind(this)}>Clear completed</span></div></div>)}// 完成itemFinshed = (item, event) => {if (!event.target.classList.contains('close-icon')) {this.finshed && this.finshed(item);}}// 删除itemDel = (item) => {this.del && this.del([item]);}// 清除完成clearCompleted = () => {const completedList = this.data.filter(item => item.state);this.del && this.del(completedList);} // 过滤itemFilter = (key) => {const children = this.Dom.querySelector(`.list`).children;const stateList = this.Dom.querySelector(`.detail`).children;Array.from(stateList).forEach(item => { item.classList.remove('state-active') });const activeList = this.data.filter(item => !item.state);const completedList = this.data.filter(item => item.state);// 手动操作 DOMArray.from(children).forEach(item => {const id = item.getAttribute('tag');if (key == 'All') {stateList[1].classList.add('state-active');Object.assign(item.style, { display: 'block' });}if (key == 'Active') {stateList[2].classList.add('state-active');const i = activeList.findIndex(activeItem => activeItem.id == id);const style = i != -1 ? { display: 'block' } : { display: 'none' };Object.assign(item.style, style);}if (key == 'Completed') {stateList[3].classList.add('state-active');const i = completedList.findIndex(activeItem => activeItem.id == id);const style = i != -1 ? { display: 'block' } : { display: 'none' };Object.assign(item.style, style);}});}
}

6、模块化 CSS

以下 CSS代码 为 TodoList 的 CSS 样式,可以结合 TodoList 中 render() 渲染方法中的 DOM 结构

/* 模块化 css */@set todolist {:root {padding: 30px 40px 20px;text-align: center;width: 440px;max-width: 100%;margin: 0 auto;border-radius: 15px;background: #f2f2f2;}:root .header {height: 88px;width: 240px;margin: auto;flow: horizontal;}:root .header::before {content: "";dispaly: inline-block;width: 88px;height: 88px;background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCgkgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHBhdGggc3R5bGU9ImZpbGw6I0YyOUMxRjsiIGQ9Ik0yODkuNjU1LDQyMC4xOTNsMjE2LjI3Ni0yMTYuMjc2YzcuOTQ1LTcuOTQ1LDcuOTQ1LTIyLjA2OSwwLTMwLjAxNGwtMTYuNzcyLTE2Ljc3MgoJYy05LjcxLTkuNzEtMjUuNi05LjcxLTM1LjMxLDBMMjQwLjIyMSwzNzAuNzU5TDI4OS42NTUsNDIwLjE5M3oiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0NDQjM3NTsiIGQ9Ik0yODkuNjU1LDQyMC4xOTNsLTQ5LjQzNC00OS40MzRsMTQ4LjMwMy0xNDguMzAzVjM1LjMxYzAtOS43MS03Ljk0NS0xNy42NTUtMTcuNjU1LTE3LjY1NUgyNjQuOTM4CglWOC44MjhjMC01LjI5Ny0zLjUzMS04LjgyOC04LjgyOC04LjgyOEgxMzIuNTI0Yy01LjI5NywwLTguODI4LDMuNTMxLTguODI4LDguODI4djguODI4SDE3Ljc2NkM4LjA1NSwxNy42NTUsMC4xMSwyNS42LDAuMTEsMzUuMzEKCXY0NTkuMDM0YzAsOS43MSw3Ljk0NSwxNy42NTUsMTcuNjU1LDE3LjY1NWgzNTMuMTAzYzkuNzEsMCwxNy42NTUtNy45NDUsMTcuNjU1LTE3LjY1NVYzMjIuMjA3TDI4OS42NTUsNDIwLjE5M3oiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0VDRjBGMTsiIGQ9Ik0yODkuNjU1LDQyMC4xOTNsLTQ5LjQzNC00OS40MzRsMTEyLjk5My0xMTIuOTkzVjYxLjc5M2MwLTUuMjk3LTMuNTMxLTguODI4LTguODI4LTguODI4aC03OS40NDgKCXY4LjgyOGMwLDUuMjk3LTMuNTMxLDguODI4LTguODI4LDguODI4SDEzMi41MjRjLTUuMjk3LDAtOC44MjgtMy41MzEtOC44MjgtOC44Mjh2LTguODI4SDQ0LjI0OGMtNS4yOTcsMC04LjgyOCwzLjUzMS04LjgyOCw4LjgyOAoJdjQwNi4wNjljMCw1LjI5NywzLjUzMSw4LjgyOCw4LjgyOCw4LjgyOGgzMDAuMTM4YzUuMjk3LDAsOC44MjgtMy41MzEsOC44MjgtOC44MjhWMzU3LjUxN0wyODkuNjU1LDQyMC4xOTN6Ii8+CjxwYXRoIHN0eWxlPSJmaWxsOiNBRjk3NjI7IiBkPSJNMjU2LjExLDcwLjYyMUgxMzIuNTI0Yy01LjI5NywwLTguODI4LTMuNTMxLTguODI4LTguODI4VjguODI4YzAtNS4yOTcsMy41MzEtOC44MjgsOC44MjgtOC44MjgKCUgyNTYuMTFjNS4yOTcsMCw4LjgyOCwzLjUzMSw4LjgyOCw4LjgyOHY1Mi45NjZDMjY0LjkzOCw2Ny4wOSwyNjEuNDA3LDcwLjYyMSwyNTYuMTEsNzAuNjIxIi8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiNFNkU3RTg7IiBwb2ludHM9IjQ4My44NjIsMjI2Ljg2OSA0NDUuOTAzLDI2NC44MjggMzk2LjQ2OSwyMTQuNTEgNDMzLjU0NSwxNzcuNDM0ICIvPgo8cGF0aCBzdHlsZT0iZmlsbDojRUVEREM4OyIgZD0iTTI0Mi44NjksNDM4LjczMWw0Ni43ODYtMTcuNjU1bC00OS40MzQtNTAuMzE3bC0xNy42NTUsNDYuNzg2CglDMjE3LjI2OSw0MzAuNzg2LDIyOS42MjgsNDQ0LjAyOCwyNDIuODY5LDQzOC43MzEiLz4KPGc+Cgk8cGF0aCBzdHlsZT0iZmlsbDojNzk2ODNCOyIgZD0iTTIzOC40NTUsMTQxLjI0MWgtODguMjc2Yy01LjI5NywwLTguODI4LTMuNTMxLTguODI4LTguODI4YzAtNS4yOTcsMy41MzEtOC44MjgsOC44MjgtOC44MjhoODguMjc2CgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhDMjQ3LjI4MywxMzcuNzEsMjQzLjc1MiwxNDEuMjQxLDIzOC40NTUsMTQxLjI0MXoiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMzAwLjI0OCwxOTQuMjA3aC01Mi45NjVjLTUuMjk3LDAtOC44MjgtMy41MzEtOC44MjgtOC44MjhzMy41MzEtOC44MjgsOC44MjgtOC44MjhoNTIuOTY1CgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhTMzA1LjU0NSwxOTQuMjA3LDMwMC4yNDgsMTk0LjIwN3oiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMjExLjk3MiwxOTQuMjA3SDg4LjM4NmMtNS4yOTcsMC04LjgyOC0zLjUzMS04LjgyOC04LjgyOHMzLjUzMS04LjgyOCw4LjgyOC04LjgyOGgxMjMuNTg2CgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhTMjE3LjI2OSwxOTQuMjA3LDIxMS45NzIsMTk0LjIwN3oiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMzAwLjI0OCwyMjkuNTE3aC0yNi40ODNjLTUuMjk3LDAtOC44MjgtMy41MzEtOC44MjgtOC44MjhzMy41MzEtOC44MjgsOC44MjgtOC44MjhoMjYuNDgzCgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhTMzA1LjU0NSwyMjkuNTE3LDMwMC4yNDgsMjI5LjUxN3oiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMjM4LjQ1NSwyMjkuNTE3aC03MC42MjFjLTUuMjk3LDAtOC44MjgtMy41MzEtOC44MjgtOC44MjhzMy41MzEtOC44MjgsOC44MjgtOC44MjhoNzAuNjIxCgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhTMjQzLjc1MiwyMjkuNTE3LDIzOC40NTUsMjI5LjUxN3oiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMTMyLjUyNCwyMjkuNTE3SDg4LjM4NmMtNS4yOTcsMC04LjgyOC0zLjUzMS04LjgyOC04LjgyOHMzLjUzMS04LjgyOCw4LjgyOC04LjgyOGg0NC4xMzgKCQljNS4yOTcsMCw4LjgyOCwzLjUzMSw4LjgyOCw4LjgyOFMxMzcuODIxLDIyOS41MTcsMTMyLjUyNCwyMjkuNTE3eiIvPgoJPHBhdGggc3R5bGU9ImZpbGw6Izc5NjgzQjsiIGQ9Ik0zMDAuMjQ4LDI2NC44MjhoLTcwLjYyMWMtNS4yOTcsMC04LjgyOC0zLjUzMS04LjgyOC04LjgyOGMwLTUuMjk3LDMuNTMxLTguODI4LDguODI4LTguODI4aDcwLjYyMQoJCWM1LjI5NywwLDguODI4LDMuNTMxLDguODI4LDguODI4QzMwOS4wNzYsMjYxLjI5NywzMDUuNTQ1LDI2NC44MjgsMzAwLjI0OCwyNjQuODI4eiIvPgoJPHBhdGggc3R5bGU9ImZpbGw6Izc5NjgzQjsiIGQ9Ik0xOTQuMzE3LDI2NC44MjhoLTUyLjk2NmMtNS4yOTcsMC04LjgyOC0zLjUzMS04LjgyOC04LjgyOGMwLTUuMjk3LDMuNTMxLTguODI4LDguODI4LTguODI4aDUyLjk2NgoJCWM1LjI5NywwLDguODI4LDMuNTMxLDguODI4LDguODI4QzIwMy4xNDUsMjYxLjI5NywxOTkuNjE0LDI2NC44MjgsMTk0LjMxNywyNjQuODI4eiIvPgoJPHBhdGggc3R5bGU9ImZpbGw6Izc5NjgzQjsiIGQ9Ik0xMDYuMDQxLDI2NC44MjhIODguMzg2Yy01LjI5NywwLTguODI4LTMuNTMxLTguODI4LTguODI4YzAtNS4yOTcsMy41MzEtOC44MjgsOC44MjgtOC44MjhoMTcuNjU1CgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhDMTE0Ljg2OSwyNjEuMjk3LDExMS4zMzgsMjY0LjgyOCwxMDYuMDQxLDI2NC44Mjh6Ii8+Cgk8cGF0aCBzdHlsZT0iZmlsbDojNzk2ODNCOyIgZD0iTTI0Ny4yODMsMzAwLjEzOGgtNTIuOTY2Yy01LjI5NywwLTguODI4LTMuNTMxLTguODI4LTguODI4czMuNTMxLTguODI4LDguODI4LTguODI4aDUyLjk2NgoJCWM1LjI5NywwLDguODI4LDMuNTMxLDguODI4LDguODI4UzI1Mi41NzksMzAwLjEzOCwyNDcuMjgzLDMwMC4xMzh6Ii8+Cgk8cGF0aCBzdHlsZT0iZmlsbDojNzk2ODNCOyIgZD0iTTE1OS4wMDcsMzAwLjEzOEg4OC4zODZjLTUuMjk3LDAtOC44MjgtMy41MzEtOC44MjgtOC44MjhzMy41MzEtOC44MjgsOC44MjgtOC44MjhoNzAuNjIxCgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhTMTY0LjMwMywzMDAuMTM4LDE1OS4wMDcsMzAwLjEzOHoiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMjExLjk3MiwzMzUuNDQ4aC03MC42MjFjLTUuMjk3LDAtOC44MjgtMy41MzEtOC44MjgtOC44MjhzMy41MzEtOC44MjgsOC44MjgtOC44MjhoNzAuNjIxCgkJYzUuMjk3LDAsOC44MjgsMy41MzEsOC44MjgsOC44MjhTMjE3LjI2OSwzMzUuNDQ4LDIxMS45NzIsMzM1LjQ0OHoiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMTA2LjA0MSwzMzUuNDQ4SDg4LjM4NmMtNS4yOTcsMC04LjgyOC0zLjUzMS04LjgyOC04LjgyOHMzLjUzMS04LjgyOCw4LjgyOC04LjgyOGgxNy42NTUKCQljNS4yOTcsMCw4LjgyOCwzLjUzMSw4LjgyOCw4LjgyOFMxMTEuMzM4LDMzNS40NDgsMTA2LjA0MSwzMzUuNDQ4eiIvPgoJPHBhdGggc3R5bGU9ImZpbGw6Izc5NjgzQjsiIGQ9Ik0xODUuNDksMzcwLjc1OWgtMTcuNjU1Yy01LjI5NywwLTguODI4LTMuNTMxLTguODI4LTguODI4czMuNTMxLTguODI4LDguODI4LTguODI4aDE3LjY1NQoJCWM1LjI5NywwLDguODI4LDMuNTMxLDguODI4LDguODI4UzE5MC43ODYsMzcwLjc1OSwxODUuNDksMzcwLjc1OXoiLz4KCTxwYXRoIHN0eWxlPSJmaWxsOiM3OTY4M0I7IiBkPSJNMTMyLjUyNCwzNzAuNzU5SDg4LjM4NmMtNS4yOTcsMC04LjgyOC0zLjUzMS04LjgyOC04LjgyOHMzLjUzMS04LjgyOCw4LjgyOC04LjgyOGg0NC4xMzgKCQljNS4yOTcsMCw4LjgyOCwzLjUzMSw4LjgyOCw4LjgyOFMxMzcuODIxLDM3MC43NTksMTMyLjUyNCwzNzAuNzU5eiIvPgo8L2c+CjxwYXRoIHN0eWxlPSJmaWxsOiNENzVBNEE7IiBkPSJNNTA1LjkzMSwyMDQuOGM3Ljk0NS03Ljk0NSw3Ljk0NS0yMi4wNjksMC0zMC4wMTRsLTE2Ljc3Mi0xNi43NzJjLTkuNzEtOS43MS0yNS42LTkuNzEtMzUuMzEsMAoJbC0xOS40MjEsMTkuNDIxbDUwLjMxNyw1MC4zMTciLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==);background-repeat: no-repeat;background-size: contain;margin-right: 10px;}:root .header .info {transform: rotate(3deg);font-size: 16px;padding: 12px 16.8px 12px 16.8px;border-top-left-radius: 6px;border-top-right-radius: 6px;border-bottom-left-radius: 6px;border-bottom-right-radius: 16px;color: #fff;background: #fe7345;user-select: none;font-weight: bolder;margin-top: 20px;}:root .title {font-size: 22px;margin-bottom: 18px;font-weight: bolder;text-align: center;}:root .form {width: 360px;height: 30px;margin: auto;}:root .form .form-input {width: 250px;height: 30px;border-bottom: 3px dashed #fe7345;flow: horizontal;}:root .form .form-input input {border: none;padding: 5px 0 3px;font-size: 14px;background: transparent;width: 100%;color: rgba(73, 74, 75, .35);}:root .form .form-input button {position: relative;transform: rotate(4deg);border-radius: 6px;outline: none;border: none;background: none;cursor: pointer;}:root .form .form-input button .submit {position: relative;display: block;font-size: 16.5px;padding: 0.34em 0.84em;border: 2px solid #494a4b;border-radius: inherit;background-color: #fff;box-sizing: border-box;}:root .empty-todos {margin-top: 30px;text-align: center;}:root .empty-todos .icon {display: inline-block;font-size: inherit;height: 1em;width: 0.75em;color: rgba(73, 74, 75, .35);margin-right: 12px;}:root .empty-todos .todos-text {font-size: 16px;padding-top: 5px;color: rgba(73, 74, 75, .45);}
}

源码

更多推荐

【sciter】案例 TodoList 带你入门 sciter 组件化编程

本文发布于:2024-03-07 23:40:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1719248.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:带你   组件   入门   案例   sciter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!