Seven weeks seven kinds of front-end frame four: Vue.js component and Component communication

Source: Internet
Author: User
Tags tagname

Basically according to the guide of the official website to comb it all over again: http://vuejs.org/guide/index.html here we use a Todo List application as an example to all the relevant just string together, this article all the code is on GitHub https:/ /github.com/lihongxun945/vue-todolistvue instances

A Vue app is booted by a root Vue instance, and Vue instance is created like this:

var vm = new Vue({  // options})

A instance is actually a VM in MVVM. All the properties in data in the incoming configuration object are mounted on the instance, and in order to avoid naming conflicts, the Vue built-in method is mounted to the instance with the properties that begin with $.

Instance from creation to destruction will experience the following lifecycle:

Roughly three steps during initialization:

    • Data monitoring is a binding
    • Compiling templates
    • Insert document or replace corresponding DOM
# Vue Basic Syntax data binding

Vue uses a class mastache syntax. Common binding syntax is divided into the following categories:

    • Mastache syntax, such as {{ data }}{{ data | filter}}
    • v-bindBinding properties, for example v-bind: href ,v-bind:class
    • v-onBinding events, for example v-on:click ,v-on:submit

All of them v-* are directive.
Example:

<div v-bind:class="[classA, isB ? classB : ‘‘]">
Attribute calculation

Vue supports a very interesting attribute calculation syntax, and you can specify that a property be computed by another property, so it does not have to be done by $watch :

var vm = new Vue({  el: ‘#example‘,  data: {    a: 1  },  computed: {    // a computed getter    b: function () {      // `this` points to the vm instance      return this.a + 1    }  }})
# # Process Control and list-related syntax includes ' v-if ', ' v-show ', ' v-else ', ' v-for ' form

Bidirectional data binding:

<input type="text" v-model="message" placeholder="edit me"><input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
# # Animated animations are implemented in the same way as Angular and React, both by adding and removing classes. # Basic usage of component components

The definition of Component consists of two parts:

1 Creating the Component class:

var Profile = Vue.extend({  template: "<div> Lily </div>"});

2 Register a tagname:

Vue.component("me-profile", Profile);

So that we can use this component through TagName:

  <div id="todo">    <my-profile></my-profile>    <form v-on:submit="add" v-on:submit.prevent>      <input type="text" v-model="input"/>      <input type="submit" value=‘add‘ />    </form>     ...</div>

Vue.component("me-profile", Profile);is a global registration, if it is only used within a certain page, it can be registered by local means:

var vm = new Vue({  el: "#todo",  components: {    "my-profile": Profile  },  ...}

Because our Vue instance is bound to an todo element, it my-profile is not valid to put it outside of this element, and only in this case will it be initialized by this instance of Vue.

Precautions:
The parameters that can be passed by the Vue constructor can be used basically Vue.extend , but the pair el and data two parameters need to be noted, in order to avoid sharing the same object among different instances, it is always function better to return a new object by returning it:

var MyComponent = Vue.extend({  data: function () {    return { a: 1 }  }})

Because the parameters are the same, they are actually the same thing, but one is a component, and one is used to boot the Vue.

Template considerations

Because Vue is the native DOM, some custom tags may not conform to the DOM standard, such as to table customize one in tr , if the direct insert my-component does not conform to the specification, so should write:

<table>  <tr is="my-component"></tr></table>
Props Passing Data

Each component in the Vue is independent and cannot and should not directly access the data of the parent class. So we pass the data to the props subassembly, is it like the React way?

Unlike React, the Vue neutron component needs to declare its own props before it can:

var Profile = Vue.extend({  props: ["name"],  template: `    

Then we can pass parameters like this when using profile:

<my-profile name=‘Lily‘></my-profile>

This is passed by literal arguments, so the value passed must be a string. Another way is to dynamically pass parameters, which v-bind can be used to bind data in two directions or to pass non-string parameters:

<my-profile v-bind:name=‘input‘></my-profile>

v-bindIf it is a string, it is the corresponding field in data that binds to the parent component, such as the value that is bound in both directions input . If it's a number, it's bound to a number.

Vue can also specify one-way or two-way data binding explicitly:

<!-- default, one-way-down binding --><child :msg="parentMsg"></child><!-- explicit two-way binding --><child :msg.sync="parentMsg"></child><!-- explicit one-time binding --><child :msg.once="parentMsg"></child>
Props Check

A good component should always verify that the parameters are correct, and you may need to set some default values for the parameters:

var Profile = Vue.extend({    input: {      type: String    }});
Parent-Child Component communication

The above props is actually a way for the parent component to pass messages to the child component.
There is one in the subcomponent this.$parent and this.$root can be used to method the parent component and the root instance. However, we should avoid doing so now. Because the component itself is designed to encapsulate independent logic, the encapsulation of the component is compromised if it accesses the data of the parent component directly.
So we should still props communicate through the way that the parent component passes to the child component.

Of course, we props can only do callbacks. In React, the problem is explored, and the React approach is to props do it by passing a callback function to the child component. In fact, I don't really like the way the callback function is transmitted, I prefer the way the event is. The Vue neutron component can communicate through events and parent components. Sending a message to the parent component is passed, and the this.$dispatch message is sent to the child component, this.$boardcast where all the fathers and children are sent a message, but once a callback is executed, it is stopped, unless the callback function is explicitly returned true .

We split the previous Todo list into different components, so we can experience the two-way communication between components, and we split up two components, respectively List Form .

FormTakes care of user input and sends a message to the parent component when the form is submitted, with the add following code:

var Form = Vue.extend({  props: {    username: {      type: String,      default: "Unnamed"    }  },  data: function() {    return {      input: "",    };  },  template: `    

ListOnly takes care of the display list and handles the user tick, and when it receives the message, it add adds an entry on its own:

var List = Vue.extend({ template: ` <ul> <li v-for=‘todo in list‘> <label v-bind:class="{ done : todo.done }" > <input type="checkbox" v-model="todo.done"/> {{todo.title}} </label> </li> </ul>`, props: { initList: { type: Array } }, data: function() { return { list: [] } }, events: { add: function(input) { if(!input) return false; this.list.unshift({ title: input, done: false }); } }});

Then, since this is two components, of course, a Vue instance is required to boot the boot, our example is as follows:

var vm = new Vue({ el: "#todo", components: { "todo-form": Form, "todo-list": List }, events: { add: function(input) { this.$broadcast("add", input); } }});

Note that Form in fact and List logically is a peer component, so they do not have a parent-child relationship, they are all vm children together. vm Form The message received here will be forwarded List .

The HTML code is much simpler:

 <div id="todo"> <todo-form username=‘Lily‘></todo-form> <todo-list></todo-list> </div>
Slots

The Slot allows you to insert the HTML rendered by the parent component into the subassembly, and it is not clear when this will be required, and the child component is too intrusive to do so.

Dynamic Switch Components

This feature feels a bit redundant, and in many cases we should be switching through logic code instead of the dynamic components built into Vue. However, it is convenient to implement a tab-like function.

Here we add a about page to the Todo List. So first we need to change the VM into a component, which is called the Todo entire Todo page:

var Todo = Vue.extend({  template: `  <div id="todo">    <todo-form username=‘Lily‘></todo-form>    <todo-list></todo-list>    <slot>not show</slot>  </div>  `,  components: {    "todo-form": Form,    "todo-list": List  },  events: {    add: function(input) {      this.$broadcast("add", input);    }  }});

In fact, the first line of changes.

Then we need to create a About component:

var About = Vue.extend({  template: `  <div id="about">    <p>About Todo List V0.1.0</p>    <p>Content here</p>  </div>`});

So here's the point, we're going to create an instance VM, which is responsible for toggling the two pages:

var vm = new Vue({  el: "body",  data: {    currentView: "todo"  },  components: {    "todo": Todo,    "about": About  }});

Here we define a currentView field, which can of course be any name, and then switch the component with a special component label:

<component :is="currentView"></component>  <ul>    <li><label><input type="radio" name=‘page‘ value=‘todo‘ v-model=‘currentView‘> Home</label></li>    <li><label><input type="radio" name=‘page‘ value=‘about‘ v-model=‘currentView‘> About</label></li>  </ul>

The above code has two needs to be noted:

    • componentThis special tag is then used to :is switch components using attributes.
    • radioThe field is modified by two-way binding currentView , enabling you to switch after clicking.
The implementation principle of data binding

Vue calls two-way binding reactive , which can be translated into reactive data binding. The interior is implemented through ES5 definitions getter and setter methods, so IE8 and the following browsers are not supported, and there are two easy ways to make mistakes:

    • If you data add and remove attributes directly on the page cannot be detected, the general deletion is not, but may be added dynamically, this time should be vm.$set(“name”, value) added by the way.
    • The changes inside the object cannot be detected, that is, the property changes that can only be detected, and data if data.a it is an object, the data.a.b = 1 change cannot be detected. In this case, you should create a new object and assign a value to data.a it.
Asynchronous update mechanism

The Vue update to the DOM is asynchronous! This asynchronous is done in an asynchronous queue, but this asynchronous queue will be executed in the current, Event Loop so if you modify the Data immediately to the DOM to do the query operation is not right, this time the DOM has not been updated, the correct way is to do this:

vm.msg = ‘new message‘ // change datavm.$el.textContent === ‘new message‘ // falseVue.nextTick(function () {  vm.$el.textContent === ‘new message‘ // true})

or this:

vm.$nextTick(function () {  this.$el.textContent === ‘new message‘ // true})

It took me half a day to finish the component, so let's look at another point:Directive

Seven weeks seven kinds of front-end frame four: Vue.js component and Component communication

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.