Vue3 reviews and summarizes component v-model parameters and dynamic component and Attribute inheritance

Vue3 reviews and summarizes component v-model parameters and dynamic component and Attribute inheritance

Put all the codes in the - > GitHub warehouse: https://github.com/zyugat/vue-review-all

It is divided into base, Component, router, Vuex and combined API. Five parts.

The examples in base and Component do not use scaffolds to run, but need to run their own browser. Position - > nocli

Component v-model parameters

Requirements: pass the data to the sub components through props to maintain the responsiveness of the data.

Idea: bind the Props value to the subcomponent through v-model, and the subcomponent is modified through the user-defined event emit.

By default, v-models on components use modelValue as prop and update:modelValue as events. We can modify these names by passing parameters to v-model:

Binding method: v-model:propname="xxx"

The event name thrown is the update:propname structure. The previous uptede is fixed.

1. Parent component binds props through v-model: v-model: my name = "myname1"

2. Accept props value myName in subcomponent.

3. The component input box sends a custom event. Send out the value when the value is changed.

<div id="app">
  <!-- First step -->
  <user-name v-model:my-name="myName1"></user-name>
  <p>myName: {{ myName1 }}</p>
</div>
<script>
  const app = Vue.createApp({
    data() {
      return {
        myName1: '123',
      }
    },
  })
  app.component('user-name', {
    // Step 2
    props: {
      myName: String,
    },
    // Declare custom events
    emits: ['update:myName'],
    // Step 3
    template: `
      <input
              type="text"
              :value="myName"
              @input="$emit('update:myName', $event.target.value)">
    `,
  })
  app.mount('#app')
</script>

Dynamic component

Using keep alive on dynamic components enables component instances to be cached.

1. Create three new components: tab home, tab posts, and tab archive

2. Splice attribute names by calculating attributes: currentTabComponent() {}

3. Switch the component name by clicking the button

4. Select the displayed components through: is = ""

<div id="dynamic-component-demo" class="demo">
  <button
          v-for="tab in tabs"
          :key="tab"
          :class="['tab-button', { active: currentTab === tab }]"
          @click="currentTab = tab"
  >
    {{ tab }}
  </button>

  <!-- Inactive components will be cached! -->
  <keep-alive>
    <component :is="currentTabComponent"></component>
  </keep-alive>
</div>
<script>
  const app = Vue.createApp({
    data() {
      return {
        currentTab: 'Home',
        tabs: ['Home', 'Posts', 'Archive'],
      }
    },
    computed: {
      currentTabComponent() {
        return 'tab-' + this.currentTab.toLowerCase()
      },
    },
  })

  app.component('tab-home', {
    template: `<div class="demo-tab">Home component</div>`,
  })
  app.component('tab-posts', {
    template: `<div class="demo-tab">Posts component</div>`,
  })
  app.component('tab-archive', {
    template: `<div class="demo-tab">Archive component</div>`,
  })

  app.mount('#dynamic-component-demo')
</script>

Attribute inheritance

Effect: component data is not received by props, and these data will be bound to HTML elements as attributes.

  • Question 1. Inheritattributes: false: if you don't want the root element of the component to inherit the attribute, set it in the option.
    • When you turn off inheritance, if you want to apply all prop attribute s to other elements instead of the root element, you can use: v-bind = "$attributes"
<!-- This will happen if it is not closed, The root element inherits all attributes -->
<div mydata="test" class="my-class" id="custom-layout">
<h2>father</h2>
</div>

<!-- When closed,to h2 Label binding $attrs -->
<h2 v-bind="$attrs">father</h2>
<div>
<h2 mydata="test" class="my-class" id="custom-layout">father</h2>
</div>
  • Question 2. What does $attrs contain?

    • Contains attribute bindings and events in the parent scope that are not component props or custom events, including class and style. When a component does not declare any prop, all parent scope bindings will be included. v-bind="$attrs"
  • Problem 3. When there is a parent component passing Props

    • When the component does not receive Props, Props will exist in $attrs.
    • When the component receives props, props will not exist in $attrs, but in $props.
  • Question 4. If there is a method call in the attribute I pass

    • For example, I bound the click event @ click="show" to the parent component. Although it is not displayed in attrs, it exists.
    • For example, in the following case, clicking father child text will trigger console output. However, clicking $attrs and $props won't respond, because I didn't bind v-bind="$attrs" to them.
<style>
  .my-class{
    color:red
  }
</style>
<div id="app">
  <grandfather />
</div>
<script>
  const App = {}
  const app = Vue.createApp(App)
  app.component('grandfather', {
    // inheritAttrs: false,
    data() {
      return {
        test: 'test',
      }
    },
    methods: {
      show() {
        console.log('1111')
      },
    },
    template: `
      <div>
      <h2>grandfather</h2>
      <father :myData="test" class="my-class" id="custom-layout"
              @click="show"></father>
      </div>
    `,
    // father assembly
    components: {
      father: {
        inheritAttrs: false,
        template: `
          <div>
          <h2 v-bind="$attrs">father</h2>
          <p>$attrs: {{ $attrs }}</p>
          <p>$props: {{ $props }}</p>

          <child v-bind="$attrs"></child>
          </div>
        `,
        // child component
        components: {
          child: {
            props: ['myData'],
            template: `
              <div>
              <h2>child</h2>
              <p>{{ myData }}</p>
              </div>
            `,
          },
        },
      },
    },
  })

  app.mount('#app')
</script>

Tags: Javascript Front-end ECMAScript Vue Vue.js

Posted on Tue, 16 Nov 2021 09:52:00 -0500 by jamesgrayking