Switches.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <template>
  2. <label :class="classObject">
  3. <input
  4. v-model="value"
  5. type="checkbox"
  6. :disabled="disabled"
  7. @click="clickEvent($event)"
  8. />
  9. <div />
  10. <span
  11. v-if="showText === undefined || showText === null || showText === true"
  12. class="vue-switcher__label"
  13. >
  14. <span
  15. v-if="value"
  16. v-text="textTrue"
  17. />
  18. <span
  19. v-if="!value"
  20. v-text="textFalse"
  21. />
  22. </span>
  23. </label>
  24. </template>
  25. <script>
  26. export default {
  27. name: 'Switches', // eslint-disable-line
  28. props: {
  29. // 选择状态, false
  30. 'modelValue':
  31. {
  32. type: Boolean,
  33. default: false,
  34. },
  35. // 禁用, false
  36. 'disabled':
  37. {
  38. type: Boolean,
  39. default: false,
  40. },
  41. // 是否显示文字提示
  42. 'showText':
  43. {
  44. type: Boolean,
  45. default: false,
  46. },
  47. // True状态下的文字
  48. 'textTrueIn':
  49. {
  50. type: String,
  51. default: '',
  52. },
  53. // False状态下的文字
  54. 'textFalseIn':
  55. {
  56. type: String,
  57. default: '',
  58. },
  59. // 显示的颜色default,primary,success,info,warning,danger
  60. 'color':
  61. {
  62. type: String,
  63. default: '',
  64. },
  65. // 大图标
  66. 'typeBold':{
  67. type: Boolean,
  68. default: false,
  69. },
  70. },
  71. emits: ['update:modelValue'],
  72. data: function () {
  73. var tempValue = false;
  74. var colors = 'red';
  75. if (this.modelValue != undefined) {
  76. tempValue = (this.modelValue == 'true' || this.modelValue == true);
  77. if (this.modelValue == 'true' || this.modelValue == true) {
  78. colors = 'green';
  79. } else {
  80. colors = 'red';
  81. }
  82. }
  83. return {
  84. 'value': tempValue,
  85. 'textTrue': (this.textTrueIn == undefined) ? '是' : this.textTrueIn,
  86. 'textFalse': (this.textFalseIn == undefined) ? '否' : this.textFalseIn,
  87. 'theme': 'default',
  88. 'colorCss': colors,
  89. };
  90. },
  91. computed: {
  92. classObject: function () {
  93. var _self = this;
  94. return {
  95. 'vue-switcher': true,
  96. ['vue-switcher--unchecked']: !_self.value,
  97. ['vue-switcher--disabled']: !!_self.disabled,
  98. ['vue-switcher--bold']: !!_self.typeBold,
  99. ['vue-switcher--bold--unchecked']: !!_self.typeBold && !_self.value,
  100. [`vue-switcher-theme--${_self.theme}`]: _self.theme,
  101. [`vue-switcher-color--${_self.colorCss}`]: _self.colorCss,
  102. };
  103. },
  104. },
  105. watch: {
  106. value: function (val, oldVal) { // eslint-disable-line
  107. this.$emit('update:modelValue', val);
  108. },
  109. modelValue: function (val, oldVal) { // eslint-disable-line
  110. if (val != undefined) {
  111. this.value = (val == 'true' || val == true);
  112. if (val == 'true' || val == true) {
  113. this.colorCss = 'green';
  114. } else {
  115. this.colorCss = 'red';
  116. }
  117. }
  118. },
  119. },
  120. methods: {
  121. clickEvent: function (e) {
  122. var clientX = e.clientX;
  123. var elm = $(e.target);
  124. var left = elm.offset().left;
  125. if (clientX - left > 50) {
  126. e.preventDefault();
  127. }
  128. },
  129. },
  130. };
  131. </script>
  132. <style>
  133. .vue-switcher {
  134. position: relative;
  135. display: inline-block;
  136. width: 100px;
  137. height: 26px;
  138. line-height: 26px;
  139. margin-bottom: 0px;
  140. top: 7px;
  141. }
  142. .vue-switcher__label {
  143. position: absolute;
  144. left: 50px;
  145. top: 0px;
  146. height: 26px;
  147. line-height: 26px;
  148. display: block;
  149. font-size: 10px;
  150. margin-bottom: 0px;
  151. }
  152. .vue-switcher input {
  153. position: absolute;
  154. left: 0px;
  155. top: 0px;
  156. width: 50px;
  157. height: 26px;
  158. line-height: 26px;
  159. opacity: 0;
  160. z-index: 1;
  161. cursor: pointer;
  162. margin: 0px !important;
  163. }
  164. .vue-switcher div {
  165. position: absolute;
  166. left: 0px;
  167. top: 8px;
  168. width: 40px;
  169. height: 10px;
  170. border-radius: 30px;
  171. display: -webkit-flex;
  172. display: -ms-flex;
  173. display: flex;
  174. align-items: center;
  175. justify-content: flex-start;
  176. cursor: pointer;
  177. }
  178. .vue-switcher div:after {
  179. position: absolute;
  180. top: -4;
  181. left: 100%;
  182. content: "";
  183. height: 18px;
  184. width: 18px;
  185. border-radius: 100px;
  186. display: block;
  187. transition: all ease 0.3s;
  188. margin-left: -17px;
  189. cursor: pointer;
  190. }
  191. .vue-switcher--unchecked div {
  192. justify-content: flex-end;
  193. }
  194. .vue-switcher--unchecked div:after {
  195. left: 15px;
  196. }
  197. .vue-switcher--disabled div {
  198. opacity: 0.3;
  199. }
  200. .vue-switcher--disabled input {
  201. cursor: not-allowed;
  202. }
  203. .vue-switcher--bold div {
  204. top: 0px;
  205. height: 26px;
  206. width: 50px;
  207. }
  208. .vue-switcher--bold div:after {
  209. margin-left: -22px;
  210. top: 4px;
  211. }
  212. .vue-switcher--bold--unchecked div:after {
  213. left: 26px;
  214. }
  215. .vue-switcher--bold .vue-switcher__label span {
  216. padding-bottom: 7px;
  217. display: inline-block;
  218. }
  219. .vue-switcher-theme--default.vue-switcher-color--default div {
  220. background-color: #b7b7b7;
  221. }
  222. .vue-switcher-theme--default.vue-switcher-color--default div:after {
  223. background-color: #9d9d9d;
  224. }
  225. .vue-switcher-theme--default.vue-switcher-color--default.vue-switcher--unchecked
  226. div {
  227. background-color: #aaa;
  228. }
  229. .vue-switcher-theme--default.vue-switcher-color--default.vue-switcher--unchecked
  230. div:after {
  231. background-color: #c4c4c4;
  232. }
  233. .vue-switcher-theme--default.vue-switcher-color--blue div {
  234. background-color: #77b0c8;
  235. }
  236. .vue-switcher-theme--default.vue-switcher-color--blue div:after {
  237. background-color: #539bb9;
  238. }
  239. .vue-switcher-theme--default.vue-switcher-color--blue.vue-switcher--unchecked
  240. div {
  241. background-color: #c0dae5;
  242. }
  243. .vue-switcher-theme--default.vue-switcher-color--blue.vue-switcher--unchecked
  244. div:after {
  245. background-color: #77b0c8;
  246. }
  247. .vue-switcher-theme--default.vue-switcher-color--red div {
  248. background-color: #c87777;
  249. }
  250. .vue-switcher-theme--default.vue-switcher-color--red div:after {
  251. background-color: #b95353;
  252. }
  253. .vue-switcher-theme--default.vue-switcher-color--red.vue-switcher--unchecked
  254. div {
  255. background-color: #e5c0c0;
  256. }
  257. .vue-switcher-theme--default.vue-switcher-color--red.vue-switcher--unchecked
  258. div:after {
  259. background-color: #c87777;
  260. }
  261. .vue-switcher-theme--default.vue-switcher-color--yellow div {
  262. background-color: #c9c377;
  263. }
  264. .vue-switcher-theme--default.vue-switcher-color--yellow div:after {
  265. background-color: #bab353;
  266. }
  267. .vue-switcher-theme--default.vue-switcher-color--yellow.vue-switcher--unchecked
  268. div {
  269. background-color: #e6e3c0;
  270. }
  271. .vue-switcher-theme--default.vue-switcher-color--yellow.vue-switcher--unchecked
  272. div:after {
  273. background-color: #c9c377;
  274. }
  275. .vue-switcher-theme--default.vue-switcher-color--orange div {
  276. background-color: #c89577;
  277. }
  278. .vue-switcher-theme--default.vue-switcher-color--orange div:after {
  279. background-color: #b97953;
  280. }
  281. .vue-switcher-theme--default.vue-switcher-color--orange.vue-switcher--unchecked
  282. div {
  283. background-color: #e5cec0;
  284. }
  285. .vue-switcher-theme--default.vue-switcher-color--orange.vue-switcher--unchecked
  286. div:after {
  287. background-color: #c89577;
  288. }
  289. .vue-switcher-theme--default.vue-switcher-color--green div {
  290. background-color: #77c88d;
  291. }
  292. .vue-switcher-theme--default.vue-switcher-color--green div:after {
  293. background-color: #53b96e;
  294. }
  295. .vue-switcher-theme--default.vue-switcher-color--green.vue-switcher--unchecked
  296. div {
  297. background-color: #c0e5ca;
  298. }
  299. .vue-switcher-theme--default.vue-switcher-color--green.vue-switcher--unchecked
  300. div:after {
  301. background-color: #77c88d;
  302. }
  303. </style>
  304. <!--<style lang="scss">
  305. /**
  306. * Default
  307. */
  308. $color-default-default: #aaa;
  309. $color-default-green: #53b96e;
  310. $color-default-blue: #539bb9;
  311. $color-default-red: #b95353;
  312. $color-default-orange: #b97953;
  313. $color-default-yellow: #bab353;
  314. $switch-width: 100px;
  315. $switch-height: 26px;
  316. $theme-default-colors: (
  317. default : $color-default-default,
  318. blue : $color-default-blue,
  319. red : $color-default-red,
  320. yellow : $color-default-yellow,
  321. orange : $color-default-orange,
  322. green : $color-default-green
  323. );
  324. .vue-switcher {
  325. position: relative;
  326. display: inline-block;
  327. width: $switch-width;
  328. height: $switch-height;
  329. line-height: $switch-height;
  330. margin-bottom: 0px;
  331. top: 7px;
  332. &__label {
  333. position: absolute;
  334. left: $switch-width * 0.6;
  335. top: 0px;
  336. height: $switch-height;
  337. line-height: $switch-height;
  338. display: block;
  339. font-size: 10px;
  340. margin-bottom: 0px;
  341. }
  342. input {
  343. position: absolute;
  344. left: 0px;
  345. top: 0px;
  346. width: $switch-width * 0.6;
  347. height: $switch-height;
  348. line-height: $switch-height;
  349. opacity: 0;
  350. z-index: 1;
  351. cursor: pointer;
  352. margin: 0px !important;
  353. }
  354. div {
  355. position: absolute;
  356. left: 0px;
  357. top: ($switch-height - 10) * 0.5;
  358. width: $switch-width * 0.4;
  359. height: 10px;
  360. border-radius: 30px;
  361. display: -webkit-flex;
  362. display: -ms-flex;
  363. display: flex;
  364. align-items: center;
  365. justify-content: flex-start;
  366. cursor: pointer;
  367. &:after {
  368. position: absolute;
  369. top: (10 - 18) * 0.5;
  370. left: 100%;
  371. content: '';
  372. height: 18px;
  373. width: 18px;
  374. border-radius: 100px;
  375. display: block;
  376. transition: all ease .3s;
  377. margin-left: -17px;
  378. cursor: pointer;
  379. }
  380. }
  381. &--unchecked {
  382. div {
  383. justify-content: flex-end;
  384. &:after {
  385. left: 15px;
  386. }
  387. }
  388. }
  389. &--disabled {
  390. div {
  391. opacity: .3;
  392. }
  393. input {
  394. cursor: not-allowed;
  395. }
  396. }
  397. &--bold {
  398. div {
  399. top: ($switch-height - 26) * 0.5;
  400. height: $switch-height;
  401. width: 51px;
  402. &:after {
  403. margin-left: -22px;
  404. top: 4px;
  405. }
  406. }
  407. &--unchecked {
  408. div {
  409. &:after {
  410. left: 26px;
  411. }
  412. }
  413. }
  414. .vue-switcher__label {
  415. span {
  416. padding-bottom: 7px;
  417. display: inline-block;
  418. }
  419. }
  420. }
  421. &-theme--default {
  422. @each $colorName, $color in $theme-default-colors {
  423. &.vue-switcher-color--#{$colorName} {
  424. div {
  425. @if $colorName == 'default' {
  426. background-color: lighten($color, 5%);
  427. } @else {
  428. background-color: lighten($color, 10%);
  429. }
  430. &:after {
  431. @if $colorName == 'default' {
  432. background-color: darken($color, 5%);
  433. } @else {
  434. background-color: $color
  435. }
  436. }
  437. }
  438. &.vue-switcher--unchecked {
  439. div {
  440. @if $colorName == 'default' {
  441. background-color: $color;
  442. } @else {
  443. background-color: lighten($color, 30%);
  444. }
  445. &:after {
  446. background-color: lighten($color, 10%);
  447. }
  448. }
  449. }
  450. }
  451. }
  452. }
  453. }
  454. </style>-->