Мы создали фронтенд-фреймворк с нуля
Здравствуйте!
Мы — команда с открытым исходным кодом под названием BugDuck, состоящая в основном из разработчиков средней школы.
В апреле 2022 года мы основали TNTjs с внезапной мыслью. Сначала мы продвигали во внешний мир язык программирования, реализованный на чистом JavaScript, но позже нам показалось это нереальным, поэтому мы изменили TNTjs на динамический полностью реактивный front-end фреймворк реального времени с поддержкой двусторонней привязки данных.
Сейчас мы снова занимаемся рефакторингом TNTjs. Мы собираемся выпустить tntjs Alpha 0.2.0 в конце июля этого года.
Так что прыгайте и позвольте мне представить вам некоторые основные возможности TNTjs!
В 0.2.0 вы можете использовать динамические переменные с помощью reactive()
, как и в Vuejs. Вы также можете использовать теги <v data="variableName">
для отображения их данных:
<v data="x"></v>
Более того, мы обернули все основные функциональные возможности в класс верхнего уровня TNTApp
. Вы можете использовать его следующим образом:
const app = new TNT.TNTApp()
.useData({
x: 233333
})
.mount(document.getElementById("app"));
В TNTjs Alpha 0.2 мы используем виртуальные DOM, и это оказалось намного быстрее, чем в TNTjs Alpha 1.0. Для рендеринга 10000 узлов потребуется около 200 мс. Однако — это все еще довольно медленно, и в настоящее время мы работаем над улучшением производительности.
Вы можете использовать <t-for>
для реализации цикла, и вы можете использовать <t-if>
<t-elif>
<t-else>
для реализации рендеринга условий.
Вот демонстрация TNTjs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TNTjs Demo</title>
<script src="./dist/tnt.min.js"></script>
<style>
.green {
color: green;
}
.red {
color: red;
}
</style>
</head>
<body>
<div id="root">
<div>
<h1>Counter</h1>
<v data="nae"></v>
Bar: <v data="bar"></v>
<p :class="(sum % 2 === 0 ? 'green' : 'red')">
Sum:
<v data="sum"></v>
</p>
<button onClick="data.foo.push(1)">Plus 1</button>
<button onClick="foo.push(-1)">Minus 1</button>
<button onClick="foo.pop()">Pop top</button>
<button onClick="bar++">Plus bar</button>
<button onClick="foo[foo.length - 2] += 2">Plus 2</button>
<t-if cond="sum % 2 === 0"> It's even! </t-if>
<t-else> It's odd! </t-else>
<br />
<p>
<code>data.foo</code>
content:
</p>
[
<t-for data="currentNumber in foo">
<span onclick="alert(`You clicked: ${currentNumber}`)">
<t-if cond="currentNumber > 0">
<v data="`${currentNumber}`"></v>,
</t-if>
<t-else>
← 0
</t-else>
</span>
</t-for>
<t-if cond="foo.length && foo[foo.length - 1] > 0">
<span>
<v data="`${foo[foo.length - 1]}`"></v>
</span>
</t-if>
]
<t-get src="./test.json" type="json">
<v data="name"></v>
</t-get>
</div>
</div>
</body>
<script>
const app = new TNT.TNTApp()
.useData({
nae: 114514,
foo: [],
bar: 5,
})
.useComputed({
sum() {
let sum = 0;
data.foo.forEach((v) => (sum += v));
return sum;
},
})
.useEffect(() => {
console.log(`Sum changed: ${data.sum}`);
})
.onMounted((app) => {
console.log("App mounted!");
})
.mount(document.getElementById("root"));
data.foo = [233];
</script>
</html>
Наконец, если вам понравился наш фреймворк, пожалуйста, оставьте нам звезду на GitHub!
Если у вас есть хорошие идеи по улучшению TNTjs, пожалуйста, напишите нам проблему или напишите нам по адресу bugduck@163.com.
И, наконец, мы приветствуем любой вклад. Если вы хотите стать соавтором, вы можете сделать форк репозитория и отправить нам запрос на исправление. Мы будем рады рассмотреть его!
Спасибо!