vue学习笔记 十九、实例完整代码

系列导航

vue学习笔记 一、环境搭建

vue学习笔记 二、环境搭建+项目创建

vue学习笔记 三、文件和目录结构

vue学习笔记 四、定义组件(组件基本结构)

vue学习笔记 五、创建子组件实例

vue学习笔记 六、ref定义单个数据

vue学习笔记 七、方法的定义和使用

vue学习笔记 八、toRef的使用

vue学习笔记 九、父子组件实例-基本结构

vue学习笔记 十、状态管理基础结构

vue学习笔记 十一、计算属性介绍

vue学习笔记 十二、通过计算属性获取定义的状态数据

vue学习笔记 十三、路由介绍

vue学习笔记 十四、页面跳转

vue学习笔记 十五、组件挂载过程及query方式带参数的页面跳转

vue学习笔记 十六、params方式带参数的页面跳转

vue学习笔记 十七、父子组件 ---> 子组件传值

vue学习笔记 十八、父子组件相互传递参数

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!
posted @ 2021-10-14 19:18  万笑佛  阅读(463)  评论(0编辑  收藏  举报