Svelte 应用程序错误:global.css 覆盖组件级别 CSS
Svelte application bug: global.css overwrites component-level CSS
在 Svelte 应用程序中,我有一个简单验证的表单。
形式
<form id="surveyForm" class="mt-4">
<div class="form-group">
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Last name">
</div>
<button class="btn btn-full" on:click={Continue}>Continue</button>
</form>
验证:
import {fly, fade} from 'svelte/transition';
let hasError = false;
let errMessage = "";
let isSuccessVisible = false;
function validateInput() {
var surveyForm = document.getElementById('surveyForm'),
inputFields = surveyForm.querySelectorAll('input[type=text]');
hasError = false;
inputFields.forEach(function(field) {
field.classList.remove("is-invalid");
var inputFieldVal = field.value;
if (inputFieldVal.length == 0) {
field.classList.add("is-invalid");
hasError = true;
}
});
errMessage = "All the fileds are mandatory";
}
function Continue(e) {
e.preventDefault();
validateInput();
if (hasError == false) {
isSuccessVisible = true;
setTimeout(function() {
isSuccessVisible = false;
}, 3000);
}
}
为了给无效的表单字段一个红色边框,我使用border: 1px solid #c00 !important
:
.error-alert {
border: 1px solid #c00 !important;
color: #c00;
}
class is-invalid
已正确添加(和删除),但默认 global.css
样式 覆盖我的组件级样式 ,正如您在 REPL.
中看到的
为什么会这样?什么是可靠的修复?
注意:所描述的案例是一个简化的案例,实际上我可能需要其他验证,比如确保该值是数字。我必须实施的解决方案不是非常具体。
在 REPL 中,您会看到以下警告:
Unused CSS selector (87:1)
那是因为 .is-invalid
选择器未在标记中的任何位置使用 — 如果 classname 未使用,Svelte 会告诉您并删除它。为了让 Svelte 能够 'see' 它,它必须在标记中——你不能用 classList
以编程方式添加它。 (这是一项功能,而不是错误:以编程方式操作 DOM 将不可避免地导致您的视图与您的状态不同步。)
虽然在这种情况下,您不需要向输入元素添加 class,也不需要在函数内部进行检查。您可以只使用输入的 required
属性和 :invalid
CSS 选择器:
<input type="text" class="form-control" placeholder="First name" required>
input:invalid {
border: 1px solid #c00;
}
:invalid
状态将在用户提交任何数据之前应用,因此您可能需要添加一个 class 来指示用户是否已尝试提交:
<form id="surveyForm" class="mt-4" class:submitted>
<div class="form-group">
<input type="text" class="form-control" placeholder="First name" required>
</div>
<!-- ... -->
</form>
.submitted input:invalid {
border: 1px solid #c00;
}
添加 class 的最简单方法是在按钮上的 click
事件处理程序中。
使用您在 HTML 中免费获得的东西还有其他好处。例如,只要存在验证错误,表单就不会提交(并且验证不限于 'required' — 您可以指定特定模式,或使用例如 type="email"
来要求有效的电子邮件地址等),这意味着在您的 submit
事件处理程序中,您已经知道输入是有效的。
您可以通过使用 HTML5 客户端表单验证来使用 Rich 描述的用于其他验证的技术。可以在 MDN
上找到更多信息
<form id="surveyForm" class="mt-4" class:submitted>
<div class="form-group">
<input type="text" class="form-control" placeholder="First name" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Last name" required>
</div>
<div class="form-group">
<input type="number" class="form-control" placeholder="Enter a number" required>
</div>
<div class="form-group">
<input type="email" class="form-control" placeholder="Email" required>
</div>
<div class="form-group">
<input type="date" class="form-control" placeholder="Date" required>
</div>
<button class="btn btn-full" on:click|preventDefault={Continue}>Continue</button>
</form>
如果您不想使用它 - 或者由于某种原因它没有涵盖您的所有用例 - 您可以使用 Svelte 操作 类 而不是直接访问 DOM :
<div class="form-group">
<input bind:value={second} type="text" class="form-control" class:is-invalid="{ submitted && second.length == 0 }" placeholder="Last name">
</div>
Svelte 删除您的 .is-invalid
样式的原因是因为 Svelte 不使用它。在这种情况下我不推荐它,但您可以强制 Svelte 使用 :global()
:
保持样式
:global(.is-invalid) {
border: 1px solid #c00;
}
在 Svelte 应用程序中,我有一个简单验证的表单。
形式
<form id="surveyForm" class="mt-4">
<div class="form-group">
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Last name">
</div>
<button class="btn btn-full" on:click={Continue}>Continue</button>
</form>
验证:
import {fly, fade} from 'svelte/transition';
let hasError = false;
let errMessage = "";
let isSuccessVisible = false;
function validateInput() {
var surveyForm = document.getElementById('surveyForm'),
inputFields = surveyForm.querySelectorAll('input[type=text]');
hasError = false;
inputFields.forEach(function(field) {
field.classList.remove("is-invalid");
var inputFieldVal = field.value;
if (inputFieldVal.length == 0) {
field.classList.add("is-invalid");
hasError = true;
}
});
errMessage = "All the fileds are mandatory";
}
function Continue(e) {
e.preventDefault();
validateInput();
if (hasError == false) {
isSuccessVisible = true;
setTimeout(function() {
isSuccessVisible = false;
}, 3000);
}
}
为了给无效的表单字段一个红色边框,我使用border: 1px solid #c00 !important
:
.error-alert {
border: 1px solid #c00 !important;
color: #c00;
}
class is-invalid
已正确添加(和删除),但默认 global.css
样式 覆盖我的组件级样式 ,正如您在 REPL.
为什么会这样?什么是可靠的修复?
注意:所描述的案例是一个简化的案例,实际上我可能需要其他验证,比如确保该值是数字。我必须实施的解决方案不是非常具体。
在 REPL 中,您会看到以下警告:
Unused CSS selector (87:1)
那是因为 .is-invalid
选择器未在标记中的任何位置使用 — 如果 classname 未使用,Svelte 会告诉您并删除它。为了让 Svelte 能够 'see' 它,它必须在标记中——你不能用 classList
以编程方式添加它。 (这是一项功能,而不是错误:以编程方式操作 DOM 将不可避免地导致您的视图与您的状态不同步。)
虽然在这种情况下,您不需要向输入元素添加 class,也不需要在函数内部进行检查。您可以只使用输入的 required
属性和 :invalid
CSS 选择器:
<input type="text" class="form-control" placeholder="First name" required>
input:invalid {
border: 1px solid #c00;
}
:invalid
状态将在用户提交任何数据之前应用,因此您可能需要添加一个 class 来指示用户是否已尝试提交:
<form id="surveyForm" class="mt-4" class:submitted>
<div class="form-group">
<input type="text" class="form-control" placeholder="First name" required>
</div>
<!-- ... -->
</form>
.submitted input:invalid {
border: 1px solid #c00;
}
添加 class 的最简单方法是在按钮上的 click
事件处理程序中。
使用您在 HTML 中免费获得的东西还有其他好处。例如,只要存在验证错误,表单就不会提交(并且验证不限于 'required' — 您可以指定特定模式,或使用例如 type="email"
来要求有效的电子邮件地址等),这意味着在您的 submit
事件处理程序中,您已经知道输入是有效的。
您可以通过使用 HTML5 客户端表单验证来使用 Rich 描述的用于其他验证的技术。可以在 MDN
上找到更多信息<form id="surveyForm" class="mt-4" class:submitted>
<div class="form-group">
<input type="text" class="form-control" placeholder="First name" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Last name" required>
</div>
<div class="form-group">
<input type="number" class="form-control" placeholder="Enter a number" required>
</div>
<div class="form-group">
<input type="email" class="form-control" placeholder="Email" required>
</div>
<div class="form-group">
<input type="date" class="form-control" placeholder="Date" required>
</div>
<button class="btn btn-full" on:click|preventDefault={Continue}>Continue</button>
</form>
如果您不想使用它 - 或者由于某种原因它没有涵盖您的所有用例 - 您可以使用 Svelte 操作 类 而不是直接访问 DOM :
<div class="form-group">
<input bind:value={second} type="text" class="form-control" class:is-invalid="{ submitted && second.length == 0 }" placeholder="Last name">
</div>
Svelte 删除您的 .is-invalid
样式的原因是因为 Svelte 不使用它。在这种情况下我不推荐它,但您可以强制 Svelte 使用 :global()
:
:global(.is-invalid) {
border: 1px solid #c00;
}