做一个动态效果的点赞
<script lang="tsx">
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const likeCount = ref(0);
const isLiked = ref(false);
const isShaking = ref(false);
const toggleLike = () => {
if (isLiked.value) {
likeCount.value--;
} else {
likeCount.value++;
}
isLiked.value = !isLiked.value;
// 触发晃动效果
isShaking.value = true;
setTimeout(() => {
isShaking.value = false;
}, 500); // 设置晃动时间为 500ms
};
return () => (
<div class="like-button" onClick={toggleLike}>
<span class={['like-icon', { liked: isLiked.value, shake: isShaking.value }]}>
❤
</span>
<span class="like-count">{likeCount.value}</span>
</div>
);
}
});
</script>
<style scoped>
:deep(.like-button) {
display: flex;
align-items: center;
cursor: pointer;
}
:deep(.like-icon) {
font-size: 24px;
color: grey;
transition: transform 0.3s ease, color 0.3s ease;
}
:deep(.like-icon.liked) {
color: red;
transform: scale(1.3);
}
:deep(.like-icon.shake) {
animation: shake 0.5s;
}
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
25% {
transform: translateX(-10px);
}
50% {
transform: translateX(10px);
}
75% {
transform: translateX(-10px);
}
}
:deep(.like-count) {
margin-left: 8px;
font-size: 16px;
}
</style>
需要注意的点:
模版编译时,里面的css由于受到scoped影响,需要:deep()穿透才可生效
这个例子中,用到了模版渲染data,样式、以及样式绑定;
下面总结一下:
如果tsx没生效,可能需要安装一个插件:
pnpm install @vitejs/plugin-vue-jsx
1.v-show 支持 <div v-show={true}></div>
setup() {
const flag = ref(false);
return () => (<div v-show={flag.value}>广东没下雪</div>)
}
2.v-if 不支持,需求实现可以使用三目运算符代替
setup() {
const flag = ref(false);
return () => (<>
<div>{flag.value ? <div>东北下雪了</div> : <div>广州大太阳</div>}</div>
</>)
}
3.v-for不支持 使用map函数代替
setup() {
const flag = ref(false);
const data = [
{city:'上海'},
{city:'北京'},
{city:'广州'},
{city:'深圳'}
];
return () => (<>
{data.map(v=>{
return <div>{v.city}</div>
})}
</>)
4.v-bind或:传参不支持,直接使用 属性={属性值}
setup() {
const flag = ref(false);
const data = [
{city:'上海'},
{city:'北京'},
{city:'广州'},
{city:'深圳'}
];
return () => (<>
{data.map(v=>{
return <div name={v.city}>{v.city}</div>
})}
</>)
}
5.v-model支持
setup(props:Props,{emit}) { // 通过emit派发事件
const v = ref<string>('');
return () => (<>
<input v-model={v.value} type='text'></input>
<div>{v.value}</div>
</>)
}