欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue组件相关props,$parents , $children, $refs , provide / inject 使用

程序员文章站 2024-03-15 10:53:05
...

组件基本需要这三部分组成

props(属性)

event(事件)

slot(插槽)

父子组件通信

# App.vue (父组件)
<template>
  <div id="app">
    <Child :msg="messsage" :model="obj" :myArr="arr"/>
  </div>
</template>
<script>
import Child from './components/Child'
export default {
  name: 'app',
  components: {
    Child
  },
  data(){
    return{
      messsage:'我是父组件的数据',
      obj:{
        name: "hello",
        age:15,
      },
      arr:[1,2,3,4],
    }
  }
}
</script>

# Child.vue (子组件)

<template>
  <div>
    <h1>{{ msg }}</h1>
    <h2>{{ model.name }} - {{model.age}}</h2>
    <ul>
      <li v-for="(item,index) in myArr" :key="index">
        {{item}}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  // props 里 推荐使用对象写法,用于组件的数据结构校验
  /** 父子组件传值 */
  props: { 
    // 父组件传入的属性是一个基本数据类型
    msg: { 
      type: String,
      default: '',
    },
    // 父组件传入的属性是一个对象
    model: {
      type: Object,
      default: () => {},
      required:true,
    },
    // 父组件 传入 一个数组
    myArr:{
      type:Array,
      default:() => [],
    }
  }
}
</script>

<style scoped>
</style>

子向父组件通信 ( $on, $emit)


# 子组件 Child.vue

<template>
  <div>
    <h1>{{ msg }}</h1>
    <button @click="changeHandle">change父组件的值</button>
  </div>
</template>
<script>
export default {
  props: { 
    msg: { 
      type: String,
      default: '',
    },
  },
  methods:{
    changeHandle(){
      this.$emit("changeParent","我是子组件的值")
    }
  }
}
</script>



# 父组件 App.vue

<template>
  <div id="app">
    <Child @changeParent="getChildData" :msg="messsage"/>
  </div>
</template>
<script>
import Child from './components/Child'
export default {
  name: 'app',
  components: {
    Child
  },
  data(){
    return{
      messsage:'我是父组件的数据',
    }
  },
  methods:{
    getChildData(params){
      this.messsage = params;
    }
  }
}
</script>

子组件通过 $parent 获取父组件的数据

# Child.vue (子组件)
<template>
  <div>
     <!-- this.$parent.messsage -->
    <h1>{{ this.$parent.messsage }}</h1>
      
    <button @click="changeHandle">change父组件的值</button>
  </div>
</template>
<script>
export default {
  props: { 
    msg: { 
      type: String,
      default: '',
    },
  },
  methods:{
    changeHandle(){
      this.$emit("changeParent","我是子组件的值")
    }
  }
}
</script>


# App.vue (父组件)
<template>
  <div id="app">
    <Child @changeParent="getChildData" :msg="messsage"/>
  </div>
</template>
<script>
import Child from './components/Child'
export default {
  name: 'app',
  components: {
    Child
  },
  data(){
    return{
      messsage:'我是父组件的数据',
    }
  },
  methods:{
    getChildData(params){
      this.messsage = params;
    }
  }
}
</script>

父组件通过($children) 获取子组件的值

# App.vue (父组件)
<template>
  <div id="app">
    <h1>{{messsage}}</h1>
    <Child :msg="messsage"/>
    <!-- <Other :msg="messsage"/> -->
    <p>{{leader}}</p>
  </div>
</template>
<script>
import Child from './components/Child'
// import Other from './components/Other'
export default {
  name: 'app',
  components: {
    Child,
    // Other,
  },
  data(){
    return{
      messsage:'我是父组件的数据',
      leader:'',
    }
  },
  mounted(){
    this.$children.map(res=>{
      console.log(res)
     this.leader = res.miss
    })
  }
}
</script>

# Child.vue(子组件1)
<template>
  <div>
    <Other/>
    <button @click="changeHandle">change父组件的值</button>
  </div>
</template>
<script>
import Other from './Other'
export default {
  components:{
    Other,
  },
  props: { 
    msg: { 
      type: String,
      default: '',
    },
  },
  data(){
    return{
      message:"我是子组件的值",
      miss:'我是Child'
    }
  },
  methods:{
    changeHandle(){
      this.message = "hello"
    }
  }
}
</script>

# Other.vue(子组件2)
<template>
  <div>
    <h3>我是other</h3>
  </div>
</template>

<script>
  export default {
    data(){
      return{
        miss:'我是other组件'
      }
    }
  }
</script>

响应动态数据的变化

# App.vue (父组件)
<template>
  <div id="app">
    <Child :msg="Arr" />
    <button @click="changeHandle">点击改变子组件中渲染的值 </button>
  </div>
</template>
<script>
import Child from './components/Child'

export default {
  name: 'app',
  components: {
    Child,
  },
  data() {
    return {
      messsage: '我是父组件的数据',
      num: 1,
      Arr:[1,2,3,4],
    }
  },
  methods: {
    changeHandle() {
      this.$set(this.Arr,2,{a:1})
    }
  }
}
</script>


# Child.vue (子组件)
<template>
  <div>
    <ul>
      <li v-for="(item,index) in msg" :key="index">{{item}}</li>
    </ul>
  </div>
</template>
<script>
export default {
  props: { 
    msg: { 
      type: Array,
      default: ()=>[],
    },
  },
  // 这个版本现在不需要作监听也能响应父组件动态数据的变化了(以前是不行的)
  watch:{ 
    msg(oldValue,newValue){
      console.log(newValue);
    }
  },
  data(){
    return{
      message:"我是子组件的值",
    }
  },
  methods:{
    changeHandle(){
      
    }
  }
}
</script>

一种无依赖的组件通信:provide / inject 接口

# App.vue
<template>
  <div>
    app
    <Brother />
    <Child />
  </div>
</template>
<script>
import Brother from './components/Brother'
import Child from './components/Child'
export default {
  components: {
    Brother,
    Child,
  },
  provide: {
    name: 'App父组件的值'
  },
  data() {
    return {

    }
  }
}
</script>

<style scoped>
</style>


# Child.vue

<template>
  <div>
    Child组件
    {{name}}
  </div>
</template>

<script>
  export default {
    inject: ['name'],
    data(){
      return{

      }
    }
  }
</script>

<style scoped>

</style>


# Brother.vue

<template>
  <div>
    兄弟组件
    {{this.name}}
    <Child/>
  </div>
</template>

<script>
import Child from "./Child";
  
export default {
   components:{
      Child
    },
  data() {
    return {
      msg:'',
    }
  },
  inject: ['name'],
}
</script>

<style scoped>
</style>

Vue 官方提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的

通过 $refs 获取子组件的值

此方法只能获取值,不能响应数据变化

# App.vue
<template>
  <div>
    <Brother ref="brother"/>
    {{myda}}
  </div>
</template>
<script>
import Brother from './components/Brother'

export default {
  components: {
    Brother,
  },
  data(){
   return{
      myda:"",
   }
  },
  mounted(){
    this.myda = this.$refs.brother.msg
  },
}
</script>

# Brother.vue
<template>
  <div>
    兄弟组件
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg:'我是Brother组件',
    }
  }
}
</script>

兄弟组件通信(同样适用于跨级组件通信)

//*事件总线
var bus=new Vue();

// 还是利用 $on 和 $emit 的监听和发射
var app=new Vue({
    el:'#app',
    template:`
    <div>
        <A1></A1>
        <A2></A2>
    </div>
`
})

// 在组件 A1 的 methods 方法中触发事件
bus.$emit('say-hello', 'world')

// 在组件 A2 的 created 钩子函数中监听事件
bus.$on('say-hello', function (arg) {
  console.log('hello ' + arg);          // hello world
})



插槽 .... 略过,已经写过如何使用!
相关标签: 组件通信