Vue组件间通信深入,父向子 子向父 非父子
组件间传值父向子传值通过标签属性传值如果子组件的props接收了 那这个标签属性就具有props特性如果子组件的props没有接收 那这个标签属性就是一个普通的自定义属性/*vue中父组件向子组件传递数据的套路:1. 父组件通过子组件的标签属性向子组件传递数据2. 子组件要通过props配置来选择性的接受父组件的数据*/<body><div id="app">
·
组件间传值
父向子传值
通过标签属性传值
如果子组件的props接收了 那这个标签属性就具有props特性
如果子组件的props没有接收 那这个标签属性就是一个普通的自定义属性
/*vue中父组件向子组件传递数据的套路:
1. 父组件通过子组件的标签属性向子组件传递数据
2. 子组件要通过props配置来选择性的接受父组件的数据*/
<body>
<div id="app">
<v-count :count="count"></v-count>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
/*vue中父组件向子组件传递数据的套路:
1. 父组件通过子组件的标签属性向子组件传递数据
2. 子组件要通过props配置来选择性的接受父组件的数据*/
var count = {
props:["count"],
template:`<span class="count">{{count}}</span>`
}
Vue.config.productionTip = false;
var vm = new Vue({
el:"#app",
data:{
count:0
},
components:{
"v-count":count
}
})
</script>
父组件如何向子组件传值 父组件通过标签属性的形式向子组件传值。 子组件可以通过props属性正常接收到来自父组件的值。 但值得注意的是 子组件接收到父组件的值后不应该修改接收到的值, 因为该值果然是一个对象,而且被几个子组件共同引用着。那很有可能会导致脏数据
非得改这数据,应该怎么办?
转存一份,再改
/*vue中父组件向子组件传递数据的套路:
1. 父组件通过子组件的标签属性向子组件传递数据
2. 子组件要通过props配置来选择性的接受父组件的数据*/
// 不建议在子组件中直接修改父组件的数据
// 如果确定子组件之间的数据是公共的!!!
// 子组件需要通知父组件自己修改数据
在vue中组件间传值是要单向数据流的,子组件不能随意修改来着父组件的值。
独立数据
<body>
<div id="app">
<v-count :count="count"></v-count>
<v-count :count="count"></v-count>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
/*vue中父组件向子组件传递数据的套路:
1. 父组件通过子组件的标签属性向子组件传递数据
2. 子组件要通过props配置来选择性的接受父组件的数据*/
// 不建议在子组件中直接修改父组件的数据
//如果确定子组件之间的数据是独立的!!! 子组件接到父组件的数据之后一定要转存一份
var count = {
props:["count"],
data(){
return {
//将父组件传递来的数据转存一份
// flag:this.count.flag
flag:this.count
}
},
template:`<span class="count" @click="addFn">{{flag}}</span>`,
methods:{
addFn(){
//子组件直接修改了父组件的数据
//this.count.flag++
//改的子组件的数据
this.flag++
}
}
}
Vue.config.productionTip = false;
var vm = new Vue({
el:"#app",
data:{
/*count:{
flag:0
}*/
count:0
},
components:{
"v-count":count
}
})
</script>
公共数据
// 如果确定子组件之间的数据是公共的!!!
// 子组件需要通知父组件自己修改数据
<body>
<div id="app">
<!--v-count.$on("updatecount,updateCount)-->
<v-count :count="count" @updatecount="updatecount"></v-count>
<v-count :count="count" @updatecount="updatecount"></v-count>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
/*vue中父组件向子组件传递数据的套路:
1. 父组件通过子组件的标签属性向子组件传递数据
2. 子组件要通过props配置来选择性的接受父组件的数据*/
// 不建议在子组件中直接修改父组件的数据
// 如果确定子组件之间的数据是公共的!!!
// 子组件需要通知父组件自己修改数据
var count = {
props:["count"],
template:`<span class="count" @click="addFn">{{count.flag}}</span>`,
methods:{
addFn(){
//通知父组件自己修改数据
this.$emit("updatecount")
}
}
}
Vue.config.productionTip = false;
var vm = new Vue({
el:"#app",
data:{
count:{
flag:0
}
// count:0
},
components:{
"v-count":count
},
methods:{
updatecount(){
this.count.flag++
}
}
})
</script>
props
props特性
最终不会表现在dom节点中
子组件拿到props之后就等于是拿到了一个data
非props特性
会表现在dom节点中
props验证:
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,
则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助
验证方式:
props:[] 数组;数组的每一项表示接受父组件传过来的哪些属性(无法做验证)
props:{} 对象;通过键值对的形式表示接受父组件传过来的哪些属性
key :哪些属性
value:验证规则
key:type
key:[type1,type2]
key:{
type: String,
required: true,
//default: 100
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
//自定义验证
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
type: String Number Boolean Array Object Date Function Symbol
子向父传值
1. 父亲向儿子传一个props 这个props是一个函数
通过函数的调用传参进行父组件的修改
2. 通过vue自定义事件
1.function&props
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.count{
display: inline-block;
border-radius: 50%;
width: 150px;
height: 150px;
background: pink;
line-height: 150px;
text-align: center;
}
</style>
</head>
<body>
<div id="app">
让vue管理updateMsg在子组件中接收
<v-count :count="count" :updatemsg="updateMsg"></v-count>
{{msg}}
</div>
</body>
<script src="../js/vue.js"></script>
<script>
var count = {
props:["count","updatemsg"],
data(){
return {
msg:"子组件的msg"
}
},
template:`<span class="count" @click="clickFn">{{count}}</span>`,
methods:{
clickFn(){
this.updatemsg(this.msg)
}
}
}
Vue.config.productionTip = false;
var vm = new Vue({
el:"#app",
data:{
count:0,
msg:"父组件的msg"
},
components:{
"v-count":count
},
methods:{
updateMsg(msg){
this.msg = msg
}
}
})
</script>
</html>
2.自定义vue事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.count{
display: inline-block;
border-radius: 50%;
width: 150px;
height: 150px;
background: pink;
line-height: 150px;
text-align: center;
}
</style>
</head>
<body>
<div id="app">
@updatemsg: 定义的事件名 updateMsg:父组件中的方法
<v-count :count="count" @updatemsg="updateMsg"></v-count>
{{msg}}
</div>
</body>
<script src="../js/vue.js"></script>
<script>
//子
var count = {
props:["count"],
data(){
return {
msg:"子组件的msg"
}
},
template:`<span class="count" @click="clickFn">{{count}}</span>`,
methods:{
clickFn(){
//在此处调用定义的updatemsg事件 ,并传递一个参数
this.$emit("updatemsg",this.msg)
}
}
}
//父
Vue.config.productionTip = false;
var vm = new Vue({
el:"#app",
data:{
count:0,
msg:"父组件的msg"
},
components:{
"v-count":count
},
methods:{
updateMsg(msg){
this.msg = msg
}
}
})
</script>
</html>
非父子
总线机制
pubsub
1.总线
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<v-a></v-a>
<v-b></v-b>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
Vue.config.productionTip = false;
//总线 $bus是一个vue实例 有能力注册vue自定义事件
Vue.prototype.$bus = new Vue();
new Vue({
el:"#app",
components:{
"v-a":{
data(){
return {
msg:"v-a"
}
},
template:`<strong @click="clickFn">{{msg}}</strong>`,
methods:{
clickFn(){
//触发$bus上的updateMsg事件
this.$bus.$emit("updateMsg",this.msg);
}
}
},
"v-b":{
data(){
return {
msg:"v-b"
}
},
template:`<strong >{{msg}}</strong>`,
mounted(){
//钩子函数给$bus注册事件
this.$bus.$on("updateMsg",(msg)=>{
this.msg = msg;
})
}
}
}
})
</script>
</html>
2. pubsub
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<v-a></v-a>
<v-b></v-b>
</div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/pubsub-js/1.9.0/pubsub.min.js"></script>
<script src="../js/vue.js"></script>
<script>
Vue.config.productionTip = false;
new Vue({
el:"#app",
components: {
"v-a": {
data() {
return {
msg: "v-a"
}
},
template: "<strong @click='clickFn'>{{msg}}</strong>",
methods: {
clickFn() {
//pubsub进行发布
PubSub.publish("updateMsg", this.msg);
}
}
},
"v-b":{
data(){
return{
msg:"v-b"
}
},
template:"<strong>{{msg}}</strong>",
mounted(){
//pubsub订阅
PubSub.subscribe('updateMsg',function(name,msg){
this.msg = msg
}.bind(this));
}
}
}
})
</script>
</html>
更多推荐
已为社区贡献6条内容
所有评论(0)