Vue动态样式绑定不是计算属性的流体



我有一个NuxtJS应用程序,我想创建一个自定义的<Radio>组件。

我动态绑定一个CSS类,这样我就可以改变我的单选按钮的font-weight,一旦它被选中。

初始加载后,在第一次点击按钮时,可以看到文本的大小略有变化,有点"缩小/增大"的感觉。但之后就不会再发生了,之后的转变更加流畅。这可能是由于计算属性的工作方式吗?

我做了一个视频,让它更清楚。

灵感来自Stephanie Eckles

<template>
<div :class="containerClasses">
<label :class="radioClasses">
<span class="radio__wrapper">
<input
:id="radioId"
class="radio__input"
type="radio"
:checked="shouldBeChecked"
:value="radioValue"
@change="updateRadio"
/>
<span class="radio__control"></span>
</span>
<span :for="radioId" class="radio__label">{{ radioLabel }}</span>
</label>
</div>
</template>
<script lang="ts">
import { defineComponent, toRefs, computed } from '@nuxtjs/composition-api';
export default defineComponent({
name: 'Radio',
model: {
prop: 'modelValue',
event: 'change',
},
props: {
id: {
type: String,
required: true,
},
label: {
type: String,
required: true,
},
value: {
type: String,
default: undefined,
},
modelValue: {
type: String,
default: '',
},
},
setup(props, { emit }) {
const { label, id, value, modelValue } = toRefs(props);
const updateRadio = () => {
emit('change', value.value);
};
const shouldBeChecked = computed(() => modelValue.value === value.value);
const containerClasses = computed(() => ({
container: true,
'container--active': shouldBeChecked.value,
}));
const radioClasses = computed(() => ({
radio: true,
'radio--active': shouldBeChecked.value,
}));
return {
radioLabel: label,
radioId: id,
radioValue: value,
shouldBeChecked,
updateRadio,
containerClasses,
radioClasses,
};
},
});
</script>
<style lang="scss" scoped>
.container {
--border-width: 1px;
position: relative;
border: solid var(--border-width) transparent;
border-radius: 16px;
background: $color-white;
background-clip: padding-box;
cursor: pointer;
&::before {
content: '';
position: absolute;
z-index: -1;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: calc(var(--border-width) * -1);
border-radius: inherit;
background: $color-dark-grey;
}
&--active {
&::before {
background: $gradient-blue-purple;
}
}
}
.radio {
display: grid;
grid-gap: 1.6rem;
grid-template-columns: min-content auto;
padding: 2rem $spacing-s;
font-size: $font-size-s;
&__wrapper {
display: flex;
}
&--active {
font-weight: $font-weight-medium;
}
&__input {
width: 0;
height: 0;
opacity: 0;
+ .radio__control::before {
content: '';
width: 1rem;
height: 1rem;
transform: scale(0);
transition: 180ms transform ease-in-out;
border-radius: 50%;
box-shadow: inset 0.5em 0.5em currentColor;
}
&:checked + .radio__control::before {
transform: scale(1);
}
}
&__control {
display: grid;
width: 2.4rem;
height: 2.4rem;
transform: translateY(-0.1em);
border: 1px solid currentColor;
place-items: center;
border-radius: 50%;
}
&__label {
display: flex;
align-items: center;
line-height: 1;
}
}
</style>

这让我找到了正确的方向,并通过样式调整使其看起来正确。

// Before
.radio {
display: grid;
grid-gap: 1.6rem;
}
// After
.radio {
display: flex;
gap: 1.6rem;
}

相关内容

  • 没有找到相关文章