一、switch组件很简单
1.达到的效果
- 点击后按钮里面的白点可以移动;
- 灰底变蓝底;
- 就以上这两种效果有何难的呢。
2.代码如何写
1)外边的框,里面的圆(硬件基础)
- 这个框就是个按钮,用button表示(h2:$h - 4px;)
- 需要高度h:height: $h;
- 宽度1/2h:width: $h * 2;
- 边框无,border: none;
- 背景为灰色, background: #bfbfbf;
- 边框的圆角为1/2h,border-radius: $h/2;
- 相对定位:position: relative;
- 这个圆就是button里面的span;
- 绝对定位:absolute;
- 距离边框上端2px;top: 2px;
- 距离边框左端2px; left: 2px;
- 高度h2; height: $h2;
- 宽度h2; width: $h2;
- 背景白色; background: white;
- 边框的圆角1/2h2; border-radius: $h2 / 2;
- 点击时动画的时间250ms; transition: all 250ms;
2)如何点击就能移动(软件)
- 首先要在button上绑定一个click事件,这样点击时,才会有反应。
<button @click="toggle" >这个toggle的作用就是点击后切换真假值的。X=! X - 还需在button上绑定一个class事件,表达click事件后,button应该做什么反应。
<button @click="toggle" :class="{checked}">
<span></span>
</button>
3)在SwitchDemo中
<switch value="false" @input=""/> 这个value是最初的值,最新的值传到input里面,如何获取,需要用一个变量获取
<switch value="false" @input=""/>
--------------------------
setup(){
const y = ref(true)
return {y}
}
解释:命名一个变量y,那么value的值就是y,当有任何变化的时候,让y等于最新的值$event
- 转过来在switch.vue里面,接收这个value,用props接收
<script>
export default{
props:{
value:Boolean}
}
</script>
这样用props接收之后,从外部传来的value值就可以直接用了{{value}}; 外部的 <switch :value="false" @input=""/>,value前加冒号是变量y,不加冒号则是字符串y。
- 既然在switch里面可以获取外部点击按钮的value值,那么在内部 <button @click="toggle" :class="{checked}">里面的checked的值就就可以用value表示可以写成
<button @click="toggle" :class="{checked}"现在的代码如下:
<template>
<div>
<Switch :value="y" @input="y=$event"/>
<!**--value显示switch的状态,但这个状态是死的,让y等于最新的值,就是最新的状态-->
</div>
</template>
<script lang="ts">
import Switch from '.....'
import {ref} from 'vue'
export default{
components:{Switch},
setup(){
const y = ref(false)
return {y}
}
}
</script>
</script>
下面是内部的函数层面
<template>
<button @click="toggle" :class="{checked:value}">
<span></span>
</button>
</template>
<script lang="ts">
import {ref} from "vue";
export default {
props:{
value:Boolean,
},
setup(props ,context){
const toggle = ()=>{
context.emit("input",!props.value);
};
return {toggle};}
}
</script>
toggle的作用就是把当前的值取反,通过input事件用emit发送出去。
Vue3新版用v-model用法重新表示:
- 因为props里面的是value,所以那个input事件要写成‘update:value’;
- 所以外部的@input也要改成,@update:value=“y=$event";
- 简化,要把@update:value=“y=$event"删掉,在:value=“y”之前加v-model;
- 加了v-model后,是双向绑定,value可以自动监听
第一步:什么事Switch组件
Switch就是一个开关两个状态。  第二步:API设计
第三步:写代码
在SRC里面新建一个文件夹lib,在lib文件夹里新建文件switch.vue;
- 因为是开关,所以先写一个button:switch;
- 在button里面加一个圆圈,让其来回滚动,表示开关的状态;
<style lang="scss" scoped>
$h:22px;
$h2:$h - 4px;
button{
height:$h;
width:$h*2;
border:none;
background:blue;
border-radius:$h/2;
position:relative;
}
span{
position:absolute;
top:2px;
left:2px;
height:$h2;
width:$h2;
background:white;
border-radius:$h2/2;
加一个transition:left 1s;
}
- 上面的代码就会出现,蓝色框里有个白圈。
- 解说relative:是在其他时间占据位置后进行寻找位置;
- 解说absolute,是在以父文件的基础上进行排序;
Hover让白色圆圈滚到右边
- 原理:是点击后在原来的基础上进行移动;
- 起始位置是left:2px;
- 结束位置left:calc(100%-#{$h2}-2px);
- 这个结束位置要单独拿出来
button:hover > span{
left:calc(100%-#{$h2}-2px);
}
以上是悬浮切换,接下来要变成点击切换,并伴有动画。
点击开关切换,并伴有动画
- 现在写一个
<script lang = “ts” >
import {ref} from 'vue'
export default{
setup(){
const x = ref(false)
const toggle = ()=>{
x.value=!x.value
}
return {X,toggle}
}
}
</script>
最后可以把x都替换成checked
- 在setup(){}里面声明一个值,const x = ref(false) return {x}
- 在button里面,用x作为class的一个类,
- 解释:如果X的值是true,那么button的class就是checked,如果是false则不是;
- 因为ref是一个盒子,不能改变,所以用它的值x.value来表达;
- 所以上面的hover要改成checked
如果是选中之后,背景可以变成红色,未选中就是蓝色
button.checked {
background:red;}
button:checked > span{
left:calc(100%-#{$h2}-2px);
如果有黑色边框可以加一个button:focus{
outline:none;}
}
在switch里面添加value和input
- 在SwitchDemo.vue里面的田间value=“y”和@input=“y=$event ”;这个value前面要加冒号:,不然接受的值是字符串而不是布尔值。
- 在@input里面传入最新的值;
- 怎么获取这个值呢,用变量获取;
setup(){
const y = ref(true)
return {y}}
如何用switch接受value
- 在switch里面加入props
export default {
props:{
value: Boolean }
- 这样直接可以获取了,在button后面写入:
<div>{{value}}</div>
最终代码
<template>
<button @click="toggle" :class="{checked:value}">
<span></span>
</button>
</template>
<script lang="ts">
import { ref } from "vue";
export default {
props: {
value: Boolean,
},
setup(props, context) {
const toggle = () => {
context.emit("update:value", !props.value);
};
return { toggle };
},
};
</script>