兔女鹅:
「爸爸,兔兔昨天讲的好难」
「有一大堆东西要记起来,要学不动了 QQ」
兔跋:
「一定是家里的装潢太压抑,要换!」
兔女鹅:
「不是,爸爸...应该跟装潢没...」
兔跋:
「要换!」
兔女鹅:
「摁...要换。」 (苦笑
兔跋:
「要换! 既然你也同意了」
「那我就去跟你妈说一声」
兔女鹅:
「可恶,被我爸算计了吗...」
「装潢哪有这麽轻易说换就换的啦...!」
有啦,还真的有!
而且还可以选择性的换哦!
你爸肯定是要用 Tailwind 来重新粉刷!
让我们看看兔跋要怎麽做吧~
昨天有介绍到属性绑定的部分,
就是透过 v-bind 可以简单的实现。
我们再来看一次属性绑定的用法:
<template>
<div :id="id"> # {{id}}</div>
</template>
<script>
export default {
data() {
return {
id: "test"
}
}
}
</script>
那之前也说过,几乎所有的属性都可以绑定,所以要绑定 style 与 class 来动态改变样式
也是可行的!
就让我们先从 style 绑定看起吧!
要绑定 style,必须要注意一下绑定的变数形式。
最基本,你可以直接给他字串,例如:
<template>
<div :style="'color:red'">兔兔教</div>
</template>
但这样其实跟你直接写并没有两样。
你也可以把它整理到 data( ) 中:
<template>
<div :style="mystyle">兔兔教</div>
</template>
<script>
export default {
data() {
return {
mystyle: "color:red"
}
}
}
</script>
所以若要在加上个蓝色背景的话:
<template>
<div :style="mystyle">兔兔教</div>
</template>
<script>
export default {
data() {
return {
mystyle: "color:red;background-color:blue"
}
}
}
</script>
如果觉得这串太长太碍眼了,也可以用阵列包起来。
<template>
<div :style="mystyle">兔兔教</div>
</template>
<script>
export default {
data() {
return {
mystyle: [
"color:red",
"background-color:blue",
].join(';')
}
}
}
</script>
需要
.join(';')
是因为 inline style 每个属性皆是用分号 ( ; ) 隔开。
不过其实上述的方法都不好,
因为它还是字串,不够灵活。
如果要在里面使用变数非常的麻烦,
所以最好的方式应该是使用物件:
<template>
<div :style="mystyle">兔兔教</div>
</template>
<script>
export default {
data() {
return {
mystyle: {
"color": 'red',
"background-color": 'blue',
}
}
}
}
</script>
这样我们就可以透过改变物件属性的方式来改变样式了!
比如按下按钮之後,文字会变成黄色:
<template>
<div :style="mystyle">兔兔教</div>
<button @click="mystyle.['color']='yellow'">黄字</button>
</template>
<script>
export default {
data() {
return {
mystyle: {
"color": 'red',
"background-color": 'blue',
}
}
}
}
</script>
不知道你有没有注意到按钮上的写法,
用阵列 key 值的方式太累了,
我们想要直接存取属性的话,
我们必须把属性以小驼峰命名方式呈现。
举例,这样就可以了:
<template>
<div :style="mystyle">兔兔教</div>
<button @click="mystyle.color='yellow'">黄字</button>
</template>
<script>
export default {
data() {
return {
mystyle: {
color: 'red',
backgroundColor: 'blue',
}
}
}
}
</script>
善用这个方法,我们就可以做到切换主题。
<template>
<div :style="getStyle">兔兔教</div>
<button @click="theme='red'">红色主题</button>
<button @click="theme='blue'">蓝色主题</button>
<button @click="theme='green'">绿色主题</button>
</template>
<script>
export default {
data() {
return {
theme: "red",
mystyle: {}
}
},
computed: {
getStyle(){
if(this.theme==='red'){
this.mystyle.color = 'red'
this.mystyle.backgroundColor = 'pink'
}
else if(this.theme==='blue') {
this.mystyle.color = 'blue'
this.mystyle.backgroundColor = 'lightblue'
}
else {
this.mystyle.color = 'green'
this.mystyle.backgroundColor = 'lightgreen'
}
return this.mystyle
}
}
}
</script>
这份切换主题的范例也有实作出来版本的,放在文章尾部。
那 style 绑定属性的方法和要注意的点就差不多这样,有了这灵活绑定属性的功能,就能简单做到像是读取进度条那种用数值变化位置或宽度的效果。
还有个小补充。
一般来说 html 不接受重复属性,
比如说不能一个元素出现两个 style 之类的。
但是因为绑定是会把运算完的结果加上去,所以可以做到重覆属性的部分。而至於为何要重复属性?
因为可能有些不会变动的样式你不希望一起写到变数中时,就可以这麽做!
举例:
<template>
<div style="line-height:2.5rem" :style="mystyle">兔兔教</div>
<button @click="mystyle.color='yellow'">黄字</button>
</template>
<script>
export default {
data() {
return {
mystyle: {
color: 'red',
backgroundColor: 'blue',
}
}
}
}
</script>
接着赶快我们进入 class 的部分吧!
终於进入到重头戏了啦!
既然是要使用 Tailwind,
那 class 的绑定绝对是必须要知道的!
毕竟 Tailwind 的语法有机会变很长,
还有为了要可以动态切换,
才能做出更多样化的效果!
跟 style 的绑定方式差不多,
不过通常为了保持设计与视觉一致,
我们不会把他拉出来到变数之中存放。
拿之前的 Box 举例:
<template>
<div
:class="[
[
'w-20 h-20 bg-gray-500 rounded-md',
'focus:ring-4 group-hover:text-gray-600',
'font-bold text-3xl text-white',
'flex justify-center items-center',
'cursor-pointer outline-none'
],
(color==='red') && 'bg-red-500 hover:bg-red-400 ring-red-300',
(color==='blue') && 'bg-blue-500 hover:bg-blue-400 ring-blue-300',
(color==='purple') && 'bg-purple-500 hover:bg-purple-400 ring-purple-300'
]"
:tabindex="number"
>
{{ number }}
</div>
</template>
<script>
export default {
name: "Box",
props: ["number", "color"]
}
</script>
上面这样是有经过整理的,不然会超~长一串。
而且这样整理的好处就是,
还可以把要吃变数的样式分离出来,
而 class 不需要 join(';')
,
因为 vue 预设会把他们用空白字元串接在一起。
上面得范例可能太复杂了,
我们换一个范例来解释。
然後顺便用 vue 官方上写的用物件的方式。
以前面的 style 切换主题为例,用 class 写而且是 Tailwind 的话,复杂度可以降低很多:
<template>
<div
:class="{
'leading-10':true,
'text-red-600 bg-red-300': theme==='red',
'text-blue-600 bg-blue-300': theme==='blue',
'text-green-600 bg-green-300': theme==='green',
}"
>
兔兔教
</div>
<button @click="theme='red'" class="p-1 m-1 bg-gray-200 rounded">
红色主题
</button>
<button @click="theme='blue'" class="p-1 m-1 bg-gray-200 rounded">
蓝色主题
</button>
<button @click="theme='green'" class="p-1 m-1 bg-gray-200 rounded">
绿色主题
</button>
</template>
<script>
export default {
data() {
return {
theme: "red",
}
},
}
</script>
有发现吗,下面整个 computed 都不用写了,简单很多。
我们把最上面那块抽出来讲解一下:
<template>
<div
:class="{
'leading-10':true,
'text-red-600 bg-red-300': theme==='red',
'text-blue-600 bg-blue-300': theme==='blue',
'text-green-600 bg-green-300': theme==='green',
}"
>
兔兔教
</div>
有发现什麽玄机吗?
仔细看应该会发现都是以 {'classNames': boolean}
的方式呈现,也就是说 Vue 在帮元素加上这些 class 时,只会加上 vaule 是 true 的 class
,如果是 false 则会直接被省略掉。
但这写法并不优。 为什麽?
不优的原因就在於第一个的样式 leading-10
,它是一个并不会变动的 class,但是为了让它可以被加在元素上,你仍然要给一个 true
的 boolean 值。
所以我们要活用 js 中的 Truthy!
若是字串不为 ""
,
那它就会是 true!
运用这个道理,我们把它以物件和阵列的混写的
方式来达成:
<template>
<div
:class="[
'leading-10',
{
'text-red-600 bg-red-300': theme==='red',
'text-blue-600 bg-blue-300': theme==='blue',
'text-green-600 bg-green-300': theme==='green',
}
]"
>
兔兔教
</div>
这样是不是好多了呢?
固定的样式我们就直接是字串
就好了,
底下需要变动的才写成物件。
不过...其实这还是不好。
(乾,兔兔又觉得不好了!)
应该要像我们前面一样,
全部都用阵列解决就好!
那再改写一下:
<template>
<div
:class="[
'leading-10',
theme==='red'? 'text-red-600 bg-red-300': '',
theme==='blue'? 'text-blue-600 bg-blue-300': '',
theme==='green'? 'text-green-600 bg-green-300': '',
]"
>
兔兔教
</div>
欸?
用三元运算子
变成字串,
然後空字串就是 false 嘛?
哦!
不错哦!这想法 ...!
还可以再更好一些 XDDD
我们可以试着运用这个方法啦!
const result1 = false && "123" // false
const result2 = true && "123" // "123"
这样看懂了吗?
没有错! 用 AND!
如果今天前方的条件为 false
,
会直接回传 false
,
但如果今天前方条件是 true
,
则会往後运算,
最後返回的是後面的字串
!
要是不这麽做啊,
我们还得再多写一个空字串,
我不要!我不要!
所以,最後我们这样写:
<div
:class="[
'leading-10',
theme==='red' && 'text-red-600 bg-red-300',
theme==='blue' && 'text-blue-600 bg-blue-300',
theme==='green' && 'text-green-600 bg-green-300',
]"
>
兔兔教
</div>
这样的写法就跟之前的 box 一样了!
那所谓的分类你可能没感受到,我们就再来多加一个功能。
我们用 transition-all
来加上过渡效果,并再多加一个 duration-500
让过度效果不要太快,不然就看不出来了。
加上去之後:
<div
:class="[
'leading-10',
'transition-all duration-500',
theme==='red' && 'text-red-600 bg-red-300',
theme==='blue' && 'text-blue-600 bg-blue-300',
theme==='green' && 'text-green-600 bg-green-300',
]"
>
兔兔教
</div>
这样一行一行的,就可以把相同用途
的功能放在一起,不但撰写起来轻松,逻辑也很清晰哦,要维护时就不会这麽困难了!
那这边就放上完整的元件内容:
<template>
<div
:class="[
'leading-10',
'transition-all duration-500',
theme==='red' && 'text-red-600 bg-red-300',
theme==='blue' && 'text-blue-600 bg-blue-300',
theme==='green' && 'text-green-600 bg-green-300',
]"
>
兔兔教
</div>
<button @click="theme='red'" class="p-1 m-1 bg-gray-200 rounded">
红色主题
</button>
<button @click="theme='blue'" class="p-1 m-1 bg-gray-200 rounded">
蓝色主题
</button>
<button @click="theme='green'" class="p-1 m-1 bg-gray-200 rounded">
绿色主题
</button>
</template>
<script>
export default {
data() {
return {
theme: "red",
}
},
}
</script>
这个范例的连结也会放在文章尾部!
最後来补充一下,同样的版搬到 React 也几乎可以马上使用! 要靠一个叫做 clsx
的 npm 套件,然後修改一下直接用:
<div
className="clsx(
'leading-10',
'transition-all duration-500',
theme==='red' && 'text-red-600 bg-red-300',
theme==='blue' && 'text-blue-600 bg-blue-300',
theme==='green' && 'text-green-600 bg-green-300',
)"
>
兔兔教
</div>
摁,只要你变数名称一模一样,上面这段就可以直接拉去 React 用
罗!
那 class 的部分就这样详解完啦~~
跟前几天的相比,
今天有没有比较简单呢? (笑)
不过就是范例的量可能比较多啦,
慢慢看一定没有问题的!
听说只要说要考试,
学生们的学习能力就会大增
,
那我是不是下次来出个考... (被摀嘴)
兔女鹅:
「爸爸,我把老师的嘴摀住了,心里不烦了,可以求你不要重新换我房间的装潢吗...!」
兔跋:
「 ... 」
「 要换!」
关於兔兔们:
( # 兔兔小声说 )
你们知道广告上的这句
「心中若少软萌兔,编译再也无一物」
其实,
是有下一句的吗?
Callback Function 回呼函式 Callback Function 其实描述的就是一个...
D6: for回圈 最基本的for回圈样式是: for (变数初始值; 判断式; 递增式){ 陈述句...
第十八天 各位点进来的朋友,你们好阿 小的不才只能做这个系列的文章,但还是希望分享给点进来的朋友,知...
系列文章要到结尾了,今天想分享一些几篇关於「社会对人工智慧的期待与影响」的文章。 未来,您对人工智慧...
前言 工作了好一段时间後,直到那次处理了OOM(Out Of Memory)问题,才发现JDK内有很...