《Vuejs设计与实现》8.4 class的处理

77 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

在vuejs中,对于class的处理是做了增强的,我们复习一下vue中怎么样设置class名。

  • 直接赋值字符串<p class="a b"></p>
  • v-bind一个变量<p :class="val"></p>,这时候val可以是vue中的data,也可以是computed,也可以是一个对象{a:true,b:true}
  • v-bind一个数组<p :class="arr"></p>,arr可以是['a b',{c:false}]这种结构
  • 三目表达式,<p :class="flag ? 'a':'b'"></p>,这种情况书里没有说,但我认为这应该按副作用函数处理

我可以假设这样一种vnode定义

const vnode = {
    type:'',
    className: ''
}

对于上面几种不同的数据,其实也就是className值不同的问题,比如在方式2中className:{a:true,b:true},方式3中又变成className:['a b',{c:false}]

所以我们首先需要把不同格式的数据转换为字符串,因为DOM中的class名只接收字符串。书上没有写这个方法,但是我们可以实现一下。这里我没想到如何去处理三目表达式,但实际上三目表达式返回的是一个确切的结果,我们仍旧可以按string处理。实际上,这里应该还有一些字符串过滤的代码,过滤一些unicode代码或者xss,这里就不深究了,有空的读者可以去研究一些源码。

image.png

然后我们就能得到一个class的字符串,这时候需要选择一种方式把class名设置到元素上,设置class名一般有这三种方式。

  • element.setAttribute('className','')
  • element.className = ''
  • element.classList

其实理论上用这三个API随便哪个都可以,但是作者推荐使用element.className,说是性能更好,各位有空可以试试。

同样,在vue中对于元素的style也做了增强处理,操作的过程应该跟这个类似,大家可以试着写写demo