父组件怎么发送数据

父组件给子组件传递数据,发送者就是父组件,那么怎么发送数据给子组件呢?
步骤
1、引入:在父组件中引入子组件
2、挂载:components中挂载
3、传值:通过键值对的形式书写在子组件身上(注意:传递js表达式(常量,变量,数字,
对象,数组),要加:冒号。不加的话,vue模板解析会认为是一个字符串)
<template>
  <div>
    <!-- 3、传递 -->
    <Son
      name="张三"
      :age="18"
      :hobby="['吃饭', '睡觉', '打豆豆']"
      :lover="{ name: '李四', age: 18 }"
      noProp="noProp"
    ></Son>
  </div>
</template>

<script>
// 1、引入
import Son from "./components/Son.vue";
export default {
  name: "App",
  // 2、挂载
  components: {
    Son,
  },
};
</script>

<style>
</style>

子组件怎么接收?

父组件已经传递值了,那么子组件怎么接收呢?
有两种接收方式:
1、数组的形式(简单接收)
2、对象的形式(复杂接收,可以设置类型校验,默认值,是否必传,以及自定义校验规则)

简单接收

<template>
  <div>
    <div>Son组件</div>
    <div>{{ name }}</div>
    <div>{{age}}</div>
    <div>{{hobby}}</div>
    <div>{{lover}}</div>
    <div>{{variable}}</div>
  </div>
</template>

<script>
export default {
  name: "web-son",
  // 简单接收
  props: ["name", "age", "hobby", "lover", "variable"],
};
</script>

<style scoped>
</style>

顺利接收
在这里插入图片描述

复杂接收

<template>
  <div>
    <div>Son组件</div>
    <div>{{ name }}</div>
    <div>{{ age }}</div>
    <div>{{ hobby }}</div>
    <div>{{ lover }}</div>
    <div>{{ variable }}</div>
  </div>
</template>

<script>
export default {
  name: "web-son",
  props: {
    name: String,
    age: Number,
    hobby: {
      // 允许传递多种数据类型
      type: [Array, Object],
    },
    lover: {
      type: Object,
    //   必须传值
      required: true,
    },
    variable: {
      type: String,
    //   父组件不传这个数据,那么这个值的默认值就为default的内容
      default: "我是默认值",
      //   自定义校验函数,返回值为true则校验通过,否则不通过
      validator: function(value){
        //   value为父组件传递的值
        // 常用的场景,封装组件库时,规定这个props值只能是哪些值
        return ["变量","我是默认值"].indexOf(value) != -1
      }
    },
    /* 说明:一般required和default不一块使用,因为没有啥
    意义,必传就一定用不上默认值 */
  },
};
</script>

<style scoped>
</style>

顺利接收
在这里插入图片描述

不满足校验规则的一些报错信息(常见于用开源ui组件库时)

数据类型不对

当类型为String的name,我传入一个数字12时,报错翻译过来就是无效的prop类型检验
失败,应该传入一个字符串,但是12是一个数字

在这里插入图片描述

必传未传

这个报错就比较容易理解了,丢失了一个必传的prop "lover"

在这里插入图片描述

自定义校验函数未通过

当我给variable传入一个"变量2",报错信息为,对prop值variable自定义校验函数失败

在这里插入图片描述

props接收的值存在哪?

为什么我们按照这种方式传值之后,可以直接在组件中通过this.xxx访问到呢?
我们打印一下当前的组件VueComponent对象查看一下
mounted(){
    console.log(this);
  }

在这里插入图片描述

在这里插入图片描述

可以发现,vue直接从_props中将这些属性添加到了当前的组件实例身上,所以我们才能
通过this.xxx访问得到。

父组件传了,子组件props未声明接收,值去哪了?

认真阅读的读者发现了,我在父组件中传的noProp字符串,怎么没在子组件中接收呢?
它们去哪了呢?其实vue对于这种情况也做了处理。vue将变量(传了但是props未接收的),
就会被放在vue组件实例.$attrs身上,它和$listeners属性牵扯到vue2另外一种组件通信,
后续将在专栏中补充,这两个属性在封装ui组件库,在进行多代关系的组件通信时十分有用

在这里插入图片描述

为什么不建议子组件修改props?

从之前打印的实例对象发现,实例对象身上并没有与之对应get和set方法。(_props对象
上有)并且如果我们直接通过this.xxx = ?修改props的值,vue会报错。eslint代码检验
也会报错。如果通过this._props.xxx = ?修改props的值,可以修改成功,但是根据vue的数据流,子组件虽然更改了值,由于数据是从父组件来的,父组件的值并没有被修改,因此子组件重新渲染的时候,值依然是父组件中的值。并且如果你这么做,谷歌浏览器控制台也会弹出warn

在这里插入图片描述

想要修改props的值怎么办?

从之前控制台的warn可以发现,vue官方给予我们提示了,你可以使用data或者computed
来复制一份props中的值,然后再进行修改以及后续业务逻辑的处理。(补充:根据vue源
码得知,props的加载顺序在data和computed之前,因此在data或computed中访问props
中的值不会是undefined)
data() {
    return {
      sonName: this.name + "son",
    };
  },
computed: {
  sonName2() {
    return this.name + "son";
  },
},

.sync修饰符

当给子组件传递一个值时,使用.sync修饰,会给子组件的消息发布与订阅的消息队列添加
一个update:变量名。代码演示。

App.vue

<template>
  <div>
    <!-- 3、传递 -->
    <Son
      ...
      :page.sync="page"
    ></Son>
    <div>father-page:{{page}}</div>
  </div>
</template>

<script>
// 1、引入
import Son from "./components/Son.vue";
export default {
  name: "App",
  data() {
    return {
      ...
      page: 1
    };
  },
  // 2、挂载
  components: {
    Son,
  },
};
</script>

<style>
</style>

在这里插入图片描述
Son.vue

mounted() {
    ...
    this.$emit("update:page",2);
  },

在这里插入图片描述

完整代码

App.vue父组件

<template>
  <div>
    <!-- 3、传递 -->
    <Son
      name="张三"
      :age="18"
      :hobby="['吃饭', '睡觉', '打豆豆']"
      :lover="{ name: '李四', age: 18 }"
      :variable="variable"
      @clg="
        {
          () => {
            console.log();
          };
        }
      "
      noProp="noProp"
      :page.sync="page"
    ></Son>
    <div>father-page:{{page}}</div>
  </div>
</template>

<script>
// 1、引入
import Son from "./components/Son.vue";
export default {
  name: "App",
  data() {
    return {
      variable: "变量",
      page: 1
    };
  },
  // 2、挂载
  components: {
    Son,
  },
};
</script>

<style>
</style>


Son.vue子组件

<template>
  <div>
    <div>Son组件</div>
    <div>{{ name }}</div>
    <div>{{ sonName }}</div>
    <div>{{ sonName2 }}</div>
    <div>{{ age }}</div>
    <div>{{ hobby }}</div>
    <div>{{ lover }}</div>
    <div>{{ variable }}</div>
  </div>
</template>

<script>
export default {
  name: "web-son",
  data() {
    return {
      sonName: this.name + "son",
    };
  },
  computed: {
    sonName2() {
      return this.name + "son";
    },
  },
  props: {
    name: String,
    age: Number,
    hobby: {
      // 允许传递多种数据类型
      type: [Array, Object],
    },
    lover: {
      type: Object,
      //   必须传值
      required: true,
    },
    variable: {
      type: String,
      //   父组件不传这个数据,那么这个值的默认值就为default的内容
      default: "我是默认值",
      //   自定义校验函数,返回值为true则校验通过,否则不通过
      validator: function (value) {
        //   value为父组件传递的值
        // 常用的场景,封装组件库时,规定这个props值只能是哪些值
        return ["变量", "我是默认值"].indexOf(value) != -1;
      },
    },
    /* 说明:一般required和default不一块使用,因为没有啥
    意义,必传就一定用不上默认值 */
  },
  mounted() {
    console.log(this);
    // this.name="zhangsan";
    // this._props.name = "zhangsan";
    this.$emit("update:page",2);
  },
};
</script>

<style scoped>
</style>
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐