119. Slot, mixin, global event bus

Keywords: Javascript Front-end Vue.js

1. Slot

1. Default slot

Components that encapsulate slots

 <ul>
       <li>{{ title }}</li>
       <slot></slot> 
 </ul>

Implementer of slot

 <Com title="game">
      <ul>
          <li>Zhang San</li>
          <li>Li Si</li>
          <li>Wang Wu</li>
     </ul>
  </Com>
  
  import Com from './components/com.vue'
  
  export default {
      components: {
        Com,
        ScopeSlot
      }
}

2. Named slot

Components that encapsulate slots

     <ul>
          <li>{{ title }}</li> 
          <slot name="img"></slot> 
          <slot name="video"></slot> 
      </ul>

Implementer of slot

 <Com title="game">
        <ul>
          <li>Zhang San</li>
          <li>Li Si</li>
          <li>Wang Wu</li>
          <img slot="img" src="https://img2.baidu.com/it/u=3666548066,2508071679&fm=26&fmt=auto" >
        </ul>
  </Com>
  <Com title="film">
        <ul>
          <li>Journey to the West Chapter 1</li>
          <li>Journey to the West Chapter 2</li>
          <li>Journey to the West Chapter 3</li>
          <li>Journey to the West Chapter 4</li>
          <div slot="video">
            <video controls src="https://vd2.bdstatic.com/mda-kj1ffr79xv2s9ykn/sc/mda-kj1ffr79xv2s9ykn.mp4?v_from_s=hkapp-haokan-hnb&auth_key=1638691138-0-0-03d64ba66ca007c414565c8fa2fd72a1&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest=17376_1-3000201_3&klogid=1738784889"></video>
          </div>
        </ul>
      </Com>
  
  import Com from './components/com.vue'
  
  export default {
      components: { 
        Com
      }
}

3. Scope slot

Components that encapsulate slots

 <ul>
    <li>{{ title }}</li>
    <slot :games="games"></slot>
  </ul>
  
export default {
  props: ['title'],
  data () {
    return {
      games: ['lol', 'FireWire', 'King', 'Wang Wu']
    }
  }
}}

Implementer of slot

 <ScopeSlot title="Scope slot" >
        <template slot-scope="{games}" >
          <ul>
            <li v-for="(item,index) in games" :key="index">
              {{ item }}
            </li>
          </ul>
        </template>
  </ScopeSlot>
      
import ScopeSlot from './components/scopeSlot.vue'
export default {
  components: { 
    ScopeSlot
  }
}

2.mixn

vue provides a hybrid mechanism - mixins, which is used to reuse component content more efficiently. Realize the reuse of function code

Directory structure:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-7otstecv-163870424563) (C: \ users \ Lenovo \ appdata \ roaming \ typora user images \ image-20211205192647727. PNG)]

mixin.js file

const mixin1 = {
  data () {
    return {
      currentTime: ''
    }
  },
  created () {
    setInterval(() => {
      this.currentTimes()
    }, 1000)
  },
  methods: {
    currentTimes () {
      let data = new Date()
      let yeth = data.getFullYear()
      let Mon = data.getMonth() + 1
      let date = data.getDate()
      let hours = data.getHours()
      let min = data.getMinutes()
      let s = data.getSeconds()
      let str = yeth + '-' + Mon + '-' + date + ' ' + hours + ':' + min + ':' + s
      this.currentTime = str
    }
  }
}
export {
  mixin1
}

zujian1

<template>
  <div>
      <h3>{{ title }}</h3>
      <h3> The current time is:{{ currentTime }} </h3>
  </div>
</template>

<script>
import { mixin1 } from './mixn'
export default {
  data () {
    return {
      title: 'Here is the data of component 1'
    }
  },
  mixins: [mixin1]
}
</script>
 

zujian2

<template>
  <div>
      <h3>{{ title }}</h3>
      <h3> The current time is:{{ currentTime }} </h3>
  </div>
</template>

<script>
import { mixin1 } from './mixn'
export default {
  data () {
    return {
      title: 'Here is the data of component 1'
    }
  },
  mixins: [mixin1]
}
</script>

index

<template>
  <el-card>
    <h1>Used here mixin</h1>
    <el-divider></el-divider>
    <Zujian1/>
    <Zujian2/>
  </el-card>
</template>

<script>
import Zujian1 from './components/zujian1.vue'
import Zujian2 from './components/zujian2.vue'
export default {
  components: {
    Zujian1,
    Zujian2
  },
  data () {
    return {
    }
  }
}
</script> 

Final effect drawing

3. Global event bus

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-VdY5dDrc-1638704245564)(C:\Users\Lenovo\Desktop08043-20200817210933683-1007105126.png)]

Communication mode props
Pass between father and son
The parent passes attributes to the child and passes the data to the child components through attributes
The child passes data to the parent. The child component passes the data to the parent component as a parameter by calling the behavior function of the parent component

Communication mode: global event bus (custom event is the basis of global event bus)

Relationship between vm object and component object
Prototype object of vm = = = prototype object of component object

Self defined events can complete the transfer between children and parents, because child components can be seen in parent components, events can be bound for child components, and events can be triggered in child components
However, if the child is not to the parent, there is no way for the rest, because the two components cannot see each other, and there is no way to bind one of them to the other

At this time, we can use the middleman, that is, the person they can see at the same time, that is, the global event bus (all component objects can see it)
In the component receiving data, get the bus binding event
In the component that sends data, get the bus trigger event

In the final analysis, the global event bus is an object. We usually use the vm object as the global event bus
Adding vm objects to Vue prototype objects forms a global event bus (vm)

directory structure

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ikfndl2n-1638704245565) (C: \ users \ Lenovo \ appdata \ roaming \ typora user images \ image-20211205193433410. PNG)]

main.js

Add Vue.prototype.$bus = this in beforeCreate

new Vue({
  el: '#app',
  router,
  store,
  beforeCreate () {
    Vue.prototype.$bus = this
  },
  components: { App },
  template: '<App/>'
})

both1

<template>
  <div class="wrap">
      <h1>Brother component 1 (sender of data)</h1>
      <el-button size="medua" @click="sendData" type="primary">send data</el-button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: 'Data sent by brother component 1'
    }
  },
  methods: {
    sendData () {
      this.$bus.$emit('busEv', this.msg)
    }
  },
  beforeDestroy () {
    this.$bus.$off('busEv')
  }
}
</script>

<style scoped>
.wrap{
    padding: 30px;
    background-color: greenyellow;
}
</style> 

both2

<template>
  <div class="wrap">
      <h1>Brother component 1 (receiver of data)</h1>
      <h1>The data received is:{{ getVal }}</h1>
  </div>
</template>

<script>
export default {
  data () {
    return {
      getVal: ''
    }
  },
  created () {
    this.$bus.$on('busEv', (params) => {
      this.getVal = params
    })
  }
}
</script>

<style scoped>
.wrap{
  background-color: hotpink;
  padding: 30px;
}
</style> 

index

<template>
  <el-card>
    <h1>Global event bus</h1>
    <el-divider></el-divider>
    <div class="father_com">
      <Both1/>
      <Both2/>
    </div>
  </el-card>
</template>

<script>
import Both1 from './components/both1.vue'
import Both2 from './components/both2.vue'
export default {
  components: {
    Both1,
    Both2
  }
}
</script>

<style scoped lang="less">
h1{
  text-align: center;
}
.father_com{
  display: flex;
  justify-content: flex-start;
  background-color: gray;
}
</style> 

Posted by nocniagenti on Sun, 05 Dec 2021 04:27:03 -0800