component

  • Components are one of the most powerful features of vue.js
  • Components can extend HTML elements and encapsulate reusable generations

The component registration

Global registration

  • Vue.component(‘ component name ‘, {}) The first argument is the label name and the second argument is an option object
  • Once the global component is registered, any VUE instance can be used
Component basics
<div id="example">
  <! Component names are used as HTML tags -->  
  <my-component></my-component>
</div>
<script>
    // Register the component
    // my-component is the name of the custom tag in the component
	Vue.component('my-component', {
      template: '
       
A custom component!
'
}) // Create the root instance new Vue({ el: '#example' })
</script> Copy the code
Component Considerations
  • The data value of the component parameter must be a function that returns an object
  • The component template must be a single root element
  • The content of a component template can be a template string
  <div id="app">
     <! Since data returns an object, the data in each component is private, i.e., each instance can maintain an independent copy of the returned object. 
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
      <! 8, must use a dash to use components -->
     <hello-world></hello-world>
  </div>

<script type="text/javascript">
	//5 If you use a humped name for a component, you can only use a humped name for the component in the string template.
    But in a normal tag template, you must use a dash to use components
     Vue.component('HelloWorld', {
      data: function(){
        return {
          msg: 'HelloWorld'}},template: '<div>{{msg}}</div>'
    });
    
    
    
    Vue.component('button-counter', {
      // 1. The data value of the component parameter must be a function
      // This function also requires that an object be returned
      data: function(){
        return {
          count: 0}},// The component template must be a single root element
      The content of a component template can be a template string
      template: '
       
< button@click ="handle"> click {{count}} times # 6 You can use components in a string template in a hump manner
`
.methods: { handle: function(){ this.count += 2; }}})var vm = new Vue({ el: '#app'.data: {}});
</script> Copy the code

Local registration

  • Can only be used in the vUE instance where it is currently registered
  <div id="app">
      <my-component></my-component>
  </div>


<script>
    // Define the template for the component
    var Child = {
      template: '
       
A custom component!
'
} new Vue({ // Locally register the component components: { // will only be available in the parent template and must be registered on the instance to be used in HTML files 'my-component': Child } })
</script> Copy the code

Vue debugging tool

Transfer values between Vue components

Parent component passes value to child component

  • The parent component sends in the form of a property binding value to the child component.
  • The child component then receives it with the properties props
  • There is no restriction on using the hump form in props, the short slash form in the template and the string form in the template
  <div id="app">
    <div>{{pmsg}}</div>
     <! -- menu-item is nested in APP, so menu-item is subcomponent -->
     <! Pass a static value to the child component -->
    <menu-item title='Value from parent component'></menu-item>
    <! Ptitle = 'data'; ptitle = 'data'; ptitle = 'data'; Values can be numbers, objects, arrays, and so on -->
    <menu-item :title='ptitle' content='hello'></menu-item>
  </div>

  <script type="text/javascript">
    Vue.component('menu-item', {
      // 3. The child component uses the props property to receive data from the parent component
      props: ['title'.'content'].data: function() {
        return {
          msg: 'Data for the child component itself'}},template: '<div>{{msg + "----" + title + "-----" + content}}</div>'
    });
    var vm = new Vue({
      el: '#app'.data: {
        pmsg: 'Contents of parent component'.ptitle: 'Dynamically bound Properties'}});</script>
Copy the code

Child components pass values to parent components

  • Child components with$emit()Triggering event
  • $emit()The first parameter is the custom event name and the second parameter is the data to be passed
  • The parent component uses V-ON to listen for events of the child component
 <div id="app">
    <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
     <! The parent component can monitor the event of the child component using the v-ON function. If the first parameter in the $emit function is magnanime-text, the handle should be the corresponding event handler.	
    <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">Vue.component_props ('menu-item', {props: ['parr'], template: '<div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>The first parameter is the name of the custom event. The second parameter is the data to be passed<button @click='$emit("enlarge-text", 5)'>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 ', parr: ['apple','orange','banana'], fontSize: 10}, methods: {handle: function(val){this.fontSize += val; }}});</script>

Copy the code

Brother to brother

  • Brothers need to use the event center to transfer data between them
    • Var hub = new Vue()
  • $emit(method name, data passed)
  • Mounted (){} Raises the hub.$on() method
  • The destruction event could not pass data after it was destroyed by the hub.$off() method name
 <div id="app">
    <div>The parent component</div>
    <div>
      <button @click='handle'>Destruction of the event</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /* Data transfer between sibling components */
    //1. Provide the event center
    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(){
          $emit(method name, data passed) emits an event from the hub.$emit(method name, data passed) emits an event from the other component
          hub.$emit('jerry-event'.2); }},mounted: function() {
       // Locate the hub.$on(mounted(){} hook)
        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(){
          $emit(method name, data passed) emits an event from the hub.$emit(method name, data passed) emits an event from the other component
          hub.$emit('tom-event'.1); }},mounted: function() {
        // Locate the hub.$on() {// locate the hub.$on() {// locate the hub
        hub.$on('jerry-event'.(val) = > {
          this.num += val; }); }});var vm = new Vue({
      el: '#app'.data: {},methods: {
        handle: function(){
          //4, the destruction event was destroyed by the hub.$off() method name
          hub.$off('tom-event');
          hub.$off('jerry-event'); }}});</script>

Copy the code

Component slot

  • The most important characteristic of component is reusability, and the use of slot can greatly improve the reusability of component

Anonymous slot

  <div id="app">
    <! If no value is passed, the default value in slot will be used.  
    <alert-box>Have a bug in</alert-box>
    <alert-box>There is a warning</alert-box>
    <alert-box></alert-box>
  </div>

  <script type="text/javascript">/* Component slot: parent component passes content to child component */ Vue.component('alert-box', {template: '<div>
          <strong>ERROR:</strong># When the component is rendered, this<slot>The element will be replaced with "nested content in component tags". Slots can contain any template code, including HTML<slot>The default content</slot>
        </div>`}); var vm = new Vue({ el: '#app', data: { } });</script>
</body>
</html>

Copy the code

A named slot

  • A slot with a name
  • Bind elements using the “name” attribute in
  <div id="app">
    <base-layout>
       <! The value of this slot must match the name value of the following slot components. If no match is found, the slot will be placed in an anonymous slot. 
      <p slot='header'>Header information</p>
      <p>Main Content 1</p>
      <p>Main Content 2</p>
      <p slot='footer'>Bottom Information</p>
    </base-layout>

    <base-layout>
      <! Template temporary package tag will not render to the page -->  
      <template slot='header'>
        <p>Title Message 1</p>
        <p>Title Message 2</p>
      </template>
      <p>Main Content 1</p>
      <p>Main Content 2</p>
      <template slot='footer'>
        <p>Bottom Information Information 1</p>
        <p>Bottom Information Information 2</p>
      </template>
    </base-layout>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">Vue.component('base-layout', {template: '<div>
          <header>### 1<slot>The "name" attribute binding element specifies the name of the current slot<slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>The rendering order of the named slots depends entirely on the template, not on the order of the elements in the parent component<slot name='footer'></slot>
          </footer>
        </div>`}); var vm = new Vue({ el: '#app', data: { } });</script>
</body>
</html>

Copy the code

Scope slot

  • Parent component to child component processing
  • You can either reuse the slots of the child components or make the slot contents inconsistent
  <div id="app">
    <! We need to use the scope slot when we want the style of li to be defined externally where the component is used, because there may be multiple places to use the component but the style is not the same.  
    <fruit-list :list='list'>
       <! <template> = scope="slotProps" --> 	
      <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>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">/* Scope slot */ Vue.component('fruit-list', {props: ['list'], template: '<div>
          <li :key='item.id' v-for='item in list'>### 3, In the child component template,<slot>The element has a function (MSG =" XXX ") for props to pass data to the component. The ### slot can provide a default content, and if the parent component does not provide content for the slot, the default content will be displayed. If the parent provides content for the slot, the default content is replaced<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>
</body>
</html>

Copy the code