06-Vue:组件通信、Todo案例

1.组件通信

1.1父向子

1.分析谁是父组件 谁是子组件;
2.子组件中通过props 定义变量,直接使用变量;
3.父组件 中 自定义变量 传递值
在这里插入图片描述
注意:父向子可以传递任意类型的数据

props数据验证
1.props选项的值可以为数组类型也可以是对象类型;
2.props选项的对象类型可以对外部传递进来的参数进行数据验证;
3.比如说某个数据必须是数字类型,如果传入字符串,不会报错 会弹出警告

<template>
  <div>
    子组件
    <hr />
    {{ num }}----{{ s }}---{{ flag }}
    {{ obj.name }}
  </div>
</template>

<script>
export default {
  //   props: ["num", "s", "flag", "obj"],
  props: {
    // 必须是数字类型
    num: Number,
    //必须是数字或者字符串
    s: [String, Number],
    // 布尔类型,默认为true
    flag: {
      type: Boolean,
      default: true,
    },
    // 如果是对象或者数组,默认必须是一个函数返回
    obj: {
      type: Object,
      default: function () {
        return {};
      },
    },
  },
};
</script>

<style scoped>
</style>

单向数据流
在vue中需要遵循单向数据流原则:
1.父组件数据发生了改变,子组件会自动跟着变;
2.子组件不能直接修改父组件传递过来的props,props是只读的;
父组件传给子组件是一个对象,子组件修改对象的属性,是不会报错的,对象是引用类型

1.2子向父

从子组件把值传给父组件

语法:

  • 父组件:@自定义事件名=“父methods函数”
  • 子组件:this.$emit(‘自定义事件名’,传值)–执行父methods函数代码

在这里插入图片描述

1.3非父子

常用于跨组件通信;
两个组件关系非常的复杂,通过父子组件通信是非常麻烦的,可以使用通用的组件通信方案—事件总线(event-bus)
在这里插入图片描述
1.1:src下创建EventBus/index.js --定义事件总线bus对象
// 定义事件总线bus对象

import Vue from ‘vue’

// 导出空白vue对象

export default new Vue()
在这里插入图片描述

2.ToDo案例

结构样式
1:创建3个组件和里面的代码还有样式

2:APP.vue中引入三个组件
渲染认为列表
需求:把任务列表展示到页面TodoMain.vue中
需求:选中状态 设置相关的样式

步骤:
1.App.vue 中定义数组传入TodoMain.vue组件中;
2.v-for循环展示数据;
3.v-model绑定复选框选中状态;
4.根据选中状态 设置样式

<template>
  <div class="todo">
    <todo-head></todo-head>
    <todo-main :arr="list"></todo-main>
    <todo-foot></todo-foot>
  </div>
</template>

<script>
import TodoFoot from "./components/TodoFoot.vue";
import TodoHead from "./components/TodoHead.vue";
import TodoMain from "./components/TodoMain.vue";
export default {
  components: { TodoHead, TodoMain, TodoFoot },
  data() {
    return {
      list: [
        { id: 100, name: "吃饭", ischeck: false },
        { id: 101, name: "睡觉", ischeck: false },
        { id: 102, name: "打游戏", ischeck: false },
      ],
    };
  },
};
</script>

<style scoped>
.todo {
  width: 500px;
  height: 500px;
  border: 1px solid #333;
  margin: 200px auto;
}
</style>
<template>
  <div>
    <div class="main">
      <ul>
        <li v-for="item in arr" :key="item.id">
          <div class="left">
            <input type="checkbox" v-model="item.ischeck" />
            <span :class="{ underline: item.ischeck }">{{ item.name }}</span>
          </div>
          <button>删除</button>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  props: ["arr"],
};
</script>

<style scoped>
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 5px;
  height: 50px;
}
.underline {
  text-decoration-line: line-through;
}
</style>

添加任务
需求:输入任务回车,新增任务

1.TodoHead.vue 输入框 --键盘事件—回车;
2.子传父 把任务 —App.vue中 加入到数组中;
3.数组改变,所有用到数组的地方都会更新;
4.输入框为空,提示用户必须输入内容

//TodoHead.vue
<input type="text" v-model="name" @keyup.enter="addFn" />

  methods: {
    addFn() {
      // 非空判断
      if (this.name.trim().length === 0) {
        alert('任务内容不能为空')
        return
      }
      // 子传父
      this.$emit('create', this.name)

      this.name = ''
    },
  },
//App.vue
<todo-head @create="createFn"></todo-head>

methods: {
    createFn(name) {
      var id =
        this.list.length === 0 ? 100 : this.list[this.list.length - 1].id + 1
      this.list.push({
        id: id,
        name: name,
        ischeck: false,
      })
    },
  },

删除任务
.删除按钮–点击事件 传id;
子传父-把id传给App.vue 删除数组list里对应的对象
数组改变所有用到数组的地方都会更新

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值