Vue 是什么让开发人员能够在 DOM 元素上使用 class 属性?
What is it about Vue that enables developers to use the class property on DOM elements?
JavaScript 框架,如 React 和 Svelte 不允许开发人员在 DOM 上使用 class
属性元素,因为 class
关键字在 JavaScript 中保留。与此同时,Vue 等其他框架以某种方式解决了这个问题。
Vue 的实现方式是什么使得 Vue 开发人员可以在元素上使用 class
关键字?我想这与 Vue 如何将 .vue
文件转换为 HTML、CSS 和 JavaScript 有关,但我对具体情况很好奇。
编辑: Svelte does not use virtual DOM 并且您可以 将 class prop 与 Svelte 一起使用。
你不能将 class
与 React 一起使用,因为 React 使用 React DOM,它使用驼峰式 属性 名称,而不是经典的 HTML 属性。
这就是为什么在 JSX(React 渲染语言)中,你必须使用 className
,而不是 class
。
Vue 使用经典的 HTML 模板,因此 class
是允许的。
使用 Svelte,您应该可以在模板中使用 class
关键字。
React 库使用 JSX 渲染任何 DOM 元素。 JSX 是 JS 的一种扩展,从 javascript 渲染 HTML。 JSX 在渲染到浏览器之前被转译。因此必须使用 className 而不是 class。但是,从一个 reactjs 版本到另一个版本有一些进步。
好像已经有人问过类似的问题了。找到更多解释
根据我的研究答案:感谢他们内置的功能。
我在 Vue.js https://github.com/vuejs/vue/blob/dev/dist/vue.js 的一侧发现 Vue 正在将 class 从 JavaScript 对象绑定到 Node。 (vue) 节点元素与 JavaScript 一起使用以分配给 DOM elm 所有 classes.
JavaScript 代码 el.setAttribute('class', cls)
正在确认。
function transformNode (el, options)
从这里您将在第 5503 行找到函数:
function genClassForVnode (vnode)
其中使用了
function renderClass (staticClass, dynamicClass)
此函数随后被
使用
function updateClass (oldVnode, vnode) {
var el = vnode.elm;
var data = vnode.data;
var oldData = oldVnode.data;
[...]
var cls = genClassForVnode(vnode);
// handle transition classes
var transitionClass = el._transitionClasses;
if (isDef(transitionClass)) {
cls = concat(cls, stringifyClass(transitionClass));
}
// set the class
if (cls !== el._prevClass) {
el.setAttribute('class', cls);
el._prevClass = cls;
}
}
注意:以下函数比较有意思:
function addClass(el, cls)
第 7873 行 function bindObjectListeners(data, value)
第 2866 行
有帮助吗?
tldr;
JSX(React 的语言)是 JavaScript 的超集(其中 class
是保留关键字),而 Vue 和 Svelte 都有模板语言,它们是 HTML 的超集,因此允许使用class
就像在 HTML.
中一样
在这里为 Svelte 代言。
首先,让我们修正错误的前提:
JavaScript frameworks like React and Svelte don't allow developers to use the class property on a virtual DOM element because the class keyword is reserved in JavaScript.
Svelte 允许在元素和组件上使用 class
关键字。您只需要在适用的限制范围内工作即可。我们要回到这个问题上了。
让我们从 React 开始。好吧,实际上是 JSX。 JSX 是 JS 的严格超集。参考这个nice explanation。 JSX 在语法上(任何 JS 程序都是有效的 JSX) 和 语义上都是 JS 的超集(任何 JS 程序在解释为 JSX 时表现相同)。
为了做到这一点,JSX 必须尊重 JS 的每一个约束,其中 "class is a reserved keyword"。这就是 React 不允许使用 class
关键字的原因。
请注意,这不是 技术 限制。 React 可以 重新解释 class
关键字并使其在 JSX 中工作。但这会使 JSX 严格来说不是 JS 的超集。为什么?因为那时,在某些情况下,相同的 JS 代码在解释为纯 JS 或 JSX 时不会表现相同(即,具有名为 class
的变量必须 崩溃才能成为JS).
这是一个哲学约束。有一次,JSX 开发人员必须权衡不能使用 class
关键字的不便,而不是突然成为 JS 的严格超集。一方面,您获得了一点好处,另一方面,您突然从纯数学超集降级为 "yet another random template language".
很容易感受到来自 React 的强烈数学倾向,它强调纯函数、"view as a function of the state"、单向数据流等。这实际上是 React 的一个非常重要的收获。他们将数学的许多好处引入到日常应用程序开发中。因此,(对我而言)完全可以理解,这群开发人员偏爱(赞成)纯粹性而不是次要的便利。
作为 JS 的超集确实带来了很多优势。即使你对 JSX 一无所知,你也可以利用现有的 JS 知识立即编写一些。只要您不开始使用 JSX 额外功能,您就可以预测代码的所有行为,因为一切都会表现得一样。
现在,关于 Svelte 的细节……Svelte 不 使用 JSX(据我所知,在大多数情况下都不使用 Vue)。他们使用自己的模板语言。不确定 Vue,但对于 Svelte,它是一个超集,不是 JS,而是 HTML。 Svelte 的创建者 Rich Harris 曾在一次演讲中称其为 HTMLX(不确定该术语目前有多正式)。就个人而言,这是我对 Svelte 如此满意的主要原因之一。我发现写 HTML 是 JS 很麻烦,而写看起来自然的 HTML(X) 到最后,产生 HTML 感觉只是......自然!但我离题了...
所以,Svelte 也必须在自己选择的法则范围内发挥作用。其中有 2 个与手头的问题相关。两者都有意义,并且都可以解决。
但首先,为了消除任何误解,Svelte 确实允许对原生元素(与 Svelte 组件相对)使用 class
关键字:
<div class="whatever">No problem with that</div>
如果不是,它就不是 HTML 的适当超集。
在这种情况下,class
实际上是 "directive",这意味着它比纯粹的 HTML class 更强大。例如:
<script>
let blue = true
</script>
<!-- will render as: <div class="blue"></div> -->
<div class:blue />
<!-- will render as: <div class="red"></div> -->
<div class:red={blue} />
<!-- you can have several of them too... -->
<div class="foo" class:red class:blue />
所以 Svelte 允许使用 class
关键字,这是毫无疑问的。对于原生元素,即。
现在,组件的情况有点不同。我前面提到的2条法则来了。
第一个是 Svelte 组件不强制具有单个根元素。或者任何元素,就此而言。
<script>
console.log('I am a valid Svelte component with no elements')
</script>
<!-- no code omitted -->
<p>I am a valid Svelte component</p>
<p>Too.</p>
这样做的结果是 Svelte 无法确定应该自动将 class
集应用到包含的组件上的哪些元素。因此,在这种情况下,它什么都不做。它会将控件交还给您。
这并不意味着你想实现就实现不了。你只需要遵守我们的第二定律:Svelte 组件的 <script>
标签内的代码必须是 有效的 JS。同样,这不是技术限制,而是哲学上的限制。 Svelte 的创建者和核心开发人员在很多场合都一再重申。在语法层面,我们甚至不再谈论超集,而是平等。任何 Svelte JS 都是有效的 JS(请注意,与 "any JS is valid JSX" 相比,关系的成员已被交换)。
另一方面,Svelte JS 也不是 JS 的语义超集。某些 JS 程序在被解释为纯 JS 时的行为与在用 Svelte 解释时的行为不同,因为 Svelte 重载了一些具有不同含义的结构(如 $:
或 export let prop
)。
此约束在这里影响我们,因为 class
不是有效的变量名称是 JS,并且 Svelte 组件的属性被定义为 JS 变量。但是你可以绕过它:
<script>
// can't do, not valid JS:
// export let class
// but:
let cls = ''
export { cls as class } // valid JS
</script>
<div class={class} />
这个组件可以这样使用 (live example):
<script>
import MyComponent from './MyComponent.svelte'
</script>
<MyComponent class="blue" />
因此您也可以在 Svelte 中为组件使用 class
关键字。
呸。希望你喜欢一个成熟的答案!
总而言之,如果一些主要框架允许使用 class
关键字而另一些则不允许,这是出于哲学原因。作为 JS 的超集,JSX 完全有理由遵守这一约束。对于 Svelte 的 HTMLX 来说,无缘无故地实施这个约束是没有意义的(并且在这个过程中不再是 HTML 的超集)。此外,React 更注重数学的纯粹性,而 Svelte 更注重代码的表现力和便利性。一如既往的好软件,一切都在权衡之中!
JavaScript 框架,如 React 和 Svelte 不允许开发人员在 DOM 上使用 class
属性元素,因为 class
关键字在 JavaScript 中保留。与此同时,Vue 等其他框架以某种方式解决了这个问题。
Vue 的实现方式是什么使得 Vue 开发人员可以在元素上使用 class
关键字?我想这与 Vue 如何将 .vue
文件转换为 HTML、CSS 和 JavaScript 有关,但我对具体情况很好奇。
编辑: Svelte does not use virtual DOM 并且您可以 将 class prop 与 Svelte 一起使用。
你不能将 class
与 React 一起使用,因为 React 使用 React DOM,它使用驼峰式 属性 名称,而不是经典的 HTML 属性。
这就是为什么在 JSX(React 渲染语言)中,你必须使用 className
,而不是 class
。
Vue 使用经典的 HTML 模板,因此 class
是允许的。
使用 Svelte,您应该可以在模板中使用 class
关键字。
React 库使用 JSX 渲染任何 DOM 元素。 JSX 是 JS 的一种扩展,从 javascript 渲染 HTML。 JSX 在渲染到浏览器之前被转译。因此必须使用 className 而不是 class。但是,从一个 reactjs 版本到另一个版本有一些进步。
好像已经有人问过类似的问题了。找到更多解释
根据我的研究答案:感谢他们内置的功能。
我在 Vue.js https://github.com/vuejs/vue/blob/dev/dist/vue.js 的一侧发现 Vue 正在将 class 从 JavaScript 对象绑定到 Node。 (vue) 节点元素与 JavaScript 一起使用以分配给 DOM elm 所有 classes.
JavaScript 代码 el.setAttribute('class', cls)
正在确认。
function transformNode (el, options)
从这里您将在第 5503 行找到函数:
function genClassForVnode (vnode)
其中使用了
function renderClass (staticClass, dynamicClass)
此函数随后被
使用function updateClass (oldVnode, vnode) {
var el = vnode.elm;
var data = vnode.data;
var oldData = oldVnode.data;
[...]
var cls = genClassForVnode(vnode);
// handle transition classes
var transitionClass = el._transitionClasses;
if (isDef(transitionClass)) {
cls = concat(cls, stringifyClass(transitionClass));
}
// set the class
if (cls !== el._prevClass) {
el.setAttribute('class', cls);
el._prevClass = cls;
}
}
注意:以下函数比较有意思:
function addClass(el, cls)
第 7873 行 function bindObjectListeners(data, value)
第 2866 行
有帮助吗?
tldr;
JSX(React 的语言)是 JavaScript 的超集(其中 class
是保留关键字),而 Vue 和 Svelte 都有模板语言,它们是 HTML 的超集,因此允许使用class
就像在 HTML.
在这里为 Svelte 代言。
首先,让我们修正错误的前提:
JavaScript frameworks like React
and Sveltedon't allow developers to use the class property on a virtual DOM element because the class keyword is reserved in JavaScript.
Svelte 允许在元素和组件上使用 class
关键字。您只需要在适用的限制范围内工作即可。我们要回到这个问题上了。
让我们从 React 开始。好吧,实际上是 JSX。 JSX 是 JS 的严格超集。参考这个nice explanation。 JSX 在语法上(任何 JS 程序都是有效的 JSX) 和 语义上都是 JS 的超集(任何 JS 程序在解释为 JSX 时表现相同)。
为了做到这一点,JSX 必须尊重 JS 的每一个约束,其中 "class is a reserved keyword"。这就是 React 不允许使用 class
关键字的原因。
请注意,这不是 技术 限制。 React 可以 重新解释 class
关键字并使其在 JSX 中工作。但这会使 JSX 严格来说不是 JS 的超集。为什么?因为那时,在某些情况下,相同的 JS 代码在解释为纯 JS 或 JSX 时不会表现相同(即,具有名为 class
的变量必须 崩溃才能成为JS).
这是一个哲学约束。有一次,JSX 开发人员必须权衡不能使用 class
关键字的不便,而不是突然成为 JS 的严格超集。一方面,您获得了一点好处,另一方面,您突然从纯数学超集降级为 "yet another random template language".
很容易感受到来自 React 的强烈数学倾向,它强调纯函数、"view as a function of the state"、单向数据流等。这实际上是 React 的一个非常重要的收获。他们将数学的许多好处引入到日常应用程序开发中。因此,(对我而言)完全可以理解,这群开发人员偏爱(赞成)纯粹性而不是次要的便利。
作为 JS 的超集确实带来了很多优势。即使你对 JSX 一无所知,你也可以利用现有的 JS 知识立即编写一些。只要您不开始使用 JSX 额外功能,您就可以预测代码的所有行为,因为一切都会表现得一样。
现在,关于 Svelte 的细节……Svelte 不 使用 JSX(据我所知,在大多数情况下都不使用 Vue)。他们使用自己的模板语言。不确定 Vue,但对于 Svelte,它是一个超集,不是 JS,而是 HTML。 Svelte 的创建者 Rich Harris 曾在一次演讲中称其为 HTMLX(不确定该术语目前有多正式)。就个人而言,这是我对 Svelte 如此满意的主要原因之一。我发现写 HTML 是 JS 很麻烦,而写看起来自然的 HTML(X) 到最后,产生 HTML 感觉只是......自然!但我离题了...
所以,Svelte 也必须在自己选择的法则范围内发挥作用。其中有 2 个与手头的问题相关。两者都有意义,并且都可以解决。
但首先,为了消除任何误解,Svelte 确实允许对原生元素(与 Svelte 组件相对)使用 class
关键字:
<div class="whatever">No problem with that</div>
如果不是,它就不是 HTML 的适当超集。
在这种情况下,class
实际上是 "directive",这意味着它比纯粹的 HTML class 更强大。例如:
<script>
let blue = true
</script>
<!-- will render as: <div class="blue"></div> -->
<div class:blue />
<!-- will render as: <div class="red"></div> -->
<div class:red={blue} />
<!-- you can have several of them too... -->
<div class="foo" class:red class:blue />
所以 Svelte 允许使用 class
关键字,这是毫无疑问的。对于原生元素,即。
现在,组件的情况有点不同。我前面提到的2条法则来了。
第一个是 Svelte 组件不强制具有单个根元素。或者任何元素,就此而言。
<script>
console.log('I am a valid Svelte component with no elements')
</script>
<!-- no code omitted -->
<p>I am a valid Svelte component</p>
<p>Too.</p>
这样做的结果是 Svelte 无法确定应该自动将 class
集应用到包含的组件上的哪些元素。因此,在这种情况下,它什么都不做。它会将控件交还给您。
这并不意味着你想实现就实现不了。你只需要遵守我们的第二定律:Svelte 组件的 <script>
标签内的代码必须是 有效的 JS。同样,这不是技术限制,而是哲学上的限制。 Svelte 的创建者和核心开发人员在很多场合都一再重申。在语法层面,我们甚至不再谈论超集,而是平等。任何 Svelte JS 都是有效的 JS(请注意,与 "any JS is valid JSX" 相比,关系的成员已被交换)。
另一方面,Svelte JS 也不是 JS 的语义超集。某些 JS 程序在被解释为纯 JS 时的行为与在用 Svelte 解释时的行为不同,因为 Svelte 重载了一些具有不同含义的结构(如 $:
或 export let prop
)。
此约束在这里影响我们,因为 class
不是有效的变量名称是 JS,并且 Svelte 组件的属性被定义为 JS 变量。但是你可以绕过它:
<script>
// can't do, not valid JS:
// export let class
// but:
let cls = ''
export { cls as class } // valid JS
</script>
<div class={class} />
这个组件可以这样使用 (live example):
<script>
import MyComponent from './MyComponent.svelte'
</script>
<MyComponent class="blue" />
因此您也可以在 Svelte 中为组件使用 class
关键字。
呸。希望你喜欢一个成熟的答案!
总而言之,如果一些主要框架允许使用 class
关键字而另一些则不允许,这是出于哲学原因。作为 JS 的超集,JSX 完全有理由遵守这一约束。对于 Svelte 的 HTMLX 来说,无缘无故地实施这个约束是没有意义的(并且在这个过程中不再是 HTML 的超集)。此外,React 更注重数学的纯粹性,而 Svelte 更注重代码的表现力和便利性。一如既往的好软件,一切都在权衡之中!