One, what are the components? What is componentization

  • Vue is a class that instantiates an instance of Vue (since one instance is sufficient for a page, we also call it the root instance).
  • Use vue.extend to create a component that is actually a class
  • It can be understood that a component is a subclass of Vue

Componentization here is not a simple introduction, the introduction of vUE official website: related links

As for componentization in VUE, my personal opinion is that everything is an object, and an object contains many attributes. In fact, components are roughly the same. Front-end development should be componentized, with some highly repeatable, highly coupled nodes encapsulated into a single component, which is nice to call on demand when used.

Two, the application of components

1. Component basic code

Here’s an example of a common popover code in a project:

//zIndex is used to prevent multiple pop-ups when the last popover level is higher
<template>
  <div class="dialog-model" v-if="visible" :style="{'z-index': zIndex}">
        <div class="dialog-mark"  @click.self="maskClose? closeDialogModel():''" :style="{'z-index': zIndex + 1}"></div>
        <transition name="dialog-transition">
            <div class="dialog-main">
                <! - the title -- -- >
                <slot name="dialog-header"></slot>
                <! -- Popover content -->
                <section class="dialog-body">
                    <slot>Popup window content {{hasValue | capitalize}}</slot>
                </section>
            </div>
        </transition>
  </div>
</template>
<script>
export default {
  name: 'DialogModel'.[] is not recommended. You are advised to use {}. Type: the type to receive, default: the default value, and required: whether the transmission is mandatory.
  // Benefit: constrains the parent component to pass in the field type, and the console outputs an error message for the incoming error type
  props: {
    drawer: {
      type: Boolean.default: false.required: true,},// Whether to allow clicking the mask to close
    maskClose: {type: Boolean.default: true}},data() {
    return {
        bodyOverflow: ' '.hasValue:' ',}},/ / filter
  filters: {
      capitalize: function (value) {
        if(! value)return ' '
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)}}computed: {
     // Calculate the property listener
    visible: {
          get() {
            return this.drawer
          },
          set(val) {
            this.$emit('update:drawer', val)
          }
      }
  },
  watch: {
     // Listen for visible changes and perform corresponding operations
     visible(val) {
      if (val) {
           /* Your operation */}}},mounted() {
            this.prohibitScroll()
        },
  methods: {
        /** Zindex is automatically increased after each capture
        getzIndex() {
            let zIndexInit = 20190315;
            return zIndexInit++
        },
       /** Click the mask to close the popover */
        closeDialogModel(event) {
            this.drawer = false;
            // Dispatches an event to the parent to tell it that the popover is closed
            this.$emit('close'.this.drawer)
            this.renewBodyOverflow()
        },
        /** Disable page scrolling */
        prohibitScroll() {
            this.bodyOverflow = document.body.style.overflow
            document.body.style.overflow = 'hidden'
        },
        /** Restore page scrolling */
        renewBodyOverflow() {
            document.body.style.overflow = this.bodyOverflow; }}},</script>
<style lang="less" scoped>
 /* CSS code: writing styles directly in the vue file is not recommended (if the style sheet is relatively simple, you can ignore it) */ 
 /* Suggestion: Import the template as follows: */ 
 @import "./styles/index.less";
</style>
Copy the code

2. Use of components

Parent component code:

<template>
  <div>
  <button @click="visible=true"></buttom>
  <dialog-model :drawer.sync="visible" @close='closeModel'>
      <div slot="dialog-header">Your popover head node</div>
      <! -- Or use this method: <template v-slot:dialog-header> <div> Your popover header node </div> </template>-->
      <div>The body content of your popover</div>
  </dialog-model>
  </div>
</template>
<script>
import DialogModel from './component/DialogModel'
export default {
  name: ' '.data() {
    return {
        visible:false,}},computed: {},watch: {},mounted() {},
  methods: { 
      closeModel(val){
         console.log(val); // false}}}</script>
<style lang="less" scoped>

</style>
Copy the code

Three, understand the knowledge points in the code

Everything is prepared, unprepared waste, before doing things to be familiar with how it runs

The code is simply commented out and won't be repeated here

1. Compute

Computed properties are cached based on their responsive dependencies. They are only reevaluated if the relevant responsive dependencies change. This means that as long as the value you want to evaluate on your data has not changed, accessing the value you wrote on the evaluated property multiple times (e.g. : visible) will immediately return the previous evaluated result without having to execute the function again

2, listener (listener) : watch

Watch to respond to changes in data. You can use Watch when you need to perform asynchronous or expensive operations as data changes. For simple attributes (such as string, number) you can simply:

   a(val, oldVal){// Regular watch listens
         console.log("a: "+val, oldVal);
     },
Copy the code

If you are dealing with complex structure listening (for example, listening for changes in a property of object obj), you need to use deep listening such as:

    b:{// Deep listen, can listen to the changes in the object, array
         handler(val, oldVal){
             console.log("b.c: "+val.c, oldVal.c);
         },
         deep:true.// deep listening
         immediate:true
     }
Copy the code
  • A feature of watch is that when a value is first bound, the listening function is not executed, only when the value changes. If we want to execute the function at the same time as the initial binding value, we need to use the immediate attribute.

Immediate indicates whether to execute the handler method when the watch is bound for the first time. If the value is true, the handler method is executed immediately when the watch is declared. If the value is false, the handler method is executed only when data changes.

  • If you set deep: true, you can listen to changes in b.c, and this listener will be added to all properties of b. when there are many properties of an object, each property value change will be executed by the handler. If you only need to listen for one attribute value in the object, you can do the following optimization,

Listen for object properties using strings:

 'b.c': {
      handler(newName, oldName) {
          // ...
      },
      deep: true.immediate: true
    }
Copy the code

When a listener is used to process a property in data, it is recommended to clone a corresponding property and operate on the cloned property to avoid program memory leakage due to code errors.

3, slot (solt)

  • In the above code we use slots to allow the user to control the body of the popover

When we use the popover component and we don't pass anything in, the popover will say 'popover content' when we write the corresponding node content and style, or replace what you wroteCopy the code
  • Named slot: Name the slot when you define it, and bind it to the name defined for you

    As in the above code:

If you do not specify the use of the named slot when the component is invoked, the content is not displayed on the page

For example (usage) :

4. Filters

Vue.js allows you to customize filters that can be used for some common text formatting. Filters can be used in two places: double curly brace interpolation and V-bind expressions (the latter supported since 2.1.0+). Of the end of the filter should be added in the JavaScript expression, the “pipe” symbol | instructions

  • Local filters: (in components) as in the code above:

    Defines a filter method called capitalize that operates on the value passed in

    Filter use:

    A lot of people may have questions, can’t I just use ‘compute properties’? The answer is yes, the computed properties depend on the changes in the attributes in the data, the changes return the corresponding new value, and the recalculation, I think this is a bit of memory consumption filter appears to deal with some text formatting, or content replacement, these cases using filters, it is better.

  • Global filter

    Define a filter file, filters.js, in the project tools folder

    import Vue from "vue";
    
    Vue.filter("capitalize".(value) = > {
         if(! value)return ' '
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)});` `By introducing this file into main.js, you can use the defined filter methods throughout the project.Copy the code

Filters can use multiple: < div v – bind: id = “need to filter the values of the | 1 2 | | filter method to filter filter method method 3” > < / div >

The official recommendation for multiple filters is that filters are executed in sequence, with the value returned by the previous filter being passed to the next filter