哈罗大家好~
不知道昨天的进度条做的怎麽样?
想要交作业的人可以贴在昨天的留言区给我呦!
那我们今天的内容也很简单,
二话不说,要开始罗?
跟昨天的环境相同,兔兔为了写文章方便是重新建立了一个,你们可以重新建立新的专案从头练习一次,也可以在昨天做完的专案直接多增加新的元件哦!
和昨天一样,先建立空白元件,所以在专案里的 ./src/components
资料夹中新增一个 RabbitButton.vue
的元件:
完成後,增添以下内容:
<template>
</template>
<script>
export default {
name: "RabbitButton",
}
</script>
接着我们就可以把这个元件新增到画面中,打开 App.vue
然後内容跟昨天差不多:
<template>
<div :class="[
'w-screen h-screen',
'flex flex-col',
'justify-center items-center',
'gap-5',
]"
>
<RabbitButton />
</div>
</template>
<script>
import RabbitButton from './components/RabbitButton.vue'
export default {
data() {
return {
}
},
components: {
RabbitButton,
}
}
</script>
这样准备工作大妥当,开始按钮博物馆导览啦!
按钮的要素其实很简单,不外乎就是一个中间有字的矩形,滑鼠悬停时有颜色变化,最好的话连按下後也有相对应的效果,才是一个良好的互动。
那麽基於这些要素,我们就可以这麽做:
px-6
、py-3
rounded-md
、font-bold
bg-gray-400
、hover:bg-gray-300
、active:bg-gray-500
hover:scale-105
、active:scale-95
transition-all
按钮
二字让它不会被误认吧?所以综合起来,就会像是这样:
<template>
<div
:class="[
'px-6 py-3',
'rounded-md font-bold',
'bg-gray-400 hover:bg-gray-300 active:bg-gray-500',
'hover:scale-105 active:scale-95',
'transition-all'
]"
>
按钮
</div>
</template>
<script>
export default {
name: "RabbitButton",
}
</script>
这麽快就有 fu 了吗?
哎呀後面还有更有趣的啦!
毕竟我们现在按钮还非常的单调,
让我们来帮它点缀一下!
Yes,这麽快就来到了我们动起来的环节了。
别以为会这麽轻易地结束,
我们现在看到的按钮是这个样子:
可是兔兔期待的是这个样子:
哇,还是有点落差对吧?
「摁,是没错啦,但不就是差个 icon 和颜色而已嘛 ... 不过每次插入 svg 的 icon 都会觉得把结构弄得好杂乱 ...」
嘿嘿,这个立马帮你解决!
没错,这就是轮到不知道甚麽时候才能派上用场但现在就派上用场的 Slot 啦!
slot 可以把原本一直要替换的东西从内部解藕出来,那麽一来我们在外面替换时就不用一直修改元件的内部功能了~
现在在文字前後帮按钮加上两个 slot,分别取名为 iconLeft
和 iconRight
,然後因为想要 icon 和文字可以横向排列且之间有点空隙,我们顺便加上 flex gap-2
的样式:
<!-- RabbitButton.vue -->
<div
:class="[
'flex gap-2',
'px-6 py-3',
'rounded-md font-bold',
'text-white',
'bg-blue-400 hover:bg-blue-300 active:bg-blue-500',
'hover:scale-105 active:scale-95',
'transition-all'
]"
>
<slot name="iconLeft" />
按钮
<slot name="iconRight" />
</div>
这麽一来就可以轻松的在按钮文字的前或後加上 icon 啦!
然後啊,Tailwind 官方的专案中有个特别的网站,叫做 heroicons
,虽然里面的 icon 量真的不多,但是各个都是精心设计过,适合搭配 Tailwind 直接使用的 icon,还可以直接复制 svg,算是很方便啦~
我们回到 App.vue
,兔兔这边要用的 icon 就是在 heroicons 上面找的 wifi
icon (不是 wife,要认明。),然後包在指定 iconLeft 插槽
的 template 中:
<!-- App.vue -->
<div
:class="[
'w-screen h-screen',
'flex flex-col',
'justify-center items-center',
'gap-5',
]"
>
<RabbitButton>
<template v-slot:iconLeft>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0" />
</svg>
</template>
</RabbitButton>
</div>
赞啦,这样真的很方便,把 icon 从元件中抽离之後就可以随时替换了!
可是 ...
(你这兔又来了,果然不管做的怎麽样都有话要说!)
就是真的需要提出来啦!
按钮的文字和颜色的改变的确是还不方便,所以我们就必须用到 ...
对,就是 Props。
我们刚刚说到要改变文字和颜色,所以就帮 props 增加两个内容,但这两个内容都必须要有预设值:
<script>
export default {
name: "RabbitButton",
props:{
text: {
default: "按钮"
},
color: {
default: "gray"
},
},
}
</script>
我们先来解决按钮文字的部分,把按钮
的字样取代成 {{ text }}
:
<div
:class="[
'flex gap-2',
'px-6 py-3',
'rounded-md font-bold',
'text-white',
'bg-gray-400 hover:bg-gray-300 active:bg-gray-500',
'hover:scale-105 active:scale-95',
'transition-all'
]"
>
<slot name="iconLeft" />
{{ text }}
<slot name="iconRight" />
</div>
再来,就要解释到为什麽 color 要有预设值且预设值是字串了。 因为我们要利用物件 (字典) 的特性来快速的切换按钮的色系!
为了方便监控和节省资源,我们先在 computed 中建立一个 colorSelector 函数,并返回一个空白物件。
<script>
export default {
name: "RabbitButton",
props:{
text: {
default: "按钮"
},
color: {
default: "gray"
},
},
computed: {
colorSelector() {
return {}
}
}
}
</script>
建立好之後,我们把元件中颜色的那一行 tailwind 语法加到物件中并命名为 gray
,且在物件後加上 [this.color]
来让函数找到并返回指定名称为 gray
的内容:
<script>
export default {
name: "RabbitButton",
props:{
text: {
default: "按钮"
},
color: {
default: "gray"
},
},
computed: {
colorSelector() {
return {
gray: 'bg-gray-400 hover:bg-gray-300 active:bg-gray-500',
}[this.color]
}
}
}
</script>
然後把 colorSelector 函数加回 class 列表,并测试一次:
<div
:class="[
'flex gap-2',
'px-6 py-3',
'rounded-md font-bold',
'text-white',
colorSelector,
'hover:scale-105 active:scale-95',
'transition-all'
]"
>
<slot name="iconLeft" />
{{ text }}
<slot name="iconRight" />
</div>
看起来没什麽变化是正常的,但至少这表示没写错!
打铁要趁热,我们接着来追加其他颜色吧~
最後追加完,完整的 code 可能会是这个样子:
<template>
<div
:class="[
'flex gap-2',
'px-6 py-3',
'rounded-md font-bold',
'text-white',
colorSelector,
'hover:scale-105 active:scale-95',
'transition-all'
]"
>
<slot name="iconLeft" />
{{ text }}
<slot name="iconRight" />
</div>
</template>
<script>
export default {
name: "RabbitButton",
props:{
text: {
default: "按钮"
},
color: {
default: "gray"
},
},
computed: {
colorSelector() {
return {
gray: 'bg-gray-400 hover:bg-gray-300 active:bg-gray-500',
green: 'bg-green-400 hover:bg-green-300 active:bg-green-500',
blue: 'bg-blue-400 hover:bg-blue-300 active:bg-blue-500',
red: 'bg-red-400 hover:bg-red-300 active:bg-red-500',
yellow: 'bg-yellow-400 hover:bg-yellow-300 active:bg-yellow-500',
}[this.color]
}
}
}
</script>
然後这边值得注意的是,为什麽不用变数取代 bg-XXX-400
、hover:bg-XXX-300
就好了呢? 为何还要这样大费周章地去把 class 名称都写过一遍?
因为要让 purge 读取
到要编译的 class 的话,class 名称
必须保持完整
,不能被拆开!
所以为了要让样式能正确被读取到且被编译,不能使用 "bg-" + color + "500"
或是 "opacity-" + number
这种组合过的形式,这对 Tailwind 来说是不合法的 class 名称哦。
既然完成了,我们就快点来测试吧!
好兴奋啊!
最後的测试环境,我们来做三个按钮吧!
然後为了美化中的美化,我们可以在按钮元件中加上 cursor-pointer
让它看起来更像样!
第一个按钮,就是最普通的按钮啦!
<RabbitButton />
再来是让人看起来很连网路的 wifi 按钮!
<RabbitButton text="wifi" color="blue">
<template v-slot:iconLeft>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0" />
</svg>
</template>
</RabbitButton>
最後,是安装软件时会出现的下一步
按钮~
<RabbitButton text="下一步" color="green">
<template v-slot:iconRight>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
</svg>
</template>
</RabbitButton>
OK,超成功的啦!
今天是不是也很轻松简单啊?
兔兔觉得这样做按钮又美、弹性又高!
以後遇到再多状况也只要小修改就能够继续使用了,
这有再度登场的机会正是做元件的目的!
希望你们都能够试试看,如果有更好方法或建议 ...
做成作业留言给我看嘿!!!!
关於兔兔们:
( # 兔兔小声说 )
不是兔兔偷懒,兔兔只是陪富坚去取材。
我相今天的篇章是大家期待已久的,因为经过前面十天的努力,今天终於要将我们的部落格公开在世人面前啦!不...
Day 23 - 前端开发工具 - HBuilder X 完成了後端开发,接下来就要将透过前端跨平台...
前言 前一天大致上了解一下,TypeScript 有支援哪些型别,从今天开始,将一一来每一个型别的定...
一样先上进度log: + exec /bin/busybox switch_root /sysroo...
正文 我预计做的是一个很简易的post/get application,而目前只预计会有4只极度简陋...