The use of Slot in Vue can also realize the communication between parent and child components

preface

Slots can be said to be a very important part of Vue. In the process of my study and practice, when components are used together with slots, they will play a better role. More time will be more convenient.

Today, let's introduce three kinds of slots in Vue: default slot, named slot and scope slot.

Environmental preparation

Let's set up an initial environment to show you. Finish this slot step by step.

Is to write a category component to render the three kinds of data respectively.

Category component

<template>
  <div class="category">
    <h1>{{title}}</h1>
    <ul>
      <li 
      v-for="(item,index) in listData"
      :key="index">{{item}}</li>
    </ul>
  </div>
</template>
<script>
export default {
  props: {
    listData:Array,
    title: String
  }
}
</script>
<style scoped>
.category{
  width: 200px;
  height: 300px;
  background-color:pink;
}
</style>

App components

<template>
  <div id="app">
    <Category :listData="games" :title="'Games'" />
    <Category :listData="movies" :title="'Movies'" />
    <Category :listData="foods" :title="'Foods'" />
  </div>
</template>
<script>
import Category from './components/Category.vue'
export default {
  name: 'App',
  components: {
    Category
  },
  data () {
    return {
      games:['Cross Fire','qq Flying car','Roco Kingdom '],
      movies:['Hello, Li Huanying','Youth school','Fleet of Time'],
      foods:['Shaoyang rice noodles','Changsha chayan','Chongqing hotpot']
    }
  }
}
</script>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  display: flex;
  justify-content: space-between;
}
</style>

At first, the demand is the same as the above figure, but now the business demand has changed. The film has only publicized one of them, the others do not publicize, and the food has only publicized one.

As shown below:

How can we change it?

Do you want to add if one by one to the Category component for judgment? Or is there a better way???

It's not good to judge one by one. In that case, the code will become very complicated and difficult to read. In case of changing business requirements in the future, the code will be difficult to move.

Next, go to the default slot.

1, Default slot

We do not need props to receive data or render in the sub component, but define a slot.

<template>
<div class="category">
    <!-- Define the slot and the default content of the slot -->
    <slot>If the parent component does not pass a value, this default is displayed</slot>
    </div>
</template>
<script>
    export default {
        props: {
        }
    }
</script>

App components have also changed

<template>
<div id="app">
    <Category>
        <h1>Games</h1>
        <!-- <ul>
<li v-for="(item, index) in games" :key="index">{{ item }}</li>
    </ul> -->
        <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fb352264fa7bfdb6d211f2e71e87cc2c48d85b805.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931135&t=0b2c6c622c84a1e387196cce8f50455e">
    </Category>
    
    <Category>
        <h1>Movies</h1>
        <img class="movies" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13236694597%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931502&t=f89c2197bda9bb129d9404d3c4b30f2f">
        <!-- <ul> -->
        <!-- <li v-for="(item, index) in movies" :key="index">{{ item }}</li> -->
        <!-- </ul> -->
    </Category>
    <Category>
        <h1>Foods</h1>
        <ul>
            <li v-for="(item, index) in foods" :key="index">{{ item }}</li>
    </ul>
    </Category>
    
    <!-- When we don't write anything, see what to show -->
    <Category>
    </Category>
    </div>
</template>

<script>
    import Category from './components/Category.vue'

    export default {
        name: 'App',
        components: {
            Category
        },
        data () {
            return {
                games:['Cross Fire','qq Flying car','Roco Kingdom '],
                movies:['Hello, Li Huanying','Youth school','Fleet of Time'],
                foods:['Shaoyang rice noodles','Changsha chayan','Chongqing hotpot']
            }
        }
    }
</script>

Display effect:

Explanation:

We wrote a < slot > in the child component. If the parent component does not pass the value, the default < / slot > tag will be displayed. This is equivalent to occupying a position.

In the parent component, we no longer write autistic and labels as before, but write non autistic and label < category > content < / category >. In this way, Vue will render the content written in the component label by default, and then put it back where the < slot > < / slot > takes a good place in the sub component.

Note: CSS style can be written in the parent component or child component, because it is put back into the child component after rendering. When it is written in a sub component, it is rendered when it is put back in the sub component.

After writing here, the customer suddenly feels that you are so powerful and dissatisfied, and starts to give you a moth again.

Then we will go to the named slot again.

2, Named slot

We can even think of using one slot, so why can't we think of using two slots to try?

Retrofit subassembly

<template>
  <div class="category">
    <!-- You must add a name in the parent component to specify which slot to put in, which is why it is called a named slot--->
    <slot name="slot1">If the parent component does not pass a value, this default is displayed</slot>
    <slot name="slot2"></slot>
  </div>
</template>
<script>
export default {
  props: {
  }
}
</script>

Parent component

<template>
	<div id="app">
    	<Category>
       	 <template slot="slot1">
          	  <h1>Games</h1>
            <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fb352264fa7bfdb6d211f2e71e87cc2c48d85b805.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931135&t=0b2c6c622c84a1e387196cce8f50455e"
                 />
	</template>
	<template slot="slot2">
		<button > qq Sign in</button>
		<button > Wechat login</button>
	</template>

</Category>
<Category>
    <template slot="slot1">
		<h1>Movies</h1>
			<img
     class="movies"
     src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13236694597%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931502&t=f89c2197bda9bb129d9404d3c4b30f2f"
     />
    </template>
    <template slot="slot2">
		<button > Click to buy tickets</button>
    </template>
</Category>

<Category>
    <template slot="slot1">
		<h1>Foods</h1>
		<ul>
    		<li v-for="(item, index) in foods" :key="index">{{ item }}</li>
        </ul>
    </template>
</Category>

<!-- When we don't write anything, see what to show -->
<Category> </Category>
</div>
</template>

<script>
    import Category from './components/Category.vue'

    export default {
        name: 'App',
        components: {
            Category
        },
        data () {
            return {
                games:['Cross Fire','qq Flying car','Roco Kingdom '],
                movies:['Hello, Li Huanying','Youth school','Fleet of Time'],
                foods:['Shaoyang rice noodles','Changsha chayan','Chongqing hotpot']
            }
        }
    }
</script>

Effect display

Explanation:

We can put multiple slots in the component, but when there are multiple slots, they must be named. In addition, they must also be specified in the parent component, so as not to fail to put them in.

3, Scope slot

The scope slot is slightly different from the previous one. In the past, the data is in the parent component, while the scope slot is that the data is in the child component, which in turn is passed to the parent component to enable the parent component to define the structure for rendering.

Modified sub assembly

<template>
  <div class="category">
    <slot name="slot1">If the parent component does not pass a value, this default is displayed</slot>
    <slot name="slot2" :foods="foods">If the parent component does not pass a value, this default is displayed</slot>
  </div>
</template>
<script>
export default {
  data () {
    return{
      foods:['Shaoyang rice noodles','Changsha chayan','Chongqing hotpot']
    }
  }
}
</script>

Parent component

<template>
  <div id="app">
    <Category>
      <template slot="slot1">
        <h1>Foods</h1>
      </template>
      <template slot="slot2" scope="listData">
        <!--If you don't know, we can output it and see what it is· {{listData}}  -->
        <ul>
          <li v-for="(item, index) in listData.foods" :key="index">
            {{ item }}
          </li>
        </ul>
      </template>
    </Category>
    <Category>
      <template slot="slot1">
        <h1>Foods</h1>
      </template>
      <template slot="slot2" scope="listData">
        <ol>
          <li v-for="(item, index) in listData.foods" :key="index">
            {{ item }}
          </li>
        </ol>
      </template>
    </Category>
    <Category>
      <template slot="slot1">
        <h1>Foods</h1>
      </template>
      <template slot="slot2" scope="listData">
          <h4 v-for="(item, index) in listData.foods" :key="index">
            {{ item }}
          </h4>
      </template>
    </Category>
    <Category>
      <template slot="slot1" scope="listData">	
{{listData}}
      </template>
    </Category>
  </div>
</template>

<script>
import Category from './components/Category.vue'

export default {
  name: 'App',
  components: {
    Category
  }
}
</script>

design sketch

During my study and practice, I didn't think of any usage scenarios, but there are cases on the official website. I think it must exist for a reason, but I have too little knowledge to use it.

Explanation:

The child component passes the value to the parent component through the variable name = "defined data", and the parent component receives it with < template slot = "slot2" scope = "not the same as the name passed by the child component" > because it needs another layer to arrive

<template slot="slot2" scope="listData">
<!--If you don't know, we can output it and see what it is· {{listData}}  -->
<ul>
    <li v-for="(item, index) in listData.foods" :key="index">
        {{ item }}
    </li>
    </ul>
</template>

Post language

Let's cheer together!!! If there are any deficiencies in the article, please point out them in time. Thank you very much.

I feel shallow on paper. I absolutely know that I have to practice it.

Hello, I'm blogger Ning Zaichun: homepage

A young man who likes literature and art but embarks on the road of programming.

Hope: when we meet on another day, we have achieved something.

Tags: Vue.js bcc

Posted on Mon, 22 Nov 2021 02:10:13 -0500 by bigphpn00b