Vue组件的props配置,让组件能够接收外部传入数据

Vue组件的props配置

简单来讲: 让组件能够接收外部传来的数据

1. 简单案例

1.1 案例演示

现在有个需求,我定义了一个组件Table(将定义的allDatas展示为表格)

<template>
  <div>
    一个列表组件
    <table>
      <thead>
      <tr>
        <th colspan="3">{{ tableTitle }}</th>
      </tr>
      <tr>
        <th v-for="tableHead in Object.keys(allDatas[0])">
          {{ tableHead }}
        </th>
      </tr>
      </thead>

      <tbody>
      <tr v-for="tableRowData in allDatas" :key="tableRowData.id">
        <td v-for="tableColData in Object.values(tableRowData)">
          {{ tableColData }}
        </td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: "User",
  data() {
    return {
      tableTitle: "用户列表",
      allDatas: [
        {
          id: 1,
          name: '小明',
          age: 20,
        },
        {
          id: 2,
          name: '张三',
          age: 16,
        },
        {
          id: 3,
          name: '李华',
          age: 19,
        },
        {
          id: 4,
          name: '王五',
          age: 17,
        },
      ]
    }
  },
}
</script>

<style>
table {
  border-width: 6px;
  border-collapse: collapse;
  width: 200px;
  text-align: center;
}

table th, table td {
  border: solid 1px;
}

</style>

此时,渲染后的HTML是这样的
在这里插入图片描述

1.2 需求分析

现在我想做的是,把这个表格的显示,作为一个可变的引入,任何的Vue调用我这个组件,只要传入了这样的表格,就能够正常渲染,说白了就是,我现在写的是用户列表,你下次调用一个学校列表,只要把参数给我,我就能渲染

而Vue,为我们提供了props配置,让我们的组件,能够去接收外部的数据

2. 实现需求

2.1 定义一个School组件

现在我定义School组件

School.vue

<template>
  <!-- 通过给List组件,绑定v-bind指令,即可实现数据的传参 -->
  <List :tableTitle="tableTitle" :allDatas="allDatas"></List>
</template>

<script>
import List from "@/components/List.vue";

export default {
  name: "School",
  data() {
    return {
      tableTitle: "学校列表",
      allDatas: [
        {
          id: 1,
          name: '老八大学',
          area: '50000m²',
        },
        {
          id: 2,
          name: '牛马大学',
          area: '80000m²',
        },
      ]
    }
  },
  components:{List}
}
</script>

<style scoped>

</style>

2.2 定义List组件的props(精简定义)

原本的List组件,就不能把数据定义死了,而是要定义在props参数中

<template>
	...省略
</template>

<script>
export default {
  name: "List",
  // 定义props就不要在data中再额外定义了,不然会报错
  props:['tableTitle','allDatas'] 
  // 这里需要定义需要接收的参数,这里需要是数组形式
}
</script>

2.3 注意事项

List组件,其实在这里类似于一个"抽象基类",可以给他继续喂东西,我们后续"继承"它的模板,但是不要将数据写死,所以我们尽量将用到的数据全部都放在props

2.4 props指定数据的类型

上面的数据,我们并没有涉及到数据的增加/变化,如果我们需求是这样的:

现在必须规定传入的参数是一个数字类型,传入其他类型,就报错

这个时候,我们简单的props就不行了,需要使用完整版props定义

<script>
export default {
  name: "Demo",
  props:{
    num:Number, // 指定num的类型,必须是Number
    name:String // 指定name的类型,必须是字符串
  }
}
</script>

此时,如果我们数据的类型,传错,会出现什么情况呢?

<Demo num="10" :name="6"></Demo>

注意:我这里的num=10没有使用v-bind,但是name使用了v-bind,所以等同于传入了以下

  • num = “10” // 字符串
  • name = 6 // 数字

和要求的传入,刚好相反,所以控制台报错

在这里插入图片描述

但是数据还是能显示的,但是既然定义了类型就不要出这种小错误!!!

在这里插入图片描述

2.5 props的数据验证(完整配置)

如果我们还需要定义,参数必须传,或者参数的默认值,或者需要满足什么要求,可以使用完整配置

Vue官方文档-props数据验证

<script>
export default {
  name: "Demo",
  props:{
    num:{
        type:Number, // 数字类型
        required:true, // 表明该参数必传!
        validator:function(value){
            return value <50? true :false // 约束传入的值,必须小于50
        }
    },
   	name:{
        type:String, // 字符串类型
        default:"未知姓名" // 定义默认值,不要和required同时出现
    }
  }
}
</script>

3. props的单向数据流(重中之重)

props传入的参数,本质上应该是只读类型,虽然可以更改,但是我们不要更改,否则会让Vue出现异常!

Vue官方文档-单项数据流

3.1 案例演示

我这样来实现案例:

  • 定义一个组件,需要传入num
  • 点击按钮会让传入的num+1
<template>
  <div>
    <div>num的值:{{ num }}</div>
    <button @click="num++">点下加1</button>
  </div>
</template>

在这里插入图片描述

可以发现,虽然值也确实增加了,但是一直报错

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "num"
意思就是,让我们不要直接修改组件传入的值,让我们用中转变量接着修改

3.2 中转变量实现修改数据

先看原本的方案:

<template>
  <div>
    <div>num的值:{{ num }}</div>
    <button @click="num++">点下加1</button>
  </div>
</template>

<script>
export default {
  name: "Demo",
  props: {
    num: Number, // 指定num的类型,必须是Number
  }
}
</script>

使用中转变量

<template>
  <div>
    <div>num的值:{{ myNum }}</div> // 这里使用中转变量
    <button @click="myNum++">点下加1</button>
  </div>
</template>

<script>
export default {
  name: "Demo",
  data() {
    return {
      myNum: this.num // 通过中转变量实现数据修改
      ,
    }
  },
  props: {
    num: Number, // 指定num的类型,必须是Number
  }
}
</script>

此时,浏览器则不再报错!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值