Vue component development

Component registration

  • assembly
    • The component is Vue JS is one of the most powerful functions
    • Components can extend HTML elements and encapsulate reusable code

Global components

  • Global component registration syntax
    • Vue.component('component name ', {}) the first parameter is the label name, and the second parameter is an option object
    • After the global component is registered, any vue instance can be used
// Global component registration template
Vue.component(Component name, {
    data: Component data,
    template: Component template content,
    methods: {
        Method name: function(){
            this.Component data
        }
    }
})
// Define a new component called button counter
Vue.component('button-counter', {
    data: function(){
        return {
            count: 0
        }
    },
    template: '<button v-on:click="count++">Click{{ count }}second.</button>'
})
  • Component considerations
    • The data value of the component parameter must be a function, and this function requires an object to be returned
      • Comparison between analysis function and ordinary object
    • Component template content must be a single root object
      • See the special writing method for details
    • The content of a component template can be a template string
      • Template strings require browser support (ES6 syntax)
    • Component naming
      • Mode short line
        • Vue.component('my-component',{/*...*/})
      • Hump mode
        • Vue.component('MyComponent',{/*...*/})
        • If the hump mode is used, the short horizontal line call is still required when the component is used

``html

```
<!-- Template string -->
<section id='app'>
    <button-counter></button-counter>
    <button-counter></button-counter>
</section>
<script>
    Vue.component('button-counter', {
        data: function(){
            return {
               count: 0
            }
        },
        template: `
            <div>
                <button v-on:click="handle">Click{{ count }}second.</button>
                <button>test</button>
            </div>
        `,
        methods: {
            handle: function(){
                this.count+= 2;
            }
        }
    });
    var vm= new Vue({
        el: '#app',
        data: {
            
        }
    });
</script>
<!-- Call of hump naming -->
<section id='app'>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <hello-world></hello-world>
</section>
<script>
    Vue.component('HelloWorld', {
      // 1. The data value of a component parameter must be a function 
      // At the same time, this function requires an object to be returned
        data: function(){
            return {
                msg: 'hello'
            }
        },
        template: '<div>{{ msg }}</div>'
    });
    Vue.component('button-counter', {
        data: function(){
            return {
               count: 0
            }
        },
      //  2. The component template must be a single root element
      //  3. The content of a component template can be a template string 
        template: `
            <div>
                <button v-on:click="handle">Click{{ count }}second.</button>
                <button>test</button>
            </div>
        `,
        methods: {
            handle: function(){
                this.count+= 2;
            }
        }
    });
    var vm= new Vue({
        el: '#app',
        data: {
            
        }
    });
</script>

Local component

  • Local registration
    • It can only be used in the vue instance that currently registers it
<section id="app">
    <hello-world></hello-world>
    <hello-tom></hello-tom>
    <hello-jerry></hello-jerry>
    <test-com></test-com>
</section>
<script>
    /*
      Local component registration
      A local component can only be used in the parent component that registers it
    */
    Vue.component('test-com',{
        // Global registration
      template: '<div>Test<hello-world></hello-world></div>'
    });
    var HelloWorld = {
        // Template definition of local components
      data: function(){
        return {
          msg: 'HelloWorld'
        }
      },
      template: '<div>{{msg}}</div>'
    };
    var HelloTom = {
      data: function(){
        return {
          msg: 'HelloTom'
        }
      },
      template: '<div>{{msg}}</div>'
    };
    var HelloJerry = {
      data: function(){
        return {
          msg: 'HelloJerry'
        }
      },
      template: '<div>{{msg}}</div>'
    };
    var vm = new Vue({
      el: '#app',
      data: {
        
      },
      components: {
          // Definition of local component registration
        'hello-world': HelloWorld,
        'hello-tom': HelloTom,
        'hello-jerry': HelloJerry
      }
    });
</script>

Value transfer between Vue components

Parent component passes value to child component

  • Parent component passes value to child component

    • The parent component sends values to child components in the form of attributes
    • Then the subcomponent receives it with the property props
    • Hump form is used in props,
    • The form of short horizontal line shall be used in the template
    • There is no such restriction in string templates
  • Pass value from parent component to child component - basic use

    • The props array in the component resolves the attribute name in the label for the template
    • If there is no v-bind binding, the transmitted data is direct data and the data type is string
    • If there is a v-bind binding, the data transferred is the data in the top-level component. The data type is the basic type
<section id="app">
  <div>{{pmsg}}</div>
    <!--1,menu-item  stay APP There are reasons nested in the menu-item   For sub components      -->
    <!-- Pass in a static value to the child component -->
  <menu-item title='Value from parent component'></menu-item>
  <!-- 2, When dynamic data is needed, it needs to be set in the form of attribute binding ptitle  From parent component data Data in . 
    The values passed can be numbers, objects, arrays, etc
-->
  <menu-item :title='ptitle' content='hello'></menu-item>
</section>
<script type="text/javascript">
  Vue.component('menu-item', {
    // 3. The child component uses the property props to receive the data passed by the parent component  
    props: ['title', 'content'],
    data: function() {
      return {
        msg: 'Data of the subcomponent itself'
      }
    },
    template:  `<div>
                {{ msg }}<br>
                {{ title }}<br>
                {{ content }}
            </div>`
  });
  var vm = new Vue({
    el: '#app',
    data: {
      pmsg: 'Content in parent component',
      ptitle: 'Dynamic binding properties'
    }
  });
</script>
  • Parent component passing value to child component - naming rules
    • Html is case sensitive, so the naming in HTML can only be horizontal
    • Hump form is used in props, and the form of short horizontal line needs to be used in the template
    • Value transfer rule: the data of the top-level component transfers the value to the props attribute of the secondary component, and then binds the data in the parsed HTML page to complete the data transfer
      • Hump type in Javascript: props: ['menuTitle ']
      • Dash in HTML: < menu item v-bind: menu title ='ptitle '> < / menu item >
<section id="app">
    <div>{{ pmsg }}</div>
    <menu-item v-bind:menu-title='ptitle'></menu-item>
</section>
<script type="text/javascript">
    /*  Rules for transferring value from parent component to child component - props attribute name  */
    Vue.component('third-com', {
        props: ['testTitle'],
        template: `<div>
                {{ testTitle }}
            </div>`
    });
    Vue.component('menu-item', {
        props: ['menuTitle'],
        template: `<div>
            {{ menuTitle }}
            <third-com testTitle='hello'></third-com>
            </div>`
    });
    var vm= new Vue({
        el: '#app',
        data: {
            pmsg: 'Content in parent component',
            ptitle: 'Parent component dynamic binding properties'
        },
    });
</script>
  • Value transfer from parent component to child component - value transfer type
    • String string
    • Value Number
    • Boolean
    • Array array
    • Object object
<section id="app">
    <div>{{ pmsg }}</div>
    <menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item>
</section>
<script type="text/javascript">
    /*  Value transfer from parent component to child component - value transfer type  */
    Vue.component('menu-item', {
      props: ['pstr','pnum','pboo','parr','pobj'],
      template: `
        <div>
          <div>{{pstr}}</div>
          <div>{{12 + pnum}}</div>
          <div>{{typeof pboo}}</div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
            <span>{{pobj.name}}</span>
            <span>{{pobj.age}}</span>
          </div>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: 'Content in parent component',
        pstr: 'hello',
        parr: ['apple','orange','banana'],
        pobj: {
          name: 'lisi',
          age: 12
        }
      }
    });
</script>

The child component passes values to the parent component

  • The child component passes values to the parent component
    • Child components can use $emit to trigger custom events of parent components
    • vm.$ The first parameter of emit (event, Arg) is the user-defined event name, and the second parameter is the data to be passed to trigger the event on the current instance
    • vm.$ On (event, FN) the parent component listens to the events of the child component with v-on
    • props data transmission principle: one-way data flow
<section id="app">
    <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
    <menu-item :parr='parr' @enlarge-text='handle'></menu-item>
</section>
<script type="text/javascript">
    /*  Pass value from child component to parent component - basic usage  */
    Vue.component('menu-item', {
      props: ['parr'],
      template: `
        <div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
          <button @click='$emit("enlarge-text")'>Increase font size in parent component</button>
          <button @click='$emit("enlarge-text, 10")'>Increase font size in parent component</button>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: 'Parent content in component',
        parr: ['apple','orange','banana'],
        fontSize: 10
      },
      methods: {
        handle: function(){
          // Expand font size
          this.fontSize += 5;
        }
      }
    });
</script>

Data transfer between sibling components

  • Data transfer between sibling components
    • The transmission of data between brothers needs the help of the event center, and the data is transmitted through the event center
      • Provide event center var hub = new Vue()
    • Pass the data side and trigger the hub through an event$ Emit (method name, passed data)
    • The data receiving party triggers the hub through the mounted() {} hook$ On() method name
    • Destroy the event through hub$ Data cannot be transferred after the off() method name is destroyed
<section id="app">
    <div>Parent component</div>
    <div>
      <button @click='handle'>Destruction event</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
</section>
<script type="text/javascript">
    /*  Data transfer between sibling components  */
    var hub = new Vue();
    Vue.component('test-tom', {
        data: function(){
            return {
                num: 0
            }
        },
        template: `
            <div>
                <div>TOM:{{num}}</div>
                <div>
                    <button @click='handle'>click</button>
                </div>
            </div>
        `,
        methods: {
            handle: function(){
                hub.$emit('jerry-event', 2);
            }
        },
        mounted: function() {
            // Listening events
            hub.$on('tom-event', (val) => {
                this.num += val;
            });
        }
        });
        Vue.component('test-jerry', {
        data: function(){
            return {
            num: 0
            }
        },
        template: `
            <div>
                <div>JERRY:{{num}}</div>
                <div>
                    <button @click='handle'>click</button>
                </div>
            </div>
        `,
        methods: {
            handle: function(){
            // Events that trigger sibling components
            hub.$emit('tom-event', 1);
            }
        },
        mounted: function() {
            // Listening events
            hub.$on('jerry-event', (val) => {
                this.num += val;
            });
        }
        });
        var vm = new Vue({
        el: '#app',
        data: {
            
        },
        methods: {
            handle: function(){
                hub.$off('tom-event');
                hub.$off('jerry-event');
            }
        }
    });
</script>

Component slot

  • Component slot

    • The biggest characteristic of components is reusability, and the reusability of components can be greatly improved by making good use of slots
  • Anonymous slot

    • When the component is rendered, the < slot > element will be replaced with "content nested in the component label".
    • The slot can contain any template code, including HTML
<section id="app">
  <!-- The nested contents in all component labels here will be replaced slot  If no value is passed, use slot Default values in  --> 
    <alert-box>have bug happen</alert-box>
    <alert-box>There is a warning</alert-box>
    <alert-box></alert-box>
</section>
<script type="text/javascript">
    /*  Component slot: the parent component passes content to the child component  */
    Vue.component('alert-box', {
      template: `
        <div>
          <strong>ERROR:</strong>
          
          <slot>Default content</slot>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        
      }
    });
</script>
  • Named slot
    • Slot with name
    • Bind elements using the "name" attribute in < slot >
    • The rendering order of named slots depends entirely on the template, not on the order of elements in the parent component
<section id="app">
  <base-layout>
  <p slot='header'>Title Information</p>
  <p>Main contents 1</p>
  <p>Main content 2</p>
  <p slot='footer'>Bottom information</p>
</base-layout>
<base-layout>
  <template slot='header'>
    <p>Title Information 1</p>
    <p>Title Information 2</p>
  </template>
  <p>Main contents 1</p>
  <p>Main content 2</p>
  <template slot='footer'>
    <p>Bottom message 1</p>
    <p>Bottom message 2</p>
  </template>
</base-layout>
</section>
<script type="text/javascript">
  /*  Named slot  */
  Vue.component('base-layout', {
    template: `
      <div>
        <header>
          <slot name='header'></slot>
        </header>
        <main>
          <slot></slot>
        </main>
        <footer>
          <slot name='footer'></slot>
        </footer>
      </div>
    `
  });
  var vm = new Vue({
    el: '#app',
    data: {
      
    }
  });
</script>
  • Scope slot

    • Processing from parent component to child component
    • It can reuse the slots of sub components and make the contents of slots inconsistent
  • Application of scope slot

    • When we want the style of li to be defined by the place where the component is used externally, because there may be many places to use the component, But the style is different. At this time, we need to use the scope slot
    • The parent component uses the < template > element and contains scope = "slotprops". Slotprops is only a temporary variable here
    • In the sub component template, there is a writing method similar to props passing data to the component on the < slot > element msg="xxx"
    • A slot can provide a default content. If the parent component does not provide content for this slot, the default content will be displayed.
    • If the parent component provides content for this slot, the default content will be replaced
<section id="app">
  <fruit-list :list='list'>
    <template slot-scope='slotProps'>
      <strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong>
      <span v-else>{{slotProps.info.name}}</span>
    </template>
  </fruit-list>
</section>
<script type="text/javascript">
  /*  Scope slot  */
  Vue.component('fruit-list', {
      props: ['list'],
      template: `
        <div>
          <li :key='item.id' v-for='item in list'>
            <slot :info='item'>{{item.name}}</slot>
          </li>
        </div>
      `
    });
  var vm = new Vue({
      el: '#app',
      data: {
        list: [{
          id: 1,
          name: 'apple'
        },{
          id: 2,
          name: 'orange'
        },{
          id: 3,
          name: 'banana'
        }]
      }
    });
</script>

Posted by iZone on Thu, 19 May 2022 10:12:07 +0300