Switch组件

初始化Switch

新建lib/Switch.vue

<template>
  <div>switch</div>
</template>
<script lang="ts">
  export default {
  }
</script>

然后在我们的SwitchDemo.vue里引入我们的Switch组件来展示

<template>
  <div>
    <Switch/>
  </div>
</template>
<script lang="ts">
  import Switch from '../lib/Switch.vue'
  export default {
    name: 'Switch',
    components: { Switch }
  }
</script>

运行后我们发现如下的报错

报错原因:
我们的父组件里使用了和我们子组件名字一样的name

解决办法:
每个组件的名字都和自己的文件名保持一致

<template>
  <div>
    <Switch/>
  </div>
</template>
<script lang="ts">
  import Switch from '../lib/Switch.vue'
  export default {
    name: 'SwitchDemo',
    components: { Switch }
  }
</script>

Switch切换

<template>
  <button @click="toggle" :class="{checked}"><span></span></button>
</template>
<script lang="ts">
  import { ref } from 'vue'
  export default {
    setup() {
      const checked = ref(false)
      const toggle = () => {
        checked.value = !checked.value
      }
      return {checked, toggle}
    }
  }
</script>
<style lang="scss" scoped>
  $h: 22px;
  $h2: $h - 4px;
  button{
    height: $h;
    width: $h*2;
    border: none;
    background: grey;
    border-radius: $h/2;
    position: relative;
    cursor: pointer;
  }
  span{
    position: absolute;
    top: 2px;
    left: 2px;
    height: $h2;
    width: $h2;
    background:white;
    border-radius: $h2 / 2;
    transition: left .25s;
  }
  button.checked{
    background: blue;
  }
  button.checked > span {
    left: calc(100% - #{$h2} - 2px);
  }
  button:focus {
    outline: none;
  }
</style>

支持自定义初始状态

我们需要用户使用组件的时候可以自己设定一开始是开启的还是关闭的,所以我们需要绑定一个初始值value,当我们修改开关状态的时候我们传入的value也要跟着修改,所以需要在父组件监听一个input事件,拿到新的value值,子组件触发这个input事件把新的value值传出去

  • SwitchDemo.vue
<template>
  <div>
    <Switch :value="x" @input="x = $event"/>
  </div>
</template>
<script lang="ts">
  import Switch from '../lib/Switch.vue'
  import { ref } from 'vue'
  export default {
    name: 'SwitchDemo',
    setup() {
      const x = ref(true)
      return { x }
    },
    components: { Switch }
  }
</script>
  • Switch.vue
<template>
  <button @click="toggle" :class="{checked: value}"><span></span></button>
</template>
<script lang="ts">
  interface Prop {
    value: boolean;
  }
  import { ref } from 'vue'
  export default {
    props: {
      value: Boolean
    },
    setup(props: Prop, context: any) {
      const toggle = () => {
        context.emit('input', !props.value)
      }
      return {toggle}
    }
  }
</script>

这里和vue2的区别是我们的父组件传进来的属性,需要在子组件的setup里的第一个参数里获取,而它的第二个参数是一个上下文对象context,我们触发一个事件需要通过context.emit

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容