这是一个关于 Angular 2 选择器、自定义标签与自定义属性、SEO 和浏览器渲染的问题。
当我第一次开始查看 Angular 2 时,我按照他们的快速入门做的第一件事就是将我的选择器更改为'[my-component]'
(属性选择器)而不是'my-component'
(标签选择器),这样我就可以<div my-component></div>
在我的 html而不是<my-component></my-component>
,这不是有效的 html。所以我会根据标准编写html。好吧,至少非常接近标准(因为my-component
它不是有效的 html 属性,但我只能忍受那个 html 验证错误)
然后,在 youtube 上的某个视频中,Angular 团队的某个人提到我们应该使用标签选择器,至少在性能方面。
好吧,我说,搞砸 html 验证......还是不应该?
所以:
假设我忽略了 W3C 对我的 html 完全无效的尖叫,因为
<custom-tags>
. 实际上,我还有另一个更大更真实的担忧:这对 SEO 有何影响?
我的意思是不要只考虑客户端应用程序,因为在现实世界中(以及我的 angular 2 项目)我也有服务器端渲染,有两个非常重要的原因:SEO和网站的快速初始渲染在应用程序启动之前,该初始视图的用户。否则,您将无法拥有非常高的流量 SPA。
当然,无论我使用什么标签,谷歌都会抓取我的网站,但它在两种情况下的排名是否相同:一种<custom-make-believe-tags>
是标准的 html 标签,另一种是标准的 html 标签?让我们谈谈浏览器和 css:
当我开始在 Angular 2 中构建我的第一个 SPA 站点时,我立即面临另一个问题:
假设(在非 SPA 站点中)我有以下 html 标记:
<header>
<a class="logo">
...
</a>
<div class="widgets">
<form class="frm-quicksearch"> ... </form>
<div class="dropdown">
<!-- a user dropdown menu here -->
</div>
</div>
</header>
<div class="video-listing">
<div class="video-item"> ... </div>
<div class="video-item"> ... </div>
...
</div>
Angular 2 明智的我将拥有以下组件树:
<header-component>
<logo-component></logo-component>
<widgets-component>
<quicksearch-component></quicksearch-component>
<dropdown-component></dropdown-component>
</widgets-component>
</header-component>
<video-listing-component>
<video-item-component></video-item-component>
...
</video-listing-component>
现在,我有两个选择。让我们<video-listing-component>
举个例子,为了保持简单......我要么
A)将我已经拥有的整个标准 html 标签(<div class="video-item"></div>
)放在<video-item-component>
标签中,一旦渲染将导致:
<video-listing-component>
<div class="video-listing>
<video-item-component>
<div class="video-item>...</div>
</video-item-component>
...
...
</div>
</video-listing-component>
或:
B)仅将的内容 <div class="video-item">
直接放入我的<video-item-component>
组件中,并在组件标签上添加所需的类 ( class="video-item"
) 进行样式设置,结果如下:
<video-listing-component class="video-listing">
<video-item-component class="video-item"></video-item-component>
<video-item-component class="video-item"></video-item-component>
...
</video-listing-component>
无论哪种方式(A或B),浏览器都可以很好地呈现一切。
但是,如果您仔细查看(当然,在所有内容都在 dom 中呈现之后),默认情况下自定义标签不会占用 dom 中的任何空间。它们是 0px x 0px。只有它们的内容占据空间。我不明白为什么浏览器仍然会呈现您希望看到的所有内容,我的意思是在第一种情况下(A):
虽然在float: left; width: 25%;
上div class="video-item"
,但每个 div 都在一个<video-item-component>
标签内,这不是有任何样式...浏览器呈现您所期望的一切不只是一个幸运的副作用吗?与所有<div class="video-item">
漂浮在彼此旁边,即使它们每个都在另一个标签内,<video-item-component>
哪个没有浮动:左?我已经在 IE10+、Firefox、Chrome 上测试过,一切正常。只是幸运还是对此有可靠的解释,我们可以安全地依赖所有(或至少大多数)浏览器所期望的这种标记来呈现?
第二种情况(B):
如果我们直接在自定义标签(<video-item-component>
)上使用类和样式......再次,一切都很好。但据我所知,我们不应该设置自定义组件的样式,对吧?这不也是一个幸运的预期结果吗?或者这也可以吗?我不知道,也许我还活在 2009 年……是吗?
这两种方法(A或B)中的哪一种是推荐的?还是两者都很好?
我没意见!!
编辑:
D'oh,谢谢 Günter Zöchbauer。是的,因为我的 div 有浮动:左,这就是为什么他们包裹的(自定义或非自定义)标签不会扩展它的高度。自从我开始查看 Angular 2 以来,似乎我已经忘记了 css 是如何工作的 :)
但有一件事仍然存在:
如果我在块元素上设置百分比宽度(称为 E),我会假设它需要 x% 是即时的父母。如果我设置浮动:左,我希望在直接父级内浮动。在我的 A案例中,由于直接父级是一个没有显示类型和宽度的自定义标签,我希望事情会以某种方式中断,但仍然......我的 E 元素的行为就像他们的父级不是他们的自定义标签'每个都包裹在里面,但是 dom 中的下一个(也就是<div class="video-listing>
在我的情况下)。它们占据了其中的 x%,并且在其中浮动。我不认为这是正常的,我认为这只是一种幸运的效果,而且我担心有一天,在浏览器更新之后......我会醒来发现我所有的 Angular 2 网站看起来都完全破碎的。
那么... A和B都是同样合适的方法吗?还是在A情况下我做错了?
EDIT2:
让我们稍微简化一下。当我回答了部分问题时,让我们再举一个生成的 html 的例子(简化一点,内联 css):
<footer>
<angular-component-left>
<div style="float: left; width: 50%;">
DIV CONTENT
</div>
</angular-component-left>
<angular-component-right>
<div style="float: left; width: 50%;">
DIV CONTENT
</div>
</angular-component-right>
</footer>
在原始的,尚未实现的 html 中(没有<angular-component-...>
,这些 div 应该向左浮动,并且每个占据 50% 的<footer>
空间。令人惊讶的是,一旦它们被包裹在<angular-component-...>
自定义标签中,它们就会做同样的事情:占据页脚的 50%。但是这个对我来说似乎是好运,运气不好......意想不到的效果。
那么,是不是“运气不好”?
我应该这样保留它,还是重写而不是上面的代码,我会有一些东西像这样:
<footer>
<angular-component-left style="display: block; float: left; width: 50%;">
DIV CONTENT
</angular-component-left>
<angular-component-right style="display: block; float: left; width: 50%;">
DIV CONTENT
</angular-component-right>
</footer>
请注意,为简单起见,此处引入了内联样式,实际上我将有一个类,而不是在<head>
我的文档中包含的外部 css 文件中,而不是通过style
或styleUrls
来自我的角度组件。