美文网首页
77.vue的属性透传 && 两个component接收同样的p

77.vue的属性透传 && 两个component接收同样的p

作者: yaoyao妖妖 | 来源:发表于2020-10-15 09:31 被阅读0次
    1. 如何实现组件的属性透传

    场景: 封装 Element-ui组件,从封装组件外部向 Element-ui 组件传值

    <!-- Input 组件 -->
    <template>
      <div>
        <el-input v-bind="$attrs" @input="hInput" v-model="myc"></el-input>
        {{myc}}
      </div>
    </template>
    

    从外部给 el-input 传值

    <template>
      <div class="hello">
        <!-- 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。 -->
        <!-- 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。 -->
        <!-- 为了能让孙组件能够将事件 emit 出去,这里使用了v-on="$listeners" -->
        <!-- 注意这里可能会有很多的属性,为了能够透传,我们可以直接使用 v-bind="$attrs" -->
        <Input placeholder="我是默认值" :clearable="true" v-on="$listeners"/>
      </div>
    </template>
    
    2. 动态组件的属性透传 渲染函数

    // 父组件 home.vue

    <template>
      <div class="home">
        <!-- <img alt="Vue logo" src="../assets/logo.png"> -->
        <HelloWorld :configJsonArr="configJson"/>
      </div>
    </template>
    
    <script>
    // @ is an alias to /src
    import HelloWorld from '@/components/Config.vue'
    
    export default {
      name: 'Home',
      components: {
        HelloWorld
      },
      data () {
        return {
          configJson: [{
            type: 'Input',
            props: {
              placeholder: '我是默认值',
              clearable: true
            }
          }, {
            type: 'Select',
            props: {
              placeholder: '我是默认值'
            }
          }, {
            type: 'Input',
            props: {
              placeholder: '我是默认值',
              suffixIcon: 'el-icon-delete'
            }
          }]
        }
      }
    }
    </script>
    

    Config.vue

    <template>
      <div class="hello">
        <div v-for="(config, index) in configJsonArr" :key="config.type + index">
          <!-- <component :is="config.type" :configProps="config.props"></component> -->
          <comp-form-item :configJson="config"></comp-form-item>
        </div>
      </div>
    </template>
    
    <script>
    import Input from './Input'
    import Select from './Select'
    
    const CompFormItem = {
      components: {
        Input, Select
      },
      name: 'FormItem',
      props: {
        configJson: {
          required: true
        }
      },
      render (h) {
        return h(`${this.configJson.type}`, {
          props: {
            ...this.configJson.props || {}
          },
          attrs: {
            ...this.configJson.props || {}
          }
        })
      }
    }
    
    export default {
      name: 'Config',
      components: {
        // Input,
        // Select,
        CompFormItem
      },
      props: {
        configJsonArr: {
          type: Array,
          required: true,
          default: () => []
        }
      }
    }
    </script>
    

    Input 组件

    <template>
      <div class="hello input-con">
        <label>输入框:</label>
        <el-input v-bind="$attrs"></el-input>
      </div>
    </template>
    
    <script>
    export default {
      name: 'Input'
    }
    </script>
    
    

    Select 组件

    <template>
      <div class="hello select-con">
        <label>选择框:</label>
        <el-select v-bind="$attrs" v-model="value"></el-select>
      </div>
    </template>
    
    <script>
    export default {
      name: 'Select',
      data () {
        return {
          value: ''
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang="scss">
    .select-con {
      margin: 20px;
      display: flex;
      align-items: center;
      label {
        width: 170px;
      }
    }
    </style>
    
    1. 要求组件 B 和组件 C 接受同样的的 props,其中 B 组件写法如下
    <template>
      <child-component v-bind="$props"/>
    </template>
    
    <script>
      import ChildComponent from '@/components/ChildComponent'
      
      export default {
        props:{
          ...ChildComponent.options.props
        }
      }
    </script>
    

    来自:https://juejin.im/post/6865451649817640968
    文档:
    https://www.jianshu.com/p/7508d2a114d3

    相关文章

      网友评论

          本文标题:77.vue的属性透传 && 两个component接收同样的p

          本文链接:https://www.haomeiwen.com/subject/qqxwpktx.html