preface

There are different operations in a page, and each operation corresponds to opening a popover. For example, in a project I did as an intern, there were 10 operations corresponding to 10 different popover. Therefore, based on the principle of code reuse, we need to reuse popover

Component registration (local registration)

  • Official article – Component Basics
  • Official article – Component registration

Vue + Webpack project for javascript-based modular system, component registration :(or custom component)

  • component-one.vue
<template>
  <div>.</div>
</template>
Copy the code
  • index.vue
<template>
  <component-one></component-one>
</template>
<script>
  import ComponentOne from './component-one.vue'
  export default{
    components: {
      ComponentOne
    }
  }
</script>
Copy the code

Pay attention to is

  1. A component is a reusable Vue instance, with options like Data, Methods, computed, watch, and so on, but no options specific to a root instance like EL;

  2. Where data must be a function that returns the data option written to the instance created by the component. Because every time a component is used, a new instance is created; Each time the component is used, a copy of data is maintained independently. Data maintained by other instances cannot be affected by data modified by one instance

  3. Each component must have one and only one root element, such as wrapping the child elements with a template

Global registration

Some components that can be used in many pages are called “base components.” “Base components” like this should be registered globally, not imported and registered with Component every time they are used:

  • dialog.vue
<div>
  <el-dialog>
    <div>
      <! -- Custom tag in parent component -->
      <slot></slot>
    </div>
  </el-dialog>
</div>
<script>
  export default {
    name: 'comDialog'.// Name is the component name, which is required for global registration
    props: {
      dialogList: Object}},</script>
Copy the code
  • main.js
/** * require. Context () File directory * parameters 2. Whether to find subsets * parameters 3. Search rules */
const requireComponent = require.context('/'.true./\.vue$/)
const install = (Vue) = > {
  if (install.installed) return // Return if the component is registered, register if it is not
  install.installed = true
  requireComponent.keys().forEach(filename= > { / / filename file
    const config = requireComponent(filename) // the ith component
    const componentName = config.default.name / / component name
    Vue.component(componentName, config.default || config) // Loop to register components
  })
}

Vue.use(install)
Copy the code
  • Can be used directly on any page:
<com-dialog></com-dialog>
Copy the code

Parameter transfer between parent and child components

The father the son –props

  • index.vue
<template>
  <component-one :prop1="value1" :prop2="value2"></component-one>
</template>
<script>
  import ComponentOne from './component-one.vue'
  export default{
    components: {
      ComponentOne
    },
    data: {
      value1:... .value2:... ,}}</script>
Copy the code
  • component-one.vue
<template>
  <div>{{prop1}}</div>
  <div>{{prop2}}</div>
</template>
<script>
  export default{
    props: {
      prop1: { type:... .default:... },
      prop2: { type:... .default:... }}},</script>
Copy the code

Parent – childemit

  • component-one.vue
<template>
  <div @click="goBacktoIndex">{{value1}}</div>
  <div>{{value2}}</div>
</template>
<script>
  export default{
    props: {
      prop1: { type:... .default:... },
      prop2: { type:... .default:... }},methods: {goBacktoIndex(){
        this.emit("fromComponentOne",params)
      }
    }
  }
</script>
Copy the code
  • index.vue
<script>
  export default{
    methods: {fromComponentOne(res){
        console.log(res) // the res value is the params value in component-one.vue}}}</script>
Copy the code

Whether a child component needs to be refreshed every time it is opened

  • Need to refresh

Method one:

<component-one v-if="showComponentOne"></component-one>
Copy the code

Method 2:

<component-one v-show="showComponentOne" :key="key"></component-one>
Copy the code
key = MathThe random () or key =new Date().getTime()
Copy the code
  • No need to refresh
<component-one v-show="showComponentOne"></component-one>
Copy the code

Whether or not a refresh will trigger life cycle functions such as created and Mounted

Modify the contents of the child – slot – in the parent component

For example, if you want to customize the contents of a template component from a component library, you need slots:

Official article – slot

Base – layout. Vue subcomponents

<div class="container"> 
  <header> <! -- Want to customize header content here --> </header>
  <main> <! -- Want to customize main content here --> </main>
  <footer> <! -- Want to customize footer content here --> </footer>
</div>
Copy the code

The solution for Vue 3.0 is:

Vue3.0 provides slot elements, named slots with the name attribute and anonymous slots without the name attribute, to specify where custom content in the parent component should be placed.

Add slot elements to base-layout.vue child components

<div class="container">
  <header>
    <slot name="header"></slot> <! -- named slot -->
  </header>
  <main>
    <slot></slot> <! -- Anonymous slot -->
  </main>
  <footer>
    <slot name="footer"></slot> <! -- named slot -->
  </footer>
</div>
Copy the code
  • The named slot locks the custom content location based on the value of name
  • Anonymous slots “accept” any custom content that does not specify a name value

The index.vue parent wraps custom content with < Template V-slot: slot name >

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p> <! Not wrapped by <template v-slot: slot name >, accepted by anonymous slot -->

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
Copy the code

Final render result (slot elements replaced with custom content)

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>
Copy the code

The parent component can use the child component’s data in the slot area – the scope slot

Current – the user. The vue subcomponents

<span>
  <slot name="userName">{{ user.lastName }}</slot>
</span>
Copy the code

Vue parent, we want to replace user.lastName with user.firstname

<current-user>
  <template v-slot:userName>
    {{ user.firstName }}
  </template>
</current-user>
Copy the code

But this doesn’t work because the data user can only be accessed in child components. The solution is:

  1. Use V-bind to bind user data in the child component
<span>
  <slot :user="user">{{ user.lastName }}</slot>
</span>
Copy the code
  1. Create a name slotProps in the parent component and use slotProps. User to access user data in the child component
<current-user>
  <template v-slot:userName="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>
Copy the code

V-slot can be shortened to # (v-bind to:, v-on to @)

Alternatively, you can dynamically bind slot names:

<base-layout>
  <template v-slot:[dynamicSlotName] >.</template>
</base-layout>
Copy the code

Vue 2.0 processing method:

  • The slot property is used as a named slot
<base-layout>
  <h1 slot="header">Here might be a page title</h1> <! -- named slot -->

  <p>A paragraph for the main content.</p> <! -- Anonymous slot -->
  <p>And another one.</p>

  <p slot="footer">Here's some contact info</p> <! -- named slot -->
</base-layout>
Copy the code

The difference between this and Vue3.0 is that custom content does not need to be wrapped with < Template V-slot: slot name >. Instead, slot attributes are added directly to the custom content component

  • The slot-scope property acts as a scope slot
<slot-example>
  <span slot="default" slot-scope="slotProps">
    {{ slotProps.msg }}
  </span>
</slot-example>
Copy the code

The difference between this and Vue3.0 is that custom content does not have to be wrapped around

<slot-example>
  <span slot="default" slot-scope="{ msg }">
    {{ msg }}
  </span>
</slot-example>
Copy the code

Refer to the article

  • Vue component global registration and local registration are used