vue 插槽slot与provide/inject跨组件传值

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

vue 插槽slot

1. 默认插槽

const component = {
  template: `
    <div :style="style">
      <slot></slot>
    </div>
  `,
  data () {
    return {
      style: {
        width: '200px',height: '100px',border: '1px solid #aaa'
      }
    }
  }
}

new Vue({
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  template: `
  <div>
  <comp>
    <span>I am slot</span>
  </comp>
  </div>
  `,
  components: {Comp: component}
})
*/

这里写图片描述

2. 具名插槽

const component = {
  template: `
    <div :style="style">
      <div class="header">
        <slot name="header"></slot>
      </div>
      <div class="body">
        <slot name="body"></slot>
      </div>
      <div>common footer</div>
    </div>
  `,
  data () {
    return {
      style: {
        width: '200px',height: '100px',border: '1px solid #aaa'
      }
    }
  }
}

new Vue({
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  template: `
  <div>
  <comp>
    <span slot="header">I am header</span>
    <span slot="body">I am body</span>
  </comp>
  </div>
  `,
  components: {Comp: component}
})

这里写图片描述

3. 作用域插槽

const component = {
  template: `
    <div :style="style">
      <slot :value="value" abc="111"></slot>
    </div>
  `,
  data () {
    return {
      style: {
        width: '200px',height: '100px',border: '1px solid #aaa'
      },
      value: '456'
    }
  }
}

new Vue({
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  template: `
  <div>
  <comp ref="comp">
    <span slot-scope="pp" ref="span">{{pp.value}} {{pp.abc}}</span>
  </comp>
  </div>
  `,
  mounted () {
    console.log(this.$refs.comp) // VueComponent对象
    console.log(this.$refs.comp.value) // 456
    console.log(this.$refs.span) // span节点
  },
  components: {Comp: component}
})

这里写图片描述

4.inject provide 子孙组件(跨组件)传值

onst ChildComp = {
  template: `<div>
    <span>child component</span>
    <span> {{value}}</span>
  </div>`,
  inject: ['grandParent', 'value'],
  mounted () {
    console.log(this.$parent.$options.name) // Vue 对象
    console.log(this.grandParent, this.value) // '123'
  }
}

const component = {
  name: 'comp',
  components: {
    ChildComp
  },
  template: `
    <div>
      <slot :value="value" abc="111"></slot>
      <child-comp></child-comp>
    </div>
  `,
  data () {
    return {
      value: 'component value'
    }
  }
}

new Vue({
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  provide () {
    return {
      grandParent: this,
      value: this.value
    }
  },
  template: `
  <div>
  <comp ref="comp">
    <span slot-scope="pp" ref="span">{{pp.value}} {{pp.abc}} {{value}}</span>
  </comp>
  <input v-model="value" >
  </div>
  `,
  components: {Comp: component}
})

这里写图片描述
根组件input用v-model更改value,并不会导致孙组件ChildComp的value值实时更改

5.跨组件的数据绑定

在跟组件的provide中,使用defineProperty,getter获取value,这样孙组件ChildComp就能实时获取到根组件的value,达到v-model的效果

const ChildComp = {
  template: `<div>
    <span>child component : </span>
    <span> {{data.value}}</span>
  </div>`,
  inject: ['grandParent', 'data']
}

const component = {
  name: 'comp',
  components: {
    ChildComp
  },
  template: `
    <div>
      <slot :value="value" abc="111"></slot>
      <child-comp></child-comp>
    </div>
  `,
  data () {
    return {
      value: 'component value'
    }
  }
}

new Vue({
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  provide () {
    const data = {}
    Object.defineProperty(data, 'value', {
      get: () => this.value,
      enumerable: true
    })
    return {
      grandParent: this,
      data
    }
  },
  template: `
  <div>
  <comp ref="comp">
    <span slot-scope="pp" ref="span">{{pp.value}} {{pp.abc}} {{value}}</span>
  </comp>
  <input v-model="value" >
  </div>
  `,
  mounted () {
  },
  components: {Comp: component}
})

这里写图片描述

猜你喜欢

转载自blog.csdn.net/m0_37068028/article/details/79828360