这种功能怎么实现?
肯定有一个布尔值的开关逻辑,初始化的时候为
switchFlag:true
当点击开关的时候
this.switchFlag=!this.switchFlag
,开关动画无非是移动圆点和改变颜色
如果要做成组件,prop应该接收一个开关逻辑
父组件:
<my-switch :flag='switchFlag1'></my-switch>
<my-switch :flag='switchFlag2'></my-switch>
<div v-if='switchFlag1'>开</div>
<div v-else>关</div>
子组件接收一个
props:['flag']
再写逻辑。
只给个思路,其实很多组件库都有开关
代码:
父组件:
<template>
<div>
<mySwitch :flag=switchFlag @changeFlag="changeFlag"></mySwitch>
{{status}}
</div>
</template>
<script>
import mySwitch from './my-btn.vue'
export default {
data(){
return{
switchFlag:false
}
},
computed:{
status(){
return this.switchFlag?'开':'关'
}
},
components:{mySwitch},
methods:{
changeFlag(){
this.switchFlag=!this.switchFlag;
}
}
}
</script>
子组件:
<template>
<div>
<div class="switch-panel">
<span class="switch-icon" :class="{'switch-on':flag,'switch-close':!flag}" @click='changeSwitch'></span>
</div>
</div>
</template>
<script>
export default {
props:['flag'],
methods:{
changeSwitch(){
this.$emit('changeFlag')
}
}
}
</script>
<style>
.switch-panel{width: 50px;height: 20px;border: 1px solid #e4e4e4;border-radius: 20px;position: relative;}
.switch-icon{display: block;width: 16px;height:16px;border-radius: 8px;top: 1px;left: 2px;cursor: pointer;position: absolute;transition: all .5s}
.switch-on{background-color: green;left:30px;}
.switch-close{background: #d4d4d4;}
</style>
效果:
上一个小 demo ,引入方式自行修改
switch.html
<div class="switch">
<span class="switch-input">
<input type="checkbox" :false-value=0 :true-value=1 v-model="val">
<span class="input-box"></span>
</span>
<div class="switch-label"><slot></slot></div>
</div>
switch.js
/*
switch切换
*/
var vue = require('vue.js');
module.exports = vue.component('switch',{
template:__inline('./switch.html'),
props:{
val:{
type:[Number,String],
require:true,
twoWay: true
}
},
data:function(){
return {};
}
});
switch.less
.switch {
display: inline-flex;
flex-direction: row;
align-items: center;
vertical-align: middle;
.switch-input{
position: relative;
width: 52px;
height: 32px;
input{
position: absolute;
left: 0;
top: 0;
width: 50px;
height: 30px;
z-index: 99;
cursor: pointer;
display: inline-block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
opacity: 0;
&:focus{
outline: none;
}
}
input:checked + .input-box{
border-color: #26a2ff;
background-color: #26a2ff;
&::before {
-webkit-transform: scale(0);
transform: scale(0);
}
&::after {
-webkit-transform: translateX(20px);
transform: translateX(20px);
}
}
.input-box {
position: absolute;
cursor: pointer;
width: 52px;
height: 32px;
border: 1px solid #d9d9d9;
outline: 0;
border-radius: 16px;
box-sizing: border-box;
background: #d9d9d9;
&::after,
&::before{
content: "";
top: 0;
left: 0;
position: absolute;
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
border-radius: 15px;
}
&::after{
width: 30px;
height: 30px;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}
&::before{
width: 50px;
height: 30px;
background-color: #fdfdfd;
}
}
}
.switch-label {
margin-left: 10px;
display: inline-block;
&:empty {
margin-left: 0;
}
}
}
10 回答11.2k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答1.5k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
用绑定不同class的方法来做:
在vue实例中写入标记和开关方法:
css样式:
这样就能通过点击时改变css属性,并配合transition来实现动态开关了。