$listeners and $attrs

This thing is for the parent and child components deeply nested for the convenience of value specific: juejin.cn/post/684490…

Can’t read emMM… Go to the official website (cn.vuejs.org/v2/api/#vm-…)

Select a component library (Vant as an example)

website

Youzan. Making. IO/vant / # / useful – C…

The installation

Install via NPM
npm i vant -S

# Install using YARN
yarn add vant
Copy the code

reference

// Import Vant from globally'vant'Vue. Use (Vant) // Go to the official website on demandCopy the code

Select a component to encapsulate (for example, van-List)

Create a new vue file to encapsulate van-list components

<! --test-list.vue--> <template> <van-list v-on="$listeners" :offset="1" v-bind="$attrs">
      <slot></slot>
    </van-list>
</template>
<script>
export default {
  
};
</script>
Copy the code

Build a VUE file that calls this wrapper component

<! --listeners-attrs.vue--> <template> <test-list v-model='loading' :finished='finished' loading-text="Loading"></test-list>
</template>
<script>
import TestList from "./test"
export default {
    components:{TestList},
    data:function() {return {
            finished:false,
            loading:false}}}; </script>Copy the code

In this way, third-party component libraries can be rewrapped without additional parent values (the V-Model is a special case)

Van-list’s V-model is special

<test-list == V-model =’loading’== :finished=’finished’ loading-text=” loading “> When van-list’s V-model is used directly in the encapsulated component, component co-failure occurs. If loading is not effective and the function of the whole component becomes invalid, we try to put this property into the original component and pass it to the parent component in other ways

* The first option
<! --test-list.vue--> <template> <van-list v-model='loading'  v-on="$listeners" :offset="1" v-bind="$attrs">
      <slot></slot>
    </van-list>
</template>
<script>
export default {
  props:{
    value:{
      type:Boolean
    }
  },
  model:{
      prop:'value',
      event:'changeValue'
  },
  computed:{
      loading:{
          get() {return this.value
          },
          set(val){
              this.$emit('changeValue',val)
          }
      }
  }
};
</script>
Copy the code
<! -- Listeners -- attrs.vue code unchanged -->Copy the code
* The second option
<! --test-list.vue--> <template> <van-list v-model="value"  v-on="$listeners" :offset="1" v-bind="$attrs" finished-text="-- no more --">
      <slot></slot>
    </van-list>
</template>
<script>
export default {
  data:function() {return {
      value:false
    }
  },
  props:{
    loading:{
      type:Boolean
    }
  },
  watch:{
    loading:function(val){
      this.value=val
    }
  }
};
</script>
Copy the code
<! --listeners-attrs.vue--> <template> <test-list :loading='loading' :finished='finished' loading-text="Loading"></test-list>
</template>
<script>
import TestList from "./test"
export default {
    components:{TestList},
    data:function() {return {
            finished:false,
            loading:false}}}; </script>Copy the code