element thành phần chi tiết mà sẽ dùng kiểu CSR (Client Side Rendering).index.html và phần dữ liệu sẽ không viết các element thành phần chi tiết mà sẽ dùng kiểu CSR (Client Side Rendering) thao tác dùng DOM để chọn element id ='root' để truyền dữ liệu render vào đây.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Todo App</title>
</head>
<body>
<div id="root"></div>
</body>
<script type="module" src="./script.js"></script>
</html>
index.html sẽ link với file script.js theo dạng module : ` `.store sẽ bao gồm các state trạng thái chứa dữ liệu, nên ở đây ta sẽ viết 1 hàm để xử lý chuyển 1 mảng danh sách state, truyền vào element #root như sau:
ES6 - Tagged template literals như sau:const rootElement = document.querySelector('#root');
const cars = ['BMW', 'Porsche', 'Mercedes'];
const html = `
<h1>TODO List</h1>
<ul>
${cars.map((car) => `<li>${car}</li>`).join('')}
<ul>
`;
console.log(html);
rootElement.innerHTML = html;
const rootElement = document.querySelector('#root');
const cars = ['BMW', 'Porsche', 'Mercedes', true, undefined, null, NaN, false];
const isSucceeded = false;
const html = `
<h1>${isSucceeded} && TODO List</h1>
<ul>
${cars.map((car) => `<li>${car}</li>`).join('')}
<ul>
`;
console.log(html);
rootElement.innerHTML = html;

export default function html([first, ...values], ...strings) {
return values
.reduce(
(acc, cur) => {
return acc.concat(strings.shift(), cur);
},
[first]
)
.filter((x) => (x && x !== true) || x === 0)
.join('');
}
import html from './core.js';
const cars = ['BMW', 'Porsche', 'Mercedes'];
const isSucceeded = false;
const output = html`
<h1>${isSucceeded} && TODO List</h1>
<ul>
${cars.map((car) => `<li>${car}</li>`)}
<ul></ul>
</ul>
`;
const rootElement = document.querySelector('#root');
rootElement.innerHTML = output;
html() được gọi là template view