Basically, we sorted out all the guidelines on the official website: http://vuejs.org/guide/index.html Here we take a Todo List application as an example to string together all the relevant only ones. All the code in this article is on github https://github.com/lihongxun945/vue-todolist
Vue instance
A Vue application is started by a root vue instance boot, and Vue instance is created like this:
var vm = new Vue({ // options})An instance is actually a VM in the MVVM. All attributes in data in the incoming configuration object will be mounted to the instance. In order to avoid naming conflicts, Vue built-in methods will be mounted to the instance with properties starting with $.
The instance will go through the following life cycle from creation to destruction:
During initialization, roughly three steps:
•Binding data monitoring, that is, monitoring of data
•Compiling templates
•Insert document or replace the corresponding dom
# Vue Basic Syntax
Data binding
Vue uses a mastache syntax. Commonly used binding syntaxes are divided into several categories:
•mastache syntax, such as {{ data }} {{ data | filter}}
•v-bind binding properties, such as v-bind: href, v-bind:class
•v-on binding events, such as v-on:click, v-on:submit
Among them, v-* is directive
example:
<div v-bind:class="[classA, isB ? classB : '']">
Attribute calculation
Vue supports a very interesting attribute calculation syntax. You can specify that an attribute is calculated by other attributes, so you don't need to use $watch to implement it:
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 } }})## The syntax related to process control and list include `v-if`, `v-show`, `v-else`, `v-for`
Form
Two-way data binding:
<input type="text" v-model="message" placeholder="edit me">
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
## The implementation method of animation is the same as that of Angular and React, and is implemented by adding and deleting classes. # Component
Basic usage of components
The definition of Component includes two parts:
1 Create component class:
var Profile = Vue.extend({ template: "<div> Lily </div>"});2 Register a tagname:
Vue.component("me-profile", Profile);
In this way, 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 in a certain page, it can be registered locally:
var vm = new Vue({ el: "#todo", components: { "my-profile": Profile }, ...}Because our Vue instance is bound to the todo element, it is invalid if my-profile is placed outside this element. Only by putting it inside will it be initialized by this instance of Vue.
Notes:
The parameters that can be passed by the Vue constructor can basically be used on Vue.extend, but you need to pay attention to the two parameters of el and data. In order to avoid sharing the same object between different instances, it is more reliable to always return a new object through function:
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 the other is used to guide Vue to start.
Notes on templates
Because Vue is a native DOM, some custom tags may not meet the DOM standard. For example, if you want to customize a tr in the table, if inserting my-component directly does not meet the specification, you should write it like this:
<table> <tr is="my-component"></tr></table>
Props Passing data
In Vue, each component is independent and cannot and should not directly access the data of the parent class. So is it very similar to React's method to pass data to subcomponents through props?
Unlike React, subcomponents in Vue need to declare their own props first:
var Profile = Vue.extend({ props: ["name"], template: ` <h2>{{name}}'s Todo List</h2> <h4>{{name}} is a good girl</h4> `});Then we can pass parameters like this when using Profile:
<my-profile name='Lily'></my-profile>
This is to pass parameters through literals, so the passed value must be a string. Another way is to pass parameters dynamically, and pass parameters through v-bind. You can bind data in two-way or pass non-string parameters:
<my-profile v-bind:name='input'></my-profile>
If v-bind is a string, it is the corresponding field in the data of the parent component, for example, the above is the value of input that is bound in both directions. If it is a number, it is bound to a number.
Vue can also explicitly specify one-way or two-way data binding:
<!-- 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 Verification
A good component should always verify that the parameters are correct first, and may also need to set the default values of some parameters:
var Profile = Vue.extend({ input: { type: String }});Parent-child component communication
The props mentioned above are actually a way for the parent component to pass messages to the child component.
In the child component there is a this.$parent and this.$root that can be used to methods the parent component and the root instance. However, now we should avoid doing so. Because the component itself is to encapsulate independent logic, if you directly access the data of the parent component, it will destroy the encapsulation of the component.
So we should still communicate through the parent component passing props to the child component.
Of course, props can only make callbacks. This issue has been discussed in React. The method of React is to use props to pass a callback function to the child component. Actually, I don’t really like this way of passing callback functions, I prefer the way of events. Vue neutronics can communicate with the parent component through events. Sending messages to the parent component is through this.$dispatch, and sending messages to the child component is through this.$boardcast. Here, messages are sent to all parents and children, but once a callback is executed, it will stop unless the callback function explicitly returns true.
We split the previous Todo List into different components to implement it, so that we can experience how to communicate with components in two-way. We split out two components, namely List and Form.
Form is responsible for processing user input and sending an add message to the parent component when submitting the form. The code is as follows:
var Form = Vue.extend({ props: { username: { type: String, default: "Unnamed" } }, data: function() { return { input: "", }; }, template: ` <h1>{{username}}'s Todo List</h1> <form v-on:submit="add" v-on:submit.prevent> <input type="text" v-model="input"/> <input type="submit" value='add' /> </form> `, methods: { add: function() { this.$dispatch("add", this.input); //This is to send a message to the parent component this.input = ""; } }});List is only responsible for displaying the list and handling user checking operations. After receiving the add message, it will add an entry on itself:
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, because these are two components, of course, a Vue instance is needed to bootstrap the startup, our instance 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 in fact, Form and List are logically parallel components, so they have no father-son relationship, and they are all children of vm. Here, vm will forward it to List after receiving the Form message.
The html code is simpler:
<div id="todo"> <todo-form username='Lily'></todo-form> <todo-list></todo-list> </div>
Slot
Slot can be used to insert HTML rendered from the parent component into the child component. It is not clear when this will be needed, and this is too invasive to the child component.
Dynamic switch components
This function feels a bit redundant. In many cases, we should switch through logical code rather than through dynamic components built-in Vue. However, it is very convenient to implement a function similar to tab switching.
Here we add an about page to Todo List. So first we need to change vm into a component, which is called Todo, which is the 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 is the first line.
Then we need to create an About component:
var About = Vue.extend({ template: ` <div id="about"> <p>About Todo List V0.1.0</p> <p>Content here</p> </div>`});Next is the key point. We want to create an instance vm, which is responsible for switching these 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 use a special component tag to switch components:
<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>
There are two things to note in the above code:
•Use the special tag component, and then use the :is property to switch components.
•radio modify the currentView field through two-way binding, so that you can switch after clicking.
The implementation principle of data binding
Vue calls bidirectional binding reactive, which can be translated as responsive data binding. It is implemented internally through the getter and setter methods defined by ES5, so it does not support IE8 and the following browsers. There are two easy things to make mistakes in this implementation:
•If you directly add and delete attributes on data, it is impossible to detect. Generally, deletion will not be possible, but may be added dynamically. At this time, it should be added through vm.$set("name", value).
•The changes inside the object cannot be detected, that is, they can only detect changes in the property of data. If data.a is an object, then data.ab = 1 This change cannot be detected. In this case, you should create a new object and assign it to data.a.
Asynchronous update mechanism
Vue's update to DOM is asynchronous! This asynchronous is performed in an asynchronous queue, but this asynchronous queue will be executed in the current Event Loop. Therefore, if you modify Data, it is wrong to go to the DOM immediately to do the query operation. At this time, the DOM has not been updated yet. 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 a long time to read the components. Here is another point: Directive
This article has been compiled into the "Vue.js Front-end Component Learning Tutorial", and everyone is welcome to learn and read.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.