vue学习笔记 十九、实例完整代码
|
系列导航 | ||
|---|---|---|
基础知识讲了不少,今天把之前所学的所有内容整合起来实现一个例子完善 vue学习笔记 九、父子组件实例-基本结构 中的功能,仔细看代码会有不小的收获。
一、 效果

父组件:Home 由三个子组件组成分别是:navHeader、navMain、navFooter
要完成的功能说明:
navHeader组件:输入新的任务,点击回车如果新的任务navMain中没有则添加到navMain中。
navMain组件:展示任务,点击“删除按钮”则删除当前任务,多选框可以多选任务。
navFooter组件:记录任务完成的数量(多选框选中为完成)、总数,以及点击“清除已完成”按钮删除navHeader中的已完成任务。
二、 项目结构截图

三、代码:
router--index.js
import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
//路由的配置属组
//paht:路由路劲 必须以/开头 必填
//component:对应的路由组件 必填
//name:路由的名字
const routes = [
{
path: '/',
name: 'Home',
//按需引入
//如果没有访问/about 就不会加载这个组件 节约性能
component: () => import( '../views/Home.vue')
},
{
path: '/about',
name: 'About',
//按需引入
//如果没有访问/about 就不会加载这个组件 节约性能
component: () => import( '../views/About.vue')
}
]
//创建路由对象
const router = createRouter({
//createWebHashHistory hash模式路径前面会多一个#号
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
store--index.js
import { createStore } from 'vuex'
export default createStore({
//定义所需要的状态
state: {
list:[
{
title:'吃饭',
complete:false
},{
title:'睡觉',
complete:false
},{
title:'敲代码',
complete:true
},
]
},
//同步修改state 都是方法
//第一个参数state,第二个参数是需要修改的值
mutations: {
//添加任务
addTodo(state,payload){
state.list.push(payload)
},
//删除任务 splice(下标,个数)
delTodo(state,payload){
state.list.splice(payload,1)
},
//清除已完成
clear(state,payload){
state.list = payload
}
},
//异步提交mutations
//第一个参数是store 第二个参数是修改的值
actions: {
},
//模块化的
modules: {
}
})
Home.vue
<template>
<div class="item">
<nav-header @add ='add'></nav-header>
<nav-main :list='list' @del='del'></nav-main>
<nav-footer :list='list' @clear='clear'></nav-footer>
</div>
</template>
<script>
//编写js内容
import NavHeader from '@/components/navHeader/NavHeader.vue'
import NavMain from '@/components/navMain/NavMain.vue'
import NavFooter from '@/components/navFooter/NavFooter.vue'
import {defineComponent,ref,computed} from 'vue'
import{useStore} from 'vuex'
export default defineComponent({
name:'Home',
components:{
NavHeader,
NavMain,
NavFooter
},
setup(){
let store = useStore()
let list = computed(()=>{
return store.state.list
})
let value = ref('')
let add =(val)=>{
value.value = val
//设置flag 判断输入的信息是否已经存在
let flag = true
list.value.map(item =>{
if(item.title===value.value){
//有重复任务
flag = false;
alert('任务已经存在')
}
})
if(flag){
//调用mutation
store.commit('addTodo',{
title:value.value,
complete:false
})
}
}
//删除任务
let del =(val)=>{
console.log(val)
store.commit('delTodo',val)
}
let clear =(val)=>{
store.commit('clear',val)
}
return {
add,
value,
list,
del,
clear
}
}
})
</script>
<style scoped lang="scss">
.item{
text-align:left;
}
</style>
NavHeader.vue
<template>
<div >
<input
placeholder="请输入任务名称"
v-model="value"
@keydown.enter="enter"
/>
</div>
</template>
<script>
import {defineComponent,ref} from 'vue'
export default defineComponent({
name:'navHeader',
setup(props,ctx){
let value=ref('')
//按回车确认
let enter = () => {
ctx.emit('add',value.value)
//console.log(value.value)
//清空输入框
value.value=''
}
return{
value,
enter
}
}
})
</script>
<style scoped lang="scss">
input{
margin-bottom: 10px;
}
</style>
NavMain.vue
<template>
<div v-for="(item,index) in list" :key ="index">
<div class="item">
<input type="checkbox" v-model="item.complete"/>
{{item.title}}
<button class="del" @click="del(item,index)">删除</button>
</div>
</div>
</template>
<script>
import {defineComponent,ref} from 'vue'
export default defineComponent({
name:'navMain',
props:{
list:{
type:Array,
required:true
}
},
//放分发事件的属性名字 没有这句浏览器控制台有报错
emits:['del'],
setup(props,ctx){
//删除任务
let del =(item,index)=>{
ctx.emit('del',index)
console.log(item)
console.log(index)
}
return{
del
}
}
})
</script>
<style scoped lang="scss">
.item{
height: 35px;
line-height: 35px;
position: relative;
width: 260px;
cursor: pointer;
button{
position: absolute;
right: 20px;
top: 6px;
display: none;
z-index: 99;
}
&:hover{
background: #ddd;
button{
display: block;
}
}
}
</style>
NavFooter.vue
<template>
<div >
<div>已完成{{isComplete}} /全部{{list.length}}</div>
<div v-if="isComplete >0" class="btn">
<button @click="clear">清除已完成</button>
</div>
</div>
</template>
<script>
import {defineComponent,ref,computed} from 'vue'
export default defineComponent({
name:'navFooter',
props:{
list:{
type:Array,
required:true
}
},
setup(props,ctx){
let isComplete = computed(()=>{
//过滤已完成
let arr = props.list.filter(item =>{
return item.complete
})
return arr.length
})
let clear = ()=>{
//过滤未完成的
let arr = props.list.filter(item =>{
return item.complete ===false
})
ctx.emit('clear',arr)
console.log('clear')
}
return{
isComplete,
clear
}
}
})
</script>
<style scoped lang="scss">
.btn{
margin-left: 10px;
}
</style>
资源丰富的的网盘资源:网盘资源大全! 推荐一个适合零基础学习SQL的网站:不用安装数据库,在线轻松学习SQL!
浙公网安备 33010602011771号