By Kevin Ball and Vuejsdevelopers

Like it and see. Make it a habit

In this paper,GitHub Github.com/qq449245884…Has included more categories of previous articles, as well as a lot of my documentation and tutorial material. Welcome Star and Perfect, you can refer to the examination points for review in the interview, I hope we can have something together.

Few people initially write Vue components with the intention of making them open source. Most of us start by writing our own components — we have a problem and decide to solve it by building a component. Sometimes we find ourselves wanting to solve the same problem in a new location in the code base, so we take components and refactor them to make them reusable. Then we wanted to use it in a different project, so we moved it into a separate package. And we thought, “Hey, why not share this with the world?” So we open-source this component.

On the one hand, this means that a large and growing number of open source components are available to anyone who works at Vue, which is very piece.

On the other hand, many of these components don’t work well with the Vue ecosystem because most of them come from specific situations and not everyone has design experience reusing components across multiple environments.

What does “fine” mean? At a high level, this means that behavior is natural to Vue developers and easy to extend and integrate into any type of application.

After exploring a wide range of open source components, here’s what I think makes a Vue component work well:

  • implementationv-modelcompatibility
  • Event transparency
  • Assign attributes to the correct elements
  • Accept the browser’s keyboard navigation specification
  • Using events takes precedence over callbacks
  • Limiting component styles

implementationv-modelcompatibility

One of the most important ways to make a component of a form field idiomatic is to support v-Models. The v-model is used to bind data and add a listener to the input event as follows:

Custom events can also be used to create custom input components that support V-Models. Remember:

<input v-model="searchText">
Copy the code

Is equivalent to:

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>
Copy the code

When used with components, the V-Model looks like this:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>
Copy the code

In order for it to work, the inside this component must:

  • Bind its value attribute to a prop named Value

  • Throws the new value through a custom input event when its input event is raised

The code looks like this:

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})
Copy the code

The V-Model should now work perfectly on this component:

<custom-input v-model="searchText"></custom-input>
Copy the code

Event transparency

To implement the V-Model, the component needs to implement the input event. But what about other events? Like click events, keyboard handling and so on? While native events bubble up in HTML, Vue’s event handling does not bubble up by default.

For example, it won’t work unless I do something specific

<my-textarea-wrapper @focus="showFocus">
Copy the code

The showFocus event handler will never be called unless we write the issue Focus event in the wrapper component. Vue does, however, give us a way to programmatically access the listeners applied to the component, so we can assign them to the right place: the $Listener object.

On second thought, the reason is obvious: This allows us to pass the listener to the right place in the component. For example, use a text area wrapper component

<div class="my-textarea-wrapper">
  <textarea v-on="$listeners" ></textarea>
</div>
Copy the code

The events that now occur on the Textarea are those that are passed.

How to understand vUE$listenersAttribute?

Suppose there is a Parent component and a Child component

// Parent
<template>
  ...
  <child v-on:event-one="methodOne" v-on:event-two="methodTwo" />
  ...
</template>
Copy the code

All v-On events passed in when you use Child can be found on the $Listeners object.

// Child
created () {
  console.log(this.$listeners) // { 'event-one': f(), 'event-two': f() }
}
Copy the code

Assign attributes to the correct elements

How do you handle attributes like rows for a Textarea or add a simple tooltip title tag to any element

By default, Vue takes attributes that are applied to a component and places them on the root element of that component. But that’s not always what we want. If we look at the TextaREA wrapper again from above, in this case it makes more sense to apply the attribute to the Textarea itself rather than to the div.

To do this, we tell the component not to apply attributes by default, but to apply them directly using the $attrs object, in the JS code:

export default {
  inheritAttrs: false,
}
Copy the code

In the template

<div class="my-textarea-wrapper">
  <textarea v-bind="$attrs"></textarea>
</div>
Copy the code

The official documentation explains component attribute passing by talking about $attrs and inheritAttrs attributes, and uses both attributes in combination. Not at first glance, combined with the code demo to figure it out.

import Vue from 'vue'; Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label> ` }) new Vue({ el:'#root', template:` <base-input v-model="username" required placeholder="Enter your username" input="testInput" ></base-input> `,  data:{ username:'', } })Copy the code

To hideinheritAttrs: falseandv-bind="$attrs", the browser gets the following results

There are two exceptions:

  1. Set in the parent componentplaceholderAttributes such as, are not passed to child components;
  2. Properties set by the parent component are passed to the root element of the child component, i.elabelAnd thelabelIt’s not necessary

[inheritAttrs:false] [inheritAttrs:false] [inheritAttrs:false] [inheritAttrs:false] [inheritAttrs:false] [inheritAttrs:false] Second, an element in a child component that adds v−bind=”$attrs” inherits the parent component’s property, even if it is not defined in props

Accept the browser’s keyboard navigation specification

Accessibility and keyboard navigation is one of the most forgotten parts of Web development, and one of the most important things to get right when writing components that are going to work in an ecosystem.

This means ensuring that the component complies with browser specifications: the TAB key should allow you to select form fields. Enter is typically used to activate a button or link.

A complete list of keyboard navigation suggestions for common components can be found on the W3C web site. Following these recommendations will make your components usable in all applications, not just those that have nothing to do with accessibility.

Using events takes precedence over callbacks

When it comes to data communication and user interaction from a component to its parent, there are two common choices: callback functions and events in props. Since Vue custom events do not bubble up like native browser events, they are functionally equivalent, but for reusable components, it is recommended to use events whenever possible, followed by callbacks. Why?

In an interview with Fullstack Radio, Chris Fritz, a member of Vue’s core team, gave the following reasons:

  1. Use events to make it clear what the parent component knows. It makes a clear distinction between “what we get from the parent component” and “what we send to the component.”

  2. Expressions can be used directly in event handlers, providing extremely compact event handlers for simple cases.

  3. It’s more conventional-Vue examples and documentation tend to use events to enable communication between a component and its parent.

Fortunately, if you are currently using the props callback, it is easy to modify the component to emit events. Components that use callbacks can look like this:

// my-custom-component.vue export default { props: ['onActionHappened', ...]  methods() { handleAction() { ... // your custom code if (typeof this.onActionHappened === 'function') { this.onActionHappened(data); }}}}Copy the code

External call method:

<my-custom-component :onActionHappened="actionHandler" />
Copy the code

Changing to an event-based approach looks like this:

// my-custom-component.vue export default { methods() { handleAction() { ... // your custom code this.$emit('action-happened', data); }}}Copy the code

External call method:

<my-custom-component @action-happened="actionHandler" />
Copy the code

Limiting component styles

Vue’s single-file component structure allows us to embed styles directly into components, especially when used in combination with scope, which gives us a great way to publish fully packaged styling components without affecting the rest of the application.

Because of the power of the system, it is easy to put all the component styles into a component and deliver a fully styled component. Here’s the thing: no application is styled alike, and what makes a component look perfect in our application will make it stand out in other people’s applications. Because component styles are usually included later than global stylesheets, overwriting them can be a specificity nightmare.

To prevent this, it is recommended that any components (colors, borders, shadows, etc.) that CSS is not necessary for structure should be excluded from our component files themselves or be able to be closed. Instead, consider maintaining a customizable SCSS section that allows users to customize the content of their hearts.

<template> <div :class="isStyledClass"> <! -- my component --> </div> </template>Copy the code

In JS:

export default { props: { disableStyles: { type: Boolean, default: false } }, computed: { isStyledClass() { if (! this.disableStyles) { return 'is-styled'; }}},Copy the code

And then, we can

@import 'my-component-styles';
.is-styled {
  @include my-component-styles();
}
Copy the code

This will allow us to use off-the-shelf styles at will, but users who want to customize no longer need to create highly exclusive overrides, they can simply turn off styles by setting the disableStyles property to True.


The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

Original text: vuejsdevelopers.com/2018/06/18/…


communication

This article is updated every week, you can search wechat “big move the world” for the first time to read and urge more (one or two earlier than the blog hey), this article GitHub github.com/qq449245884… It has been included and sorted out a lot of my documents. Welcome Star and perfect. You can refer to the examination points for review in the interview.