全栈开发技术分享
首页
👉 CSS大揭秘 👈
  • 目录
  • 分类
  • 标签
  • 归档
  • Vue
  • JavaScript
  • 微信开发
  • 移动端H5调试工具
  • 国内十大前端团队网站
  • Nodejs
  • Egg
  • 环境搭建
  • 运维面板
  • 域名配置
  • Nginx
  • 收藏
  • 常用工具
  • 实用技巧
  • 常用命令
  • 友情链接
关于

Dreaming Lee 🍍 ҉҉҉҉҉҉҉҉

开发小菜鸡
首页
👉 CSS大揭秘 👈
  • 目录
  • 分类
  • 标签
  • 归档
  • Vue
  • JavaScript
  • 微信开发
  • 移动端H5调试工具
  • 国内十大前端团队网站
  • Nodejs
  • Egg
  • 环境搭建
  • 运维面板
  • 域名配置
  • Nginx
  • 收藏
  • 常用工具
  • 实用技巧
  • 常用命令
  • 友情链接
关于
  • 代码规范

    • Eslint
    • Eslint-Plugin-Vue
    • Stylelint
  • uniapp

    • 问题解决

      • 【uniapp】字节小程序BUG - “navigateToMiniProgram/getUserProfile:fail must be invoked by user tap gesture”
  • JavaScript

    • JS验证18位身份证号码
    • JS图片压缩
    • JS调用elementUI图片预览
    • JS图片上传前校验大小、尺寸
  • Vue

    • Vue基础教程

      • Vue教程(1)-基础篇
      • Vue教程(2)-路由篇Vue-Router
      • Vue教程(3)- 状态管理Vuex
    • Vue自定义组件开发

      • Vue实现移动端轮播swiper组件
      • Vue实现switch开关组件
        • Switch开关实现功能
        • 演示
        • 基础用法
        • 配置参数
        • 模版调用的回调方法
        • 源码
    • Vue扩展

      • Vue接入阿里OSS文件上传
    • Vue学习参考资料
  • 微信开发

    • 微信开发参考资料
    • 微信公众号

      • 微信公众号/订阅号/服务号主动给用户发消息
      • 微信jssdk自定义分享在iOS不生效
    • 微信小程序

      • 微信小程序区分运行环境:开发版/体验版/正式版
      • H5唤醒微信小程序
  • 收藏

    • 国内十大前端团队官网及GitHub
  • 常见问题解决

    • js错误

      • iframe下localStorage禁止访问。“Failed to read the localStorage property from Window”
      • TypeError: Promise.allSettled is not a function
    • IE兼容

      • fixed定位在IE下页面滚动时抖动
  • 工具

    • 移动端H5调试工具
  • 前端
  • Vue
  • Vue自定义组件开发
Dreaming Lee 🍍 ҉҉҉҉҉҉҉҉
2021-04-17

Vue实现switch开关组件

# Switch开关实现功能

开关组件,支持自定义宽度、开关颜色和开关值。

# 演示

开关

开关--默认

开关状态:false

开关--禁用

开关状态:false

开关--修改颜色(支持渐变色)

开关状态:true

开关--修改状态默认值

开关状态:open

开关--改变宽度

开关状态:false

开关--prevent default

开关状态:false

# 基础用法

<oc-switch v-model="switchValue"></oc-switch>

<oc-switch
  v-model="switchValue"
  activeValue="open"
  inactiveValue="close"
  activeColor="#2b88e3"
  inactiveColor="#f5f5f5"
  :width="54"
  :disabled="false"
  :preventDefault="true"
  @onClick="switchClick"
  @onChange="switchChange"
></oc-switch>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 配置参数

参数 说明 类型 可选值 默认值
value / v-model 绑定值 Boolean / String / Number - false
disabled 是否禁用 Boolean - false
width 开关宽度,单位 px Number - 44
activeValue switch 打开时的值 Boolean / String / Number - true
inactiveValue switch 关闭时的值 Boolean / String / Number - false
activeColor switch 打开时的背景色(支持渐变色) String - #ff5040
inactiveColor switch 关闭时的背景色(支持渐变色) String - #d9d9d9
preventDefault 阻止默认点击事件(用于异步切换开关状态) Boolean - -

# 模版调用的回调方法

方法名 说明 回调参数
onClick switch 点击时的回调函数 点击时的值
onChange switch 状态发生变化时的回调函数 新状态的值

# 源码

点击查看 OcSwiper.vue 组件源码
<template>
  <span
    :class="[
      'oc-switch',
      { 'oc-switch-disabled': disabled },
      checked ? 'oc-switch-active' : 'oc-switch-inactive',
    ]"
    :style="styleObject"
    @click.prevent="clickHandler"
    ref="switch"
  ></span>
</template>
<script>
export default {
  name: "OcSwitch",
  props: {
    value: {
      type: [Boolean, String, Number],
      default: false,
    },
    disabled: {
      // 是否禁用
      type: Boolean,
      default: false,
    },
    activeValue: {
      // switch 打开时的值
      type: [Boolean, String, Number],
      default: true,
    },
    inactiveValue: {
      // switch 关闭时的值
      type: [Boolean, String, Number],
      default: false,
    },
    activeColor: {
      // switch 打开时的背景色(支持渐变色)
      type: String,
      default: "",
    },
    inactiveColor: {
      // switch 关闭时的背景色(支持渐变色)
      type: String,
      default: "",
    },
    width: {
      // 开关宽度,单位px
      type: Number,
    },
    preventDefault: {
      // 阻止默认点击事件(用于异步切换开关状态)
      type: Boolean,
    },
  },
  created() {
    // 若缺省值不在可选范围内,则默认为关。
    if ([this.activeValue, this.inactiveValue].indexOf(this.value) === -1) {
      this.$emit("input", this.inactiveValue);
    }
  },
  computed: {
    checked() {
      return this.value === this.activeValue;
    },
    styleObject() {
      let styleObject = {};
      // 自定义背景色
      if (this.activeColor || this.inactiveColor) {
        let newColor = this.checked ? this.activeColor : this.inactiveColor;
        styleObject.background = newColor;
      }
      // 自定义宽度
      if (this.width) {
        styleObject.width = this.width + "px";
      }
      return styleObject;
    },
  },
  methods: {
    clickHandler() {
      if (this.disabled) return;
      if (this.preventDefault) {
        this.$emit("onClick", this.value);
      } else {
        this.changeValue();
      }
    },
    changeValue() {
      const val = this.checked ? this.inactiveValue : this.activeValue;
      this.$emit("input", val); // 更新父组件值
      this.$emit("onChange", val); // 开关状态改变事件
    },
  },
};
</script>
<style lang="scss" scoped>
$oc-switch-transition-duration: 300ms !default; // switch切换动画时长
$oc-switch-bg-color-active: #ff5040 !default;
$oc-switch-bg-color-inactive: #d9d9d9 !default;
.oc-switch {
  display: inline-block;
  position: relative;
  overflow: hidden;
  width: 44px;
  height: 24px;
  border-radius: 12px;
  transition: all $oc-switch-transition-duration;
  cursor: pointer;
  box-sizing: border-box;
  & * {
    box-sizing: inherit;
  }
  &::before,
  &::after {
    box-sizing: inherit;
  }
  &.oc-switch-disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  &::after {
    content: "";
    position: absolute;
    top: 2px;
    background-color: #fff;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    transition: all $oc-switch-transition-duration;
  }
  &-active {
    background: $oc-switch-bg-color-active;
    &::after {
      left: 100%;
      margin-left: -22px;
    }
  }
  &-inactive {
    background: $oc-switch-bg-color-inactive;
    &::after {
      left: 2px;
    }
  }
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
点击查看 DEMO 源码
<template>
  <div class="demo-switch-page">
    <h1>开关</h1>
    <section class="demo">
      <h2>开关--默认</h2>
      <oc-switch v-model="switchValue1" @onChange="switchChange"></oc-switch>
      <div class="ret">开关状态:{{ switchValue1 }}</div>
    </section>
    <section class="demo">
      <h2>开关--禁用</h2>
      <oc-switch v-model="switchValue1" :disabled="true"></oc-switch>
      <oc-switch
        v-model="switchValue1"
        activeColor="#409eff"
        inactiveColor="#dcdfe6"
        :disabled="true"
      ></oc-switch>
      <oc-switch
        v-model="switchValue1"
        activeColor="#13ce66"
        inactiveColor="#ff4949"
        :disabled="true"
      ></oc-switch>
      <oc-switch
        v-model="switchValue1"
        activeColor="#2b88e3"
        inactiveColor="#f5f5f5"
        :disabled="true"
      ></oc-switch>
      <div class="ret">开关状态:{{ switchValue1 }}</div>
    </section>
    <section class="demo">
      <h2>开关--修改颜色(支持渐变色)</h2>
      <oc-switch
        v-model="switchValue2"
        activeColor="#409eff"
        inactiveColor="#dcdfe6"
      ></oc-switch>
      <oc-switch
        v-model="switchValue2"
        activeColor="#13ce66"
        inactiveColor="#ff4949"
      ></oc-switch>
      <oc-switch
        v-model="switchValue2"
        activeColor="#2b88e3"
        inactiveColor="#f5f5f5"
      ></oc-switch>
      <oc-switch
        v-model="switchValue2"
        activeColor="linear-gradient(to left, #ff6c49 0%, #ff9a3d 100%)"
        inactiveColor="linear-gradient(180deg, #ffe666, #fc3)"
      ></oc-switch>
      <div class="ret">开关状态:{{ switchValue2 }}</div>
    </section>
    <section class="demo">
      <h2>开关--修改状态默认值</h2>
      <oc-switch
        v-model="switchValue3"
        activeValue="open"
        inactiveValue="close"
      ></oc-switch>
      <div class="ret">开关状态:{{ switchValue3 }}</div>
    </section>
    <section class="demo">
      <h2>开关--改变宽度</h2>
      <oc-switch v-model="switchValue4" activeValue="a" :width="40"></oc-switch>
      <oc-switch v-model="switchValue4" activeValue="a" :width="54"></oc-switch>
      <div class="ret">开关状态:{{ switchValue4 }}</div>
    </section>
    <section class="demo">
      <h2>开关--prevent default</h2>
      <oc-switch
        v-model="switchValue5"
        :preventDefault="true"
        @onClick="switchClick"
      ></oc-switch>
      <div class="ret">开关状态:{{ switchValue5 }}</div>
    </section>
  </div>
</template>

<script>
export default {
  name: "DemoSwitch",
  data() {
    return {
      switchValue1: false,
      switchValue2: true,
      switchValue3: "open",
      switchValue4: false,
      switchValue5: false,
    };
  },
  methods: {
    switchChange(msg) {
      console.log("switch change:", msg);
    },
    switchClick(val) {
      alert("你点击了开关");
      this.switchValue5 = !val;
    },
  },
};
</script>

<style lang="scss" scoped>
.demo-switch-page {
  margin: 10px;
}

.demo {
  margin-top: 15px;
  margin-left: 5px;
}

h1 {
  margin-bottom: 12px;
  font-size: 20px;
  color: #ff5040;
}

h2 {
  font-size: 18px;
  color: #ff00ff;
}

.ret {
  margin-top: 10px;
  color: 14px;
}

ul {
  margin-left: 5px;
  width: 150px;
}

li {
  margin-top: 5px;
}

.slot-icon {
  font-size: 24px;
  color: #aaa;
}

.slot-text {
  text-align: left;
  color: 14px;
}
.oc-switch {
  margin-right: 20px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#Switch
上次更新: 2021-05-10 14:08:54
Vue实现移动端轮播swiper组件
Vue接入阿里OSS文件上传

← Vue实现移动端轮播swiper组件 Vue接入阿里OSS文件上传→

最近更新
01
【uniapp】字节小程序BUG - “navigateToMiniProgram/getUserProfile:fail must be invoked by user tap gesture”
06-21
02
七牛云上传自有证书
04-27
03
使用腾讯云申请免费SSL证书
04-27
更多文章>
Theme by Vdoing | Copyright © 2020-2024 | 豫ICP备2020030395号 | 靳立祥 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式