持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
前言
这一节我们对底部做一下组件封装
底部
数量显示
- 这个组件主要做数据的过滤显示
- Vue 3.0 中移除了过滤器,不再支持,我们可以使用函数或者计算属性来代替。
- Count.vue
<template>
<span class="todo-count"
>进行中<strong>{{ remaining }}</strong
>{{ pluralize(remaining) }} left
</span>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
props: {
remaining: Number
},
setup() {
const pluralize = (count) => {
return count <= 1 ? 'item' : 'items';
};
return {
pluralize
};
}
});
</script>
操作组件
- 这里的封装主要是更新
visibility
值到父组件就可以了。 - Filter.vue
<template>
<ul class="filters">
<li><a href="#/all" :class="{ selected: visibility === 'all' }">显示所有</a></li>
<li><a href="#/active" :class="{ selected: visibility === 'active' }">进行中</a></li>
<li><a href="#/completed" :class="{ selected: visibility === 'completed' }">已完成</a></li>
</ul>
</template>
<script>
import { computed, defineComponent, onMounted, onUnmounted } from 'vue';
import { filters } from '@/utils/index';
export default defineComponent({
props: {
visibility: String
},
emits: ['update:visibility'],
setup(props, { emit }) {
const visibilityValue = computed({
get: () => props.visibility,
set: (v) => {
emit('update:visibility', v);
}
});
onMounted(() => {
window.addEventListener('hashchange', onHashChange);
onHashChange();
});
onUnmounted(() => {
window.removeEventListener('hashchange', onHashChange);
});
const onHashChange = () => {
const hash = window.location.hash.replace(/#\/?/, '');
if (filters[hash]) {
visibilityValue.value = hash;
} else {
visibilityValue.value = 'all';
window.location.hash = '';
}
};
return {};
}
});
</script>
清空按钮
- 这里的封装主要是更新
todos
的值到父组件 - Completed.vue
<template>
<button v-show="todos.length > remaining" @click="removeCompleted" class="clear-completed">
清除已完成
</button>
</template>
<script>
import { defineComponent, toRefs, computed } from 'vue';
import { filters } from '@/utils/index';
export default defineComponent({
props: {
todos: Array,
remaining: Number
},
emits: ['update:todos'],
setup(props, { emit }) {
const { todos } = toRefs(props);
const todosValue = computed({
get: () => todos.value,
set: (v) => {
emit('update:todos', v);
}
});
const removeCompleted = () => {
todosValue.value = filters.active(todos.value);
};
return {
removeCompleted
};
}
});
</script>
总结
组件的拆分做完了,我们可以做一下对比
- 封装之前我们把所有样式、逻辑放到一个文件中,杂而且乱,如果想修改某部分功能需要上下翻看很多行代码。
- 封装之后有没有感觉整体清爽了很多,需要修改哪部分逻辑,我们去对应的组件修改就可以了,不会被太多无关代码影响到。
那么下一节,我们来做下逻辑上的封装。
项目代码在GitHub,可以查阅