前端小白不迷路 - 今天来带你深入了解vue中的难懂概念 -- 子传父

232 阅读1分钟

这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战

前言:

大家好啊,又见面了,我是loncon,一个前端路上不断探索的小白,让我们开始今天的主题:深入了解vue中的难懂概念 -- 子传父.

vue中有父子传值这一概念,即包含父传子,还包括子传父,上篇我的文章中提到了父传子,这次一个案例带你了解比较难懂的子传父。

首先,我们根据效果图来分析这个案例实现的主要功能:

image.png

我们可以根据这幅图了解到,左边是子组件,右边是父组件,子组件中输入内容,转而父组件中同步显示子组件的内容,父组件使用子组件的内容,这个就是实现了子传父这个概念。

子传父的原理是事件传值,根据这一原理现在开始我们的代码梳理:

1.定义子组件及内容,子组件中要定义组件标签名,因为要传给父组件多个值,所以用对象的方式将数据包裹起来。

2.给最后一个表单注册键盘回车事件,触发绑定的事件,也就是这个按键按下之后,开启了子传父一系列的操作。

3.v-model,作用是接收表单的值,进行双向数据绑定。

4.vue中的this.$emit('事件名',参数……)方法,这个是子传父的关键,子组件通过这里定义的事件名,绑定到组件标签上。

5.父组件根据这个事件名的属性值,然后在自己的实例中,定义属性值为事件名的函数,在函数里进行数据的传递。(十分关键)

<div id="app">
      <modal @fclick="ffn"> </modal>          
//第三步:子组件标签自定义事件fclick,ffn是父组件的要在自己实例中定义的函数名
      <div class="right">
        <h2>父组件</h2>
        <p>1.从子组件传来的  ---  {{title}}</p>
        <p>2.从子组件传来的  ---  {{one}}</p>
      </div>
</div>
 
 
 
Vue.component('modal', {
        template: `
          <div class="modal">
            <div>
            <h2>子组件</h2>
              1.---<input type="text" v-model='list.first'><br/>
              2.---<input type="text" v-model='list.second' @keyup.enter='sure'><br/>
              //第一步:键盘回车触发事件,开启一系列的传值
            </div>
          </div>
        `,
        data() {
          return {
            list: {
              first: '',
              second: '',
            },
          };
         },
        methods: {
          sure() {
            if (
              !this.list.first |
              !this.list.second 
            )
              return;
            this.$emit('fclick', this.list);
            //第二步:子组件自定义函数名,将收集到的表单数据写在this.$emit里面
          },
        },
      });
 
  const vm = new Vue({
        el: '#app',
        data: {
          title: '',
          one: '',
        },
        methods: {
          ffn(n) {
//最后一步:父子件根据子组件标签里的ffn,在自己内部定义ffn这一函数,用来数据的接收
            console.log(n);
            this.title = n.first;
            this.one = n.second;
          },
        },
      });

完整代码(加样式)献上,小伙伴们有疑问还请留言沟通哦!!

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      .modal {
        width: 300px;
        padding: 50px;
        background-color: rgb(93, 165, 194);
        border-radius: 30px;
        margin: 10px;
        float: left;
      }
      input {
        height: 20px;
        margin: 12px 0 12px 12px;
      }
      body {
        padding: 0 200px;
        background-color: #ccc;
      }
      .right {
        float: right;
        width: 300px;
        padding: 80px;
        background-color: #fff;
        border: 4px solid #ea797f;
        border-radius: 30px;
        margin: 10px;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <modal @fclick="ffn"> </modal>
      <div class="right">
        <h2>父组件</h2>
        <p>1.从子组件传来的  ---  {{title}}</p>
        <p>2.从子组件传来的  ---  {{one}}</p>
      </div>
    </div>
 
    <script src="./vue.js"></script>
    <script>
      Vue.component('modal', {
        template: `
          <div class="modal">
            <div>
            <h2>子组件</h2>
              1.---<input type="text" v-model='list.first'><br/>
              2.---<input type="text" v-model='list.second' @keyup.enter='sure'><br/>
            </div>
          </div>
        `,
        data() {
          return {
            list: {
              first: '',
              second: '',
            },
          };
        },
        methods: {
          sure() {
            if (
              !this.list.first |
              !this.list.second 
            )
              return;
            this.$emit('fclick', this.list);
          },
        },
      });
 
      const vm = new Vue({
        el: '#app',
        data: {
          title: '',
          one: '',
        },
        methods: {
          ffn(n) {
            console.log(n);
            this.title = n.first;
            this.one = n.second;
          },
        },
      });
    </script>
  </body>
</html>