应用系统定制开发详细讲解vue2组件通信(一)——父传子props

文章结构

应用系统定制开发父组件怎么发送数据

应用系统定制开发父组件给子组件传递数据,应用系统定制开发发送者就是父组件,应用系统定制开发那么怎么发送数据给子组件呢?步骤1、引入:应用系统定制开发在父组件中引入子组件2、挂载:components中挂载3、传值:应用系统定制开发通过键值对的形式书写应用系统定制开发在子组件身上(注意:传递js表达式(常量,变量,数字,对象,数组),要加:冒号。不加的话,vue应用系统定制开发模板解析会认为是一个字符串)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
<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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

子组件怎么接收?

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

简单接收

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

顺利接收

复杂接收

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

顺利接收

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

数据类型不对

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

必传未传

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

自定义校验函数未通过

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

props接收的值存在哪?

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

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

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

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

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

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

想要修改props的值怎么办?

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

.sync修饰符

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

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31


Son.vue

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

完整代码

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发