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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36407748/article/details/87881880

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

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
})



插槽 .... 略过,已经写过如何使用!

猜你喜欢

转载自blog.csdn.net/qq_36407748/article/details/87881880