props 用于接收父组件传过来的数据,父传子。
props 是只读的,如果修改 props 中的数据,Vue 会发出警告。如果需要修改,可以将 props 中的数据复制到 data 中,然后修改 data 中的数据。
引出 props 的作用:
首先需要在 components 文件夹内创建一个子组件。例:Shop.vue 组件。
<template>
<div>
<h2>商品名称:{{ name }}</h2>
<strong>商品价格:¥{{ price }}</strong>
<p>商品数量:{{ num }}</p>
<hr />
</div>
</template>
<script>
export default {
name: "Shop",
data() {
return {
name: "草莓",
price: 999,
num: 100
}
}
}
</script>
然后在 Home.vue 页面引入 Shop.vue 组件 并多次使用创建商品。
<template>
<div>
<h2>商品列表</h2>
<hr />
<Shop></Shop>
<Shop></Shop>
<Shop></Shop>
</div>
</template>
<script>
import Shop from "../components/Shop";
export default {
name: 'Home',
components: { Shop }
}
</script>
注:所有商品的内容都是一样的 很明显不符合实际场景 如果想要动态指定每个组件的内容 需要使用 props 配置项了。
props 数组写法【无限制】:
在 Shop.vue 组件内定义 props 并以数组的形式接收参数 然后在页面使用即可。
<template>
<div>
<h2>商品名称:{{ name }}</h2>
<strong>商品价格:¥{{ price }}</strong>
<p>商品数量:{{ num }}</p>
<hr />
</div>
</template>
<script>
export default {
name: "Shop",
props: ['name', 'price', 'num'],
}
</script>
在 Home.vue 页面使用组件时 直接在标签中传递参数即可。
<template>
<div>
<h2>商品列表</h2>
<hr />
<Shop name="草莓" price="99" num="50"></Shop>
<Shop name="苹果" price="30" num="30"></Shop>
<Shop name="葡萄" price="56" num="20"></Shop>
</div>
</template>
<script>
import Shop from "../components/Shop";
export default {
name: 'Home',
components: { Shop }
}
</script>
注:在组件标签中 不允许使用 key、ref 等 Vue 已经使用的关键字作为参数名。
也可以配合 v-for 指令动态传递参数 效果一致。
<template>
<div>
<h2>商品列表</h2>
<hr />
<Shop v-for="item in lists" :key="item.id" :name="item.name" :price="item.price" :num="item.num"></Shop>
</div>
</template>
<script>
import Shop from "../components/Shop";
export default {
name: 'Home',
components: { Shop },
data() {
return {
lists: [
{
id: 1,
name: "草莓",
price: 99,
num: 50
}, {
id: 2,
name: "苹果",
price: 30,
num: 30
}, {
id: 3,
name: "葡萄",
price: 56,
num: 20
}
]
}
}
}
</script>
注:如果不需要对数据进行任何限制 推荐使用数组写法。
对象写法【限制数据类型】:
将 Shop.vue 组件中的 props 配置项换成对象的写法 并设置数据类型。
<template>
<div>
<h2>商品名称:{{ name }}</h2>
<strong>商品价格:¥{{ price }}</strong>
<p>商品数量:{{ num }}</p>
<hr />
</div>
</template>
<script>
export default {
name: "Shop",
props: {
name: String,
price: Number,
num: Number
}
}
</script>
然后在 Home.vue 页面正常引入 在组件标签上定义内容即可。
<template>
<div>
<h2>商品列表</h2>
<hr />
<Shop name="草莓" price="99" num="50"></Shop>
<Shop name="苹果" price="30" num="30"></Shop>
<Shop name="葡萄" price="56" num="20"></Shop>
</div>
</template>
<script>
import Shop from "../components/Shop";
export default {
name: 'Home',
components: { Shop }
}
</script>
注:数据虽然可以正常显示 但是控制台出现了报错 这是因为 props 定义的 price 和 num 的类型为数字,而接收到的却是字符串。
在组件标签上 直接写的数据都是字符串类型 可以用 v-bind 动态指定数据解决这个问题。
<template>
<div>
<h2>商品列表</h2>
<hr />
<Shop name="草莓" :price="99" :num="50"></Shop>
<Shop name="苹果" :price="30" :num="30"></Shop>
<Shop name="葡萄" :price="56" :num="20"></Shop>
</div>
</template>
<script>
import Shop from "../components/Shop";
export default {
name: 'Home',
components: { Shop }
}
</script>
注:这是因为 Vue 会将 v-bind 绑定的内容当做 JS 表达式去解析 而不是普通的字符串。
完整写法【限制数据类型、默认值、是否必填】:
将 Shop.vue 组件中的 props 配置项换成完整写法,并限制数据类型、将 name、price 设置为必填、给 num 设置默认值。
<template>
<div>
<h2>商品名称:{{ name }}</h2>
<strong>商品价格:¥{{ price }}</strong>
<p>商品数量:{{ num }}</p>
<hr />
</div>
</template>
<script>
export default {
name: "Shop",
props: {
name: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
num: {
type: Number,
default: 0
}
}
}
</script>
然后在 Home.vue 页面正常引入 不过在传参时 我们少传几个参数演示一下。
<template>
<div>
<h2>商品列表</h2>
<hr />
<Shop name="草莓" :price="99" :num="50"></Shop>
<Shop name="苹果" :price="30"></Shop>
<Shop name="葡萄"></Shop>
</div>
</template>
<script>
import Shop from "../components/Shop";
export default {
name: 'Home',
components: { Shop }
}
</script>
注:如果在 props 中定义了默认值 不传参会显示这个默认值 如果在 props 中定义了必填 不传参就会报错并且页面无内容。
备注:默认值和必填选项不能一起使用 完整写法一般很少使用 用的最多的还是第一种哟。