初始化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>
运行后我们发现如下的报错
![](https://img.haomeiwen.com/i14361446/07519a6dd177e29f.png)
报错原因:
我们的父组件里使用了和我们子组件名字一样的name
![](https://img.haomeiwen.com/i14361446/c1a7b46dd452536d.png)
解决办法:
每个组件的名字都和自己的文件名保持一致
<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
网友评论