vue组件间数据传递—props

关于props,老套路,看下官网的解释:

props可以是数组或对象,用于接收父组件的数据。。。

之所以父组件的数据需要通过props传到子组件中,因为组件实例的作用域是孤立的,子组件模板不可能直接引用父组件数据。。。(也就是说子组件不能在模板中渲染父组件中的数据)

<div id="app">
   <son-component :alias="name"></son-component>    
</div>
<script>
var sonComponent = {
    props:["alias"],
    data(){
        return {
            myalias:this.alias
        }
    },
    //可直接把数据写在摸板中,在data 或方法中取props里边的数据用this.xxx
    template:`<div>{{myalias}}{{alias}}</div>`
}


//根实例中的name数据传给子组件
var vm = new Vue({
    el:"#app",
    data:{
        name:"吕星辰"
    },
    components:{
        sonComponent
    }
})
</script>

上边代码,子组件"son-component"引用了父组件(根实例)的name数据,在自定义标签上,name是父组件中的数据,前边alias是自定义的名字,子组件也是通过自定义名字来接受父组件传来的值。

 

porp类型

数组:可以传多个数据

props:["title","name","age", ··· ]

对象:可以指定props中的每一个值的类型

props:{
    title:String,//title必须是字符串类型
    name:String,//name必须是字符串类型
    age:Number,//age必须是数字类型
    callback:Function//callback必须是函数
}

prop验证

我们可以为props中的值提供一个带有验证需求的对象,而不是字符串数组。

这一点在开发中经常会用到,基于vue封装一些组件库时尤为重要。

大致分为5种情况:

Vue.component("myComponent",{
   props:{
      //基础类型的检查
	 param1:Number,
     //字符串或数字都行
	 param2:[String,Number],
	 //param3必须要填写,而且要是字符串类型的才行
	 param3:{
		type:String,
		require:true
	 },
     //如果param4没有传的话,默认值是100
	 param4:{
		type:Number,
		default:100
	 },
     //自定义校验函数(value是传递过来的参数,且必须是数组中的某一个)
	 param5:{
		validator(value){
		   return ["hehe","haha","heihei"].indexOf(value) !== -1
		}
	 },
     //如果参数是一个数组 或者对象 ,默认值必须从工厂函数中获取
	 param6:{
		default(){
		  return {width:"100px",height:"30px",backgroundColor:red}
		}
	 }

   }
})

当验证失败时,Vue会产生一个控制台警告。

类型检查中的type可以是:String、Number、Boolean、Array、Object、Date、Function、Symbol。

 

在这里我们说几个值得注意的地方:

1、子组件中不可以更改来自父组件的数据。

<div id="app">
	<son-component :num="number"></son-component>
</div>

<script>

 //子组件
 let sonComponent = {
	props:["num"],
	template:`<button @click="changeData">{{num}}</button>`,
	//修改父组件传过来的数据
	methods:{
	  changeData(){
	    this.num = 30
	  }
	}
  }

    //父组件
 let vm = new Vue({
	el: "#app",
	data: {
	   number: 20
	},
	components: {
	   sonComponent
	}
  });


</script>

这里Vue会报错。

如果你非要修改,有两种方法,相信大家从上边vue报错中也能发现,官方给提供了这2种方法:(分情况而定,根据不同需求来)

一、在data中,可在子组件data数据对象中把父组件数据保存,这样会有一个问题,父组件数据更改,子组件中的props里边的数据会更新,但是子组件模板中的数据不会更新!

let sonComponent = {
	props: ["num"],
	data() {
		return {
		  changeNum: this.num//把数据线存到changeNum中,更改changeNum
		};
	},
	template: `<button @click="changeData">{{changeNum}}</button>`,
	methods: {
		changeData() {
		   this.changeNum = 30;
		}
	}
};

二、在计算属性中:

<div id="app">
	<son-component :alias="name"></son-component>
</div>

<script>

let sonComponent = {
	props: ["alias"],
	template: `<p>{{myAlias}}</p>`,
	computed: {
		myAlias() {
		    return this.alias.trim()
		}
	}
};

let vm = new Vue({
	el: "#app",
	data: {
		name:"   lxc   "
	},
	components: {
		sonComponent
	}
});

</script>

2、子组件中更改来自父组件对象形式的数据,父组件数据也会跟着更改,因为对象或数组都是引用类型的,当一个对象赋给一个变量时,这个变量只是引用的对象地址。

<div id="app">
	<son-component :change="author"></son-component>
</div>

<script>
let sonComponent = {
	props: ["change"],
	template: `<button @click="changeFatherData">{{change}}</button>`,
	methods: {
        //更改数据对象中的name属性
		changeFatherData() {
		    this.change.name = "hehe";
		}
	}
};

let vm = new Vue({
	el: "#app",
	data: {
		author:{name:"lxc",age:20,height:170}
	},
	components: {
		sonComponent
	}
});
</script>

结果显示:父组件中的name属性也改变了。。。

以上是vue中props用法,有不足的地方,希望指正,以后我会随时更新。。。

 

补充:

一个小例子:

一个button按钮组件:

<template>
  <div class="home">
    <about :myStyle="style" :mycontent="content"></about>
  </div>
</template>
<script>
import about from '@/views/About.vue'
export default {
  name: 'home',
  data(){
    return{
      content:"click",
      style:{
        width:"80px",
        height:"30px",
        backgroundColor:"#f40",
        color:"#fff",
        lineHeight:"30px",
      }
    }
  },
  components: {
    about
  }
}
</script>

子组件用props接受来自父组件的数据

<template>
  <div class="about">
    <div :style="myStyle">{{mycontent}}</div>
  </div>
</template>

<script>
export default {
  name:"about",
  props:{
    mycontent:{
      type:String,
      default:"click"
    },
    myStyle:{
      type:Object,
      default(){
        return {
          width:"200px",
          height:"50px",
          backgroundColor:"#000",
          borderRadius:"5px",
          color:"#fff",
          textAline:"center",
          lineHeight:"50px",
          fontSize:"30px"
        }
      }
    }
  }
}
</script>

渲染结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值