组件通信深入

1.组件通信自定义事件深入

父组件给子组件绑定原生DOM事件

<template>
    <div>
      <!-- 此处的Son为组件Father的子组件 -->
        <Son @click="Dome"></Son>
			<!-- 此时@click会被认为是组建的自定义事件需要在子组件中用$emit触发绑定事件 -->
       	<Son @click.native="Dome"></Son>
			<!--   native:原生的  将组建的自定义事件转化为DOM的原生事件
      其原理就是给子元素的根节点绑定了单击事件-->
      <button @click="Dome">按钮绑定自定义事件,没办法触发没有意义</button>
    </div>
</template>

<script>
import Son from './components/Son.vue'; 
    export default {
        name:'Father',
        components:{
            Son,
        },
        methods:{
            Dome(){
                alert("绑定Son组件的单击事件Dome被执行了")
            }
        }
    };
</script>

  

2.v-model深入

<template>
    <div> 
        {{ textData }}
        <input type="text" v-model="textData">
        <!--   实现v-model功能  
          1.给input框绑定一个value值textData
          2.触发input事件(@input 表单元素文本发生变化时会执行)
          3.变化后的textData再赋值给textData
          ($event.target.value 当前DOM元素变化后的value值 )
          -->
        <input type="text" :value="textData" @input="textData=$event.target.value" >
				 <!--   实现父子组件数据同步功能  
          1.给子组件传递数据textData
          2.给子组件绑定自定义事件@vmodel 回调 将自定义事件的返回值赋给textData
          -->
        <Son :textData="textData" @vmodel="textData=$event"></Son>
				<!-- :textData="textData" @vmodel="textData=$event" 等同于 v-model="textData"  -->
        <Son v-model="textData"></Son>
    </div>
</template>

<script>
import Son from './components/Son.vue'; 
    export default {
        name:'Father',
        components:{ Son, },
        data() {
            return {
                textData:'我是数据'
            }
        },
    };
</script>
<template>
  <div class="Son" >
    我是Son组件
		<!--2.将textData的值赋给文本框的值value 
    		3.触发input事件 调用自定义事件vmodel,将input框最新的值传给返回给父组件 -->
    <input type="text" :value="textData" @input="$emit('vmodel',$event.target.value)" >
  </div>
</template>

<script>
export default {
    // 1.接收父组件传过来的值textData
    props:['textData'],
    name:'Son',
}
</script>

3.sync修饰符

<template>
    <div> 
      我今年{{ age }}岁。<br>
      <Son :age="age" @updata:age="age=$event"></Son>
			<!-- .sync修饰符等同于   @updata:age="age=$event"
           :age.sync="age"   给子组件传递了一个age数据
           并给子组件绑定了一个@updata:age事件
      -->
      <Son :age.sync="age" ></Son>
    </div>
</template>

<script>
import Son from './components/Son.vue'; 
    export default {
        name:'Father',
        components:{ Son, },
        data() {
            return {
                age:18,
            }
        },
    };
</script>
<template>
  <div class="Son" >
    现在他 {{ age }}岁
    <button @click="$emit('updata:age',age-1)">过了一年</button>
  </div>
</template>

<script>
export default {
    props:['age'],
    name:'Son',
}
</script>

4.$attrs 和 $listener

<template>
    <div> 
       <Son 
       type="primary" 
       title="提示"
       @click="Dome"
       ></Son>       
    </div>
</template>

<script>
import Son from './components/Son.vue'; 
    export default {
        name:'Father',
        components:{ Son,},
        methods:{
            Dome(){
                alert('提示我')
            },
        }
    };
</script>

:::tips
$attrs 用于接受父组件传来的参数 type="primary" title="提示"
当子组件用props接收参数 title="提示" $attrs 接受的参数将会将 title="提示" 去掉剩下 type="primary"
使用的时候必须配合 v-bind="$attrs" 不能简写
$listeners 用于接收父组件传过来的自定义事件 使用时必须 v-on="$listeners" 不能写成简写形式
:::

<template>
  <div class="Son" >
    <a title="title">
      <el-button v-bind="$attrs" v-on="$listeners" > 加载中</el-button>
      <br>
      <button @click="Dome" v-on="" >nininin</button>
    </a>
  </div>
</template>
<script>
export default {
  name:"Son",
  props:['title'],
  methods:{
    Dome(){
      console.log(this.$listeners)
    }
  }
}
</script>

5.$children和$parent

1 $children 可以拿到父组件中的所有子组件,值为一个数组
2 $parent 可以拿到子组件的父组件

<template>
    <div> 
        {{ money }}        
        <button @click="getSonMoney(100)">向son借钱100元</button>
        <button @click="getSon2Money(200)">向son借钱200元</button>
        <button @click="getAllMoney(300)">向son和son2借钱300元</button>
        <Son ref="son"></Son>
        <Son2 ref="son2"></Son2>
    </div>
</template>
<script>
import Son from './components/Son.vue'; 
import Son2 from './components/Son2.vue'; 
    export default {
        name:'Father',
        components:{ Son,Son2},
        data(){
            return{
                money:300000,
            }
        },
        methods:{
            getSonMoney(money){
                // ref 标签的所有属性
                this.money+=money
                //拿到子组件的money值并计算赋值
                this.$refs.son.money-=money
            },
            getSon2Money(money){
                this.money+=money
                this.$refs.son2.money-=money
            },
            getAllMoney(money){
                this.money+=2*money
              //$children 可以拿到所有子组件,值为一个数组
                this.$children.forEach(item => {
                    item.money-=money
                });
            },         
        }
    };
</script>
<template>
  <div class="Son" >
      <button  @click="getMoney(100)">向father借钱100元</button>{{ money }}
  </div>
</template>
<script>
export default {
  name:"Son",
  data() {
    return {
      money:10000,
    }
  },
  methods:{
    getMoney(money){
      this.money+=money
      this.$parent.money-=money
    }
  }
}
</script>
<template>
  <div class="Son2">
    <button @click="getMoney(200)">向father借钱200元</button>{{ money }}
  </div>
</template>
<script>
export default {
  name: 'Son2',
  data() {
    return {
      money: 13000,
    }
  },
  methods:{
    getMoney(money){
      this.money+=money
      //拿到自组件的父组件并计算赋值
      this.$parent.money-=money
    }
  }
}
</script>

6.mixin 混入(混合)

续5
1 将son和son2中相同的部分摘取出来 放在hunhe.js文件中

export default {
  // 将son和son2中相同的部分摘取出来 放在hunhe.js文件中
    methods: {
        getMoney(money) {
            this.money += money
            this.$parent.money -= money
        }
    }
}

2 在Son和Son2组件中引入hunhe.js并进行使用

<template>
  <div class="Son" >
      <button  @click="getMoney(100)">向father借钱100元</button>{{ money }}
  </div>
</template>
<script>
import hunhe from './hunhe'
export default {
  mixins:[hunhe],
  name:"Son",
  data() {
    return {
      money:10000,
    }
  },
}
</script>
<template>
  <div class="Son2">
    <button @click="getMoney(200)">向father借钱200元</button>{{ money }}
  </div>
</template>
<script>
import hunhe from './hunhe'
export default {
  mixins:[hunhe],
  name: 'Son2',
  data() {
    return {
      money: 13000,
    }
  },
}
</script>
posted @ 2023-02-20 23:12  陌小丠  阅读(16)  评论(0)    收藏  举报