prop:组件上注册的一些自定义属性
prop作用:向子组件传递数据
特点:
可以传递任意数量,任意类型的prop
父组件
(一个个地传递比较麻烦,可以直接打包成一个对象传过去,然后通过点属性接收)<template> <div id="app"> <!-- <img src="./assets/logo.png"> <router-view/> --> <son :username="usernaem" :age="age" :isSingle="isSingle" :car="car" :hobby="hobby" ></son> </div> </template> <script> import son from './components/son' export default { // name: 'App' data() { return { usernaem:'小帅', age:25, isSingle:true, car:{ brand:'宝马', }, hobby:['篮球','足球','乒乓球'] } }, components:{ son } } </script> <style> /* #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } */ </style>
子组件<template> <div> <h3>个人信息组件</h3> <div>姓名:{{ username }}</div> <div>年龄:{{ age }}</div> <div>是否单身:{{ isSingle }}</div> <div>爱好:{{ hobby.join(',') }}</div> <div>车:{{ car.brand }}</div> </div> </template> <script> export default { props:['username','age','isSingle','hobby','car'] } </script>
prop校验
app组件<template> <div id="app"> <!-- <img src="./assets/logo.png"> <router-view/> --> <baseprogress :w="width" ></baseprogress> </div> </template> <script> import Baseprogress from './components/baseprogress.vue' export default { // name: 'App' data() { return { width:'abc' //50 } }, components:{ Baseprogress } } </script> <style> </style>
baseprogress组件
<template> <div class="base-progress"> <div :style="{width:w + '%'}" > <span>{{ w }}%</span> </div> </div> </template> <script> export default { props:['w'] } </script> <style scoped> .base-progress { height: 26px; width: 400px; border-radius:15px; background-color: red; border:3px solid black; box-sizing:border-box; margin-bottom: 30px; } </style>
当width是字符串时,居然也能显示而且不报错,这就出问题了
如果希望组件传错了,能给提示,就需要加校验写法。将数组写法改为对象写法,对象中有键和值。键就是当前props中的名字,值就是校验要求。也可以写String,Boolean,Array,Object,Function
可以看到因为传过来的不是数然后报错了
非空校验
这两种写法是一样的
漏传或者默认二选其一即可,要么没传过来报错,要么设定一个默认值管传没传过来自定义的形参能接收到来自父组件的传值value
//完整写法(类型,非空,默认,自定义) props:{ type:Number, required:true, //如果w漏传,会报错 default:0, //默认值 validator(value) { // console.log(value) if (value >=0 && value <= 100) { return true } else { console.error('传入的prop w必须是0-100的数字') return false } // return true //true则通过了校验,false则没有通过校验 // return false } } }
prop和data的区别
在自己组件中的数据能直接修改
而如果想要修改传过来的数据就会报错
如果想要在子组件中修改数据,那么只能给父组件传递修改信息,让父组件进行数据修改在按键中不仅是直接对数据进行加减操作了,将进行加减的按键分别绑定不同函数
函数中定义相同的事件和不同的要修改后的数值,将之传给父组件
父组件定义一个函数监听该事件
在该函数中将修改后的值赋值给原变量
然后父组件将变化后的值又继续传递给子组件了,形成闭环
BaseCount组件<template> <div class="base-count"> <button @click="handleub">-</button> <span>{{count}}</span> <button @click="handleup">+</button> </div> </template> <script> export default { // 1.自己的数据自己负责,随便改 // data(){ // return { // count:999 // } // }, // 2.prop传过来的数据(外部的数据)不能直接改 props: { count:Number }, methods:{ // 子传父this.$emit(事件名,参数) handleub(){ this.$emit('changeCount',this.count -1) //不能是++或者--,因为这就相当于修改数据了 }, handleup(){ this.$emit('changeCount',this.count +1) } } } </script> <style scoped> </style>
App组件
<template> <div id="app"> <BaseCount :count="count" @changeCount="handleChange"></BaseCount> </div> </template> <script> import BaseCount from './components/BaseCount.vue' export default { data() { return { count:666 } }, components: { BaseCount }, methods:{ handleChange(newcount) { this.count = newcount } } } </script> <style> </style>