gpt4 book ai didi

javascript - 如何使用 vanilla JS 实现可维护的响应式(Reactive) UI

转载 作者:行者123 更新时间:2023-12-03 07:12:29 26 4
gpt4 key购买 nike

今天我遇到了一个问题,可以通过使用像 Vue 这样的响应式(Reactive)和状态管理的框架来轻松解决。可悲的是,它不可能使用它。
以下(简化的)情况(link to codepen):我们有一个服务器渲染的页面,它有一个价格字段。它有机会添加或删除注释。如果我们添加一个注释,它会发布到服务器,并且 UI 应该会自行更新。删除笔记也是如此。

const priceField = document.getElementById("priceField");

priceField.querySelector("#create-note-btn").addEventListener("click", () => {
priceField.querySelector("#note-input-row").classList.toggle("hidden");

// depending on state #create-note-btn can hide/show #note-row or #node-input-row
});

priceField.querySelector("#submit-note-btn").addEventListener("click", () => {
priceField.querySelector("#note-row").classList.toggle("hidden");
priceField.querySelector("#note-input-row").classList.toggle("hidden");

const input = priceField.querySelector("input").value;
priceField.querySelector("#note").innerHTML = input;
// api call
// further ui updates, like changing icon of #create-note-btn
});

priceField.querySelector("#delete-note-btn").addEventListener("click", () => {
priceField.querySelector("#note-row").classList.toggle("hidden");
// api call
// resetting icon of #create-note-btn
});

// much more logic with additional UI update operations, like recalculation of price etc.
.hidden {
display: none;
}
<div id="priceField">
<div>
<span>100 €</span>
<button id="create-note-btn">Create Note</button>
</div>
<div id="note-input-row" class="hidden">
<input></input>
<button id="submit-note-btn">Submit</button>
</div>
<div id="note-row" class="hidden">
<span id="note">Placeholder note</span>
<button id="delete-note-btn">Delete Note</button>
</div>
</div>

为了实现这一点(仅!)javascript 用于更新 View 。因此很多 classlist.toggle("..")调用或其他操作来显示/隐藏元素。此外,还有许多不同的操作也会更新不同位置的 View 。
为了保持代码的可维护性,我想要实现,UI 更新在一个中心位置完成,而不是在不同的调用中拆分。还应保留状态以重新加载页面。
有什么简单且可维护的方法吗?
我的想法:
实现一个小状态机(INITIAL, OPEN_NOTE, CLOSED_NOTE, ...)和一个 render() -取决于实际状态的功能。为了保持页面重新加载的更改,必须使用本地存储或服务器端呈现的 html 也需要有状态。

最佳答案

我按照自己的想法使用 render 实现内部状态。 - 保存所有 UI 相关更改的函数。

const RenderMode = {
INITIAL: "Initial",
CREATE: "Create",
OPEN: "Open",
SHOW_NOTE: "Show note input",
TOGGLE_PRICE: "Toggle price input",
};

render() {
switch (this.renderMode) {
case RenderMode.INITIAL:
this._hideIndicatorIcon();
this._hideIndicatorRow();
this._hideInputRow();
this._hidePriceInput();

break;
case RenderMode.CREATE:
this._showInputRow();
break;
case RenderMode.OPEN:
this._showIndicatorIcon();
this._hideInputRow();
this._hideIndicatorRow();
break;
case RenderMode.SHOW_NOTE:
this._showIndicatorRow();
break;
case RenderMode.TOGGLE_PRICE:
this._togglePriceInputs();
break;
default:
console.error("No render mode defined!");
}
页面重新加载后的状态由服务器端呈现的 html 的自定义属性确定:
  initializeRenderMode() {
...
// if note already exists on page load switch render mode to open
this.renderMode = existingNote ? RenderMode.OPEN : RenderMode.INITIAL;
this._render();
}
到目前为止,它不是最好的解决方案,但它可以帮助我保持简单。

关于javascript - 如何使用 vanilla JS 实现可维护的响应式(Reactive) UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64893795/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com