Skip to content

Commit f4fdb4d

Browse files
committed
learn/tutorials/TodoList: create a functional.component.Base version #7070
1 parent b290bdf commit f4fdb4d

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

learn/tutorials/TodoList.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,89 @@ class MainContainer extends Container {
231231

232232
MainContainer = Neo.setupClass(MainContainer);
233233
```
234+
235+
## Functional Style
236+
237+
This version shows how to build the same UI using a single functional component.
238+
It uses hooks for state management, resulting in more concise and declarative code.
239+
240+
```javascript live-preview
241+
import {defineComponent, useConfig, useEvent} from '../functional/_export.mjs';
242+
243+
let MainContainer = defineComponent({
244+
config: {
245+
className: 'Neo.examples.todoList.version3.MainContainer'
246+
},
247+
createVdom() {
248+
const [items, setItems] = useConfig([
249+
{id: 1, done: true, text: 'Todo Item 1'},
250+
{id: 2, done: false, text: 'Todo Item 2'},
251+
{id: 3, done: false, text: 'Todo Item 3'}
252+
]);
253+
254+
const [inputValue, setInputValue] = useConfig('');
255+
256+
useEvent('click', data => {
257+
if (inputValue) {
258+
const newItem = {
259+
id : items.length + 1,
260+
done: false,
261+
text: inputValue
262+
};
263+
setItems([...items, newItem]);
264+
setInputValue('');
265+
}
266+
}, {delegate: '.todo-add-button'});
267+
268+
useEvent('click', data => {
269+
const itemNode = Neo.vdom.Util.find(data.path[0].id);
270+
const itemIndex = itemNode.vdom.parent.cn.indexOf(itemNode.vdom);
271+
const itemToToggle = items[itemIndex];
272+
273+
const newItems = items.map(item =>
274+
item.id === itemToToggle.id ? {...item, done: !item.done} : item
275+
);
276+
setItems(newItems);
277+
}, {delegate: '.todo-item'});
278+
279+
useEvent('input', data => {
280+
setInputValue(data.value);
281+
}, {delegate: '.todo-input'});
282+
283+
return {
284+
style: {border: '1px solid #000', margin: '20px', padding: '10px', maxWidth: '300px'},
285+
cn: [
286+
{tag: 'h3', html: 'Todo List'},
287+
{tag: 'ol', cn: items.map(item => ({
288+
tag: 'li',
289+
cn: [
290+
{
291+
tag : 'span',
292+
cls : ['todo-item', item.done ? 'fa fa-check' : 'far fa-square'],
293+
style: {cursor: 'pointer', width: '20px', marginRight: '5px'}
294+
},
295+
{vtype: 'text', html: item.text}
296+
]
297+
}))},
298+
{
299+
cn: [
300+
{
301+
tag: 'input',
302+
cls: ['todo-input'],
303+
value: inputValue
304+
},
305+
{
306+
tag: 'button',
307+
cls: ['todo-add-button'],
308+
html: 'Add Item',
309+
style: {marginLeft: '1em'}
310+
}
311+
]
312+
}
313+
]
314+
};
315+
}
316+
});
317+
318+
MainContainer = Neo.setupClass(MainContainer);
319+
```

0 commit comments

Comments
 (0)