【Vue】Vue中【爷组件】与【子组件】通过【父组件】参数相互调用方法(props方式,图文+代码示例)_ico【Vue】Vue中【爷组件】与【子组件】通过【父组件】参数相互调用方法(props方式,图文+代码示例)_ico_02

 1、MyHeader.vue(顶部Vue,子组件)

【Vue】Vue中【爷组件】与【子组件】通过【父组件】参数相互调用方法(props方式,图文+代码示例)_javascript_03

<template>
<div>
<input type="text" v-model="m_task" />
<button @click="m_add">添加</button>
</div>
</template>

<script>

// import {nanoid} from 'nanoid'

export default {
name: "MyHeader",
data() {
return {
m_task: "",
};
},
methods: {
m_add() {

const m_id=this.numberAll+1;
const todoObj={id:m_id.toString(),title:this.m_task,done:"0"};
this.addTodo(todoObj);
},
},
props:["addTodo","numberAll"]
};
</script>

<style scoped>
body {
padding: 0;
margin: 0;
}
div {
height: 50px;
width: 97%;
display: flex;
flex-direction: row;
border: 1px rgb(251, 190, 190) solid;
}
input {
width: 0px;
flex-grow: 6;
height: 25px;
position: relative;
top: 10px;
margin-right: 2%;
}
button {
width: 0px;
flex-grow: 1.5;
height: 30px;
margin-top: 10px;
/* margin-left: 20px; */
}
</style>

 2、MyItem.vue(check单行,孙组件)

【Vue】Vue中【爷组件】与【子组件】通过【父组件】参数相互调用方法(props方式,图文+代码示例)_前端_04

<template>
<div class="row">
<span>
<input
type="checkbox"
:checked="todoObj.done==1"
@click="m_click(todoObj.id)"
/>
{{ todoObj.title }}
</span>
<span>
<button @click="delete_click(todoObj.id)">delete</button>
</span>
</div>
</template>

<script>
export default {
name: "MyItem",
data() {
return {};
},
props: ["todoObj", "changChecked", "deleteChecked"],
methods: {
m_click(m_id) {
this.changChecked(m_id);
},
delete_click(m_id) {
this.deleteChecked(m_id);
},
},
};
</script>

<style scoped>
.row {
width: 90%;
height: 35px;
border-bottom: 1px rgb(237, 235, 235) solid;
/* background-color: antiquewhite; */
margin-bottom: 5px;
display: flex;
flex-direction: row;
}

div span:nth-child(1) {
flex-grow: 2;
}

div span:nth-child(2) {
flex-grow: 8;
text-align: right;
}
.row {
height: 40px;
background-color: antiquewhite;
}
</style>

3、MyList.vue(选择项列表,父组件)

【Vue】Vue中【爷组件】与【子组件】通过【父组件】参数相互调用方法(props方式,图文+代码示例)_前端_05

<template>
<div class="m_list">
<MyItem v-for="todoObj in todos" :key="todoObj.id" :todoObj="todoObj" :changChecked="changChecked" :deleteChecked="deleteChecked"> </MyItem>
</div>
</template>

<script>

import MyItem from "@/components/MyItem";

export default {
name: "MyList",
components: {
MyItem,
},
props: ["todos", "changChecked", "deleteChecked"],
};
</script>

<style scoped>
.m_list {
margin-top: 10px;
padding-left: 20px;
line-height: 35px;
overflow: hidden;
width: 91.5%;
border: 1px rgb(253, 211, 211) solid;
}
</style>

4、App.vue(主组件)

<template>
<div id="myapp">
<MyHeader :addTodo="addTodo" :numberAll="numberAll"> </MyHeader>

<Mylist
:todos="todos"
:changChecked="changChecked"
:deleteChecked="deleteChecked"
></Mylist>
<MyFooter
:selectAll="selectAll"
:numberAll="numberAll"
:m_All="m_All"
:delete_All="delete_All"
></MyFooter>
</div>
</template>

<script>
// 引入组件
import MyFooter from "@/components/MyFooter.vue";
import MyHeader from "@/components/MyHeader.vue";
import Mylist from "@/components/MyList.vue";

// 注册组件
export default {
name: "App",
components: {
MyFooter,
MyHeader,
Mylist,
},
data() {
return {
todos: [
{ id: "001", title: "抽烟", done: "1" },
{ id: "002", title: "喝酒", done: "0" },
{ id: "003", title: "烫头", done: "1" },
],
selectAll: 2,
numberAll: 3,
// del_list: [],
};
},
methods: {
addTodo(todoObj) {
// --------- 可以往数组里边放了
this.todos.unshift(todoObj);

// --------- 更新总数和被选条数
this.numberAll = this.numberAll + 1;
},
// 点击MyItem组件对勾后的事件
changChecked(checkId) {
this.todos.forEach((item) => {
if (item.id == checkId) {
if (item.done == "1") {
item.done = "0";
this.selectAll = this.selectAll - 1;
} else {
item.done = "1";
this.selectAll = this.selectAll + 1;
}
}
});
},

// 点击MyItem组件对勾后的事件
deleteChecked(checkId) {
this.todos.forEach((item, index) => {
if (item.id == checkId) {
this.numberAll = this.numberAll - 1; // 更新总数
// 更新已选总数
if (item.done == 1) {
this.selectAll = this.selectAll - 1;
}
this.todos.splice(index, 1);
}
});
},

// 点击MyFooter.vue组件【全选】的事件
m_All() {
this.todos.forEach((item) => {
item.done = "1";
});
this.selectAll = this.numberAll;
},
// 点击MyFooter.vue组件【全选】的事件
delete_All() {
const del_list=[];

this.todos.forEach((item, index) => {
if (item.done == "1") {
del_list.unshift(index);
}
});
del_list.forEach((item) => {
this.todos.splice(item, 1);
this.selectAll = this.selectAll - 1;
this.numberAll = this.numberAll - 1;
});
},
},
};
</script>

<style scoped>
#myapp {
border: 1px rgb(134, 0, 0) dashed;
/* height: 400px; */
padding-top: 20px;
padding-left: 10px;
/* background-color: aqua; */
}
</style>

4、index.html

<!DOCTYPE html>
<html lang="">

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<style>

</style>

<body>

<div>
<h5>===== 组件嵌套 =====</h5>
</div>


<div id="app">


</div>
</body>

</html>