SoFunction
Updated on 2025-03-03

Vue custom attribute instance analysis

This article describes the Vue custom properties. Share it for your reference, as follows:

1 Event Name

Unlike components and props, there is no automated case conversion in event names. Instead, the triggered event name needs to exactly match the name used to listen to this event. For example, if an event with camelCase name is triggered:

this.$emit('myEvent')

Then listening to the kebab-case version of this name will not have any effect:

<my-component v-on:my-event="doSomething"></my-component>

Unlike components and props, event names are not used as a JavaScript variable name or property name, so there is no reason to use camelCase or PascalCase. andv-onEvent listeners will be automatically converted to all lowercase in the DOM template (because HTML is case-insensitive), sov-on:myEventWill becomev-on:myevent——Makes that myEvent cannot be heard.

Therefore, we recommend that you always use the event name of kebab-case.

2. Custom component v-model

2.2.0+ New

The v-model on a component will be used by default.valueofpropand namedinputEvents, but input controls such as radio boxes, check boxes, etc. may convertvalueFeatures are used for different purposes.modelOptions can be used to avoid such conflicts:

('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template:
      `
      <input
        type="checkbox"
        v-bind:checked="checked"
        v-on:change="$emit('change',$)"
      >
      `
});

Now when using v-model on this component:

<base-checkbox v-model="loving"></base-checkbox>

The loving value here will be passed into this namecheckedofprop. At the same time<base-checkbox>Trigger achangeWhen the event is accompanied by a new value, thislovingThe properties of , will be updated.

Note that you still need to declare the checked prop in the component's props option.

3 Bind native events to component

There may be many times you want to listen for a native event directly on the root element of a component. At this time, you can usev-onof.nativeModifier:

<base-input v-on:="onFocus"></base-input>

This is useful sometimes, but it is not a good idea when you try to listen for a very specific element like <input>. For example, the above <base-input> component may have been refactored as follows, so the root element is actually a <label> element:

<label>
  {{ label }}
  <input
      v-bind=$attrs",
      v-bind:value="value"
      v-on:input="$emit('input',$)"
      >
</label>

At this time, the parent.nativeThe listener will fail silently. It will not produce any errors, butonFocusThe handler will not be called as you expected.

To solve this problem, Vue provides a$listenersA property, it is an object, which contains all listeners acting on this component. For example:

{
 focus: function (event) { /* ... */ }
 input: function (value) { /* ... */ },
}

With this$listenersAttributes, you can cooperatev-on="$listeners"Point all event listeners to a specific child element of this component. For similar<input>You hope it can be matchedv-modelFor working components, it is often useful to create a computed property for these listeners similar to the following inputListeners:

('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this;
      //() will merge all objects into a new object      return ({},
          //Add all listeners from parent          this.$listeners,
          //Add a custom listener or rewrite listener behavior          {
            input: function (event) {
              vm.$emit('input', );
            }
          }
      )
    }
  },
  template: `
    &lt;label&gt;
      {{ label }}
      &lt;input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      &gt;
    &lt;/label&gt;
  `
});

Now<base-input>The component is a completely transparent wrapper, which means it can be completely like an ordinary one<input>Elements are used: all the same features and listeners as it can work.

4.sync modifier

2.3.0+ New

In some cases, we may need to "two-way binding" a prop. Unfortunately, true bidirectional binding can cause maintenance problems, because child components can modify the parent component, and there is no obvious source of changes in both the parent component and the child component.

This is why we recommendupdate:my-prop-nameThe pattern trigger event is replaced by the For example, in a hypothetical component containing title prop, we can express the intention to assign a new value to it using the following methods:

this.$emit('update:title', newTitle)

The parent component can then listen to that event and update a local data attribute as needed. For example:

<text-document
 v-bind:title=""
 v-on:update:title=" = $event"
></text-document>

For convenience, we provide an abbreviation for this pattern, i.e..syncModifier:

<text-document v-bind:=""></text-document>

When we set multiple props with one object at the same time, we can also use this.syncModifiers andv-bindUse with:

<text-document ="doc"></text-document>

This will take each property (such as title) in the doc object as an independentpropPass it in, and add each to update itv-onListener.

WillUsed on a literal object, e.g.=”{ title: }”, does not work properly, because when parsing a complex expression like this, there are many edge cases that need to be considered.

I hope this article will be helpful to everyone's programming.