vue 组件传值


Vue 组件传值

一. 父子组件传值

步骤: 1. 在子组件标签中通过v-bind把自定义属性赋值为父组件的动态数据 ? ? 2. 在子组件对象中通过props字段添加自定义属性 ? props: ["myData"] ? 3, 在子组件模板中, 使用自定义属性渲染数据 ?  {{myData}} 

<body>
   <script src='vue.js'>script>
   
   <div id='myApp'>
      父组件中的输入:
       <input type="text" v-model="name"> <br>
       <hr>
      子组件的显示:
       <my-com :my-data="name">my-com>
   div>
   
   <template id='com'>
       <span>
          {{myData}}
       span>
   template>  
   <script>
       // 组件
       Vue.component('myCom',{
           template: '#com',
           // 使用props字段添加自定义属性,用于接收父组件传值, 值是数组结构
           props: ["myData"],
           // created() {
           //     console.log(this.myData)
           // },
           // watch:{
           //     myData(newValue){console.log(newValue)}
           // },
           // computed:{ }
      })
       // 根组件
       var vm = new Vue({
           el: '#myApp',
           data: {
               name: "张三"
          }
      })
       // 总结: 父组件向子组件传值步骤:
       // 1, 在子组件对象中通过props字段添加自定义属性
           // props: ["myData"]
       // 2, 在子组件标签中通过v-bind把自定义属性赋值为父组件的动态数据
           //
       // 3, 在子组件模板中, 使用自定义属性渲染数据
           // {{myData}}
   script>

二 . 子传父

<body>
   <script src='vue.js'>script>
   
   <div id='myApp'>
       
       <my-com @myevent="getData">my-com> <hr>
      父组件显示: {{fatherData}}
   div>
   
   <template id='com'>
       <div>
          子组件输入: <input type="text" v-model="childData">
       div>
   template>
   <script>
       // 组件
       Vue.component('myCom',{
           template: '#com',
           data(){
               return{
                   childData: "child"
              }
          },
           watch:{
               childData(newValue){
                   // 监听到子组件数据更新时,把新数据发送给父组件
                   // 原理: 子组件调用$emit函数发射一个自定义事件, 在父组件中监听事件并在事件函数中取值
                   this.$emit("myevent", newValue)
                   // 参数一是自定义事件名, 事件名必须用小写
                   // 参数二是发送的数据
              }
          }
      })
       // 根组件
       var vm = new Vue({
           el: '#myApp',
           data: {
               fatherData:""
          },
           methods: {
               //在父组件的事件函数中拿到参数中的数据并展示
               getData(data){
                   this.fatherData = data
              }
          }
      })
       // 总结: 子组件向父组件传值的步骤:
       // 1, 在子组件中合适的位置, 通过$emit函数发射自定义事件,把数据发出去
           // this.$emit("myevent", newValue)
       // 2, 在子组件标签上, 通过v-on绑定自定义事件,调用父组件中的事件函数
           //
       // 3, 在父组件的事件函数中拿到参数中的数据并展示
           // getData(data){ this.fatherData = data }
   script>
body>

三 . 非父子组件传值

 <script src='vue.js'>script>
   
   <div id='myApp'>
       <my-com1>my-com1>
       <my-com2>my-com2>
   div>
   
   <template id='com1'>
       <div>
          组件1输入 : <input type="text" v-model="name">
       div>
   template>
   <template id='com2'>
       <div>
          组件2显示 : {{name2}}
       div>
   template>
   <script>
?
       // 总线: 在全局作用域创建一个空的vue对象,视作总线.用于非父子传值
       var bus = new Vue();
?
       // 组件1
       Vue.component('myCom1',{
           template: '#com1',
           data(){
               return{
                   name:"张三"
              }
          },
           watch: {
               name(value){
                   // 调用$emit自定义事件把数据发出去
                   // this.$emit()
                   // 使用bus总线调用$emit发送数据
                   bus.$emit("myevent", value)
                   console.log("发送")
              }
          }
      })
       // 组件2
       Vue.component('myCom2',{
           template: '#com2',
           data(){
               return{
                   name2: ""
              }
          },
           created() {
               console.log(this)
               // 在另一个组件的初始化函数created中使用bus总线监听自定义事件,取值
               // bus.$on("myevent", function(data){
               //     // 在事件函数中this指向事件目标bus, 不是当前组件com2
               //     console.log("接收",data, this)
               //     this.name2 = data
               // })
               // 使用箭头函数保证函数中的this和函数外的this保持一致为com2
               bus.$on("myevent", (data)=>{
                   // 在事件函数中this指向事件目标bus, 不是当前组件com2
                   console.log("接收",data, this)
                   this.name2 = data
              })
?
               // 注意: 每一个组件对象中都有属性 _uid 它是一个索引值, 记录的是这个组件创建的顺序(第一个创建的组件,_uid是0, 往后依次增加)
          },
      })
       // 根组件
       var vm = new Vue({
           el: '#myApp',
           data: {
          },
           methods: {
          }
      })
   
       // 总结: 非父子组件传值/兄弟组件传值/bus总线传值  
       // 1, 在全局作用域中创建空的vue对象, 称之为总线bus
           // var bus = new Vue();
       // 2, 在一个组件中合适的位置,通过bus总线调用$emit发送数据
           // bus.$emit("myevent", value)
       // 3, 在另一个组件中的初始化函数created中,使用bus总线监听事件, 接收数据并展示
           // bus.$on("myevent", (data)=>{ this.name2 = data })
          script>
?

四 . 插槽传值

 <script src='vue.js'>script>
   
   <div id='myApp'>
      父组件输入:                          
       <input type="text" v-model="name"> <hr>
       <my-com>默认在组件标签之间的信息会被忽略my-com>
       
       <my-com>{{name}}my-com>
   div>
   
   <template id='com'>
       <div>
           
          子组件显示: <slot>slot>
       div>
   template>
   <script>
       // 组件
       Vue.component('myCom',{
           template: '#com',
           created() {
               // 在组件对象中拿不到插槽数据
          },
      })
       // 根组件
       var vm = new Vue({
           el: '#myApp',
           data: {
               name: "张三"
          }
      })

 

五 . 具名插槽


   <script src='vue.js'>script>
   
   <div id='myApp'>
       <my-com>父组件动态数据my-com> <hr>
       <my-com>
           <span slot="s1">父组件数据1span>
           <span slot="s2">父组件数据3span>
       my-com>
   div>
   
   <template id='com'>
       <div>
           
           
?
           
           
           <slot name="s1">slot> <br>
          子组件数据2 <br>
           <slot name="s2">slot>
       div>
   template>
   <script>
       // 组件
       Vue.component('myCom',{
           template: '#com'
      })
       // 根组件
       var vm = new Vue({
           el: '#myApp'
      })
       // 总结: 插槽的用法
       // 1, 子组件模板中slot标签如果没有name属性会把插槽数据全部渲染
       // 2, slot标签添加name属性后,只会渲染插槽数据中拥有slot属性且name属性和slot属性值相同的数据
   script>

 

 

vue