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

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

<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单行,孙组件)

<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(选择项列表,父组件)

<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>

猜你喜欢

转载自blog.csdn.net/dxnn520/article/details/124568296