vue 组件化综合案例demo
程序员文章站
2022-07-04 19:26:47
...
1. 技术栈
vue 组件化编码
父子组件数据交互 $parent
watch 深度监视
本地缓存 localstorage
js高阶函数灵活使用
按键修饰符使用
2. 编码
- app.vue
<template>
<div class="todo-container">
<Header></Header>
<Todos :todos="todos"></Todos>
<Footer></Footer>
</div>
</template>
<script>
import Header from "./components/header/Header";
import Todos from "./components/todos/Todos";
import Footer from "./components/footer/Footer";
export default {
data () {
return {
todos: JSON.parse(localStorage.getItem('todo'))
}
},
// 深度监视 todos数据变化
watch : {
todos: {
deep: true,
handler (value) {
localStorage.setItem('todo', JSON.stringify(value))
}
}
},
components: {
Header, Todos, Footer
}
}
</script>
<style lang="less">
.todo-container{
width: 500px;
border: 1px solid #ccc;
margin: auto;
user-select: none;
}
</style>
- header.vue
<template>
<div class="header">
<input type="text" placeholder="请添加任务" @keyup.enter="addTodo" v-model="currentTodo">
</div>
</template>
<script>
export default {
name: "Header",
data () {
return {
currentTodo: ''
}
},
methods: {
addTodo () {
this.$parent.todos.unshift({name: this.currentTodo, complate: false});
this.currentTodo = '';
}
}
}
</script>
<style scoped lang="less">
.header{
width: 100%;
height: 50px;
border-bottom: 1px solid #ccc;
input{
width: 100%;
height: 100%;
outline: none;
border: 1px solid #ccc;
padding: 20px;
box-sizing: border-box;
}
}
</style>
- todos
<template>
<div class="content">
<div class="item" v-for="(item, index) in todos" :key="index">
<input type="checkbox" :checked="item.complate" @click="item.complate = !item.complate">
<span>{{ item.name }}</span>
<button @click.prevent="deleteTodo(index)">删除</button>
</div>
</div>
</template>
<script>
export default {
name: "Todos",
props: ['todos'],
data () {
return {
isShow: false
}
},
methods: {
deleteTodo (index) {
this.$parent.todos.splice(index, 1)
}
}
}
</script>
<style scoped lang="less">
.content{
width: 100%;
.item{
width: 100%;
line-height: 40px;
padding-left: 20px;
border-bottom: 1px solid #ccc;
position: relative;
input{
margin-right: 10px;
}
button{
line-height: 20px;
font-size: 14px;
outline: none;
border: 1px solid grey;
background-color: red;
color: white;
position: absolute;
right: 10px;
margin-top: 10px;
}
}
}
</style>
- footer
<template>
<div class="bottom">
<div class="selectAll">
<input type="checkbox" id="select" @click="selectAll"> <label for="select"> 全选 / 全不选 </label>
</div>
<div class="complate">
<span>已完成{{ complated }} / 总任务{{ $parent.todos.length }}</span>
</div>
<button @click="deleteComplated">清空已完成</button>
</div>
</template>
<script>
export default {
name: "Footer",
data () {
return {
isAllSelect : false
}
},
methods: {
selectAll () {
this.isAllSelect = this.$parent.todos.every(todo=>todo.complate === true);
if (this.isAllSelect) {
this.$parent.todos.forEach(todo=>{
todo.complate = false
});
this.isAllSelect = false
} else {
this.$parent.todos.forEach(todo=>{
todo.complate = true
});
this.isAllSelect = true
}
},
deleteComplated () {
this.$parent.todos = this.$parent.todos.filter(todo => {
return todo.complate === false
})
}
},
computed : {
complated () {
return this.$parent.todos.reduce((total, todo) => {
return total + todo.complate
}, 0)
}
}
}
</script>
<style scoped lang="less">
.bottom{
width: 100%;
height: 50px;
/*margin-top: 20px;*/
display: flex;
align-items: center;
justify-content: space-between;
.selectAll{
margin-left: 10px;
}
.complate{}
button{
background-color: red;
color: white;
margin-right: 20px;
outline: none;
border: 1px solid red;
}
}
</style>
3. 效果图
上一篇: 从Centos7升级到Centos8的教程(图文详解)
下一篇: vue 后端管理框架模板
推荐阅读
-
Vue使用echarts可视化组件的方法
-
案例精选 | 蘑菇街、滴滴、淘宝、微信的组件化架构解析 组件化架构架构
-
案例精选 | 蘑菇街、滴滴、淘宝、微信的组件化架构解析 组件化架构架构
-
vue祖孙组件之间的数据传递案例
-
前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例
-
Vue学习笔记进阶篇之函数化组件解析
-
Vue form表单动态添加组件实战案例
-
vue 使用 async 和 await 实现异步 axios 同步化(实战案例:数据异步校验通过后,再执行保存)
-
vue组件化中slot的基本使用方法
-
vue组件化中slot的基本使用方法