What is a component: Components are one of the most powerful features of Vue.js. Components can extend HTML elements and encapsulate reusable code. At a higher level, components are custom elements, and Vue.js' compiler adds special features to it. In some cases, components can also be in the form of native HTML elements, extended with the is feature.
How to register components?
You need to create a component using the Vue.extend method, and then register the component using the Vue.component method. The format of the Vue.extend method is as follows:
var MyComponent = Vue.extend({ // Options...I will introduce it later})If you want to use this created component elsewhere, you have to name it:
Vue.component('my-component', MyComponent)
After naming, you can use this component name in the HTML tag, just like using a DOM element. Let’s take a look at a complete example of component registration and usage.
html code:
<div id="example"> <my-component></my-component></div>
js code:
// Define var MyComponent = Vue.extend({ template: '<div>A custom component!</div>'})// Register Vue.component('my-component', MyComponent)// Create root instance new Vue({ el: '#example'})Output result:
<div id="example"> <div>A custom component!</div></div
Nested Components
The component itself can also contain components. The following parent component contains a component named child-component, but this component can only be used by parent components:
var child = Vue.extend({ template: '<div>A custom component!</div>'});var parent = Vue.extend({ template: '<div>Parent Component: <child-component></child-component></div>', components: { 'child-component': child }});Vue.component("parent-component", parent);The above definition process is quite cumbersome, and you don't need to call the Vue.component and Vue.extend methods every time:
// Extend and register Vue.component('my-component', {template: '<div>A custom component!</div>'})// This is also possible with local registration var Parent = Vue.extend({ components: { 'my-component': { template: '<div>A custom component!</div>' } }})Dynamic Components
Multiple components can use the same mount point and then dynamically switch between them. Use the reserved <component> element to dynamically bind to its is property. The columns below have three components home, posts, and archive installed under the same vue instance, and dynamically switch component display through the currentView feature.
html code:
<div id="dynamic"> <button id="home">Home</button> <button id="posts">Posts</button> <button id="archive">Archive</button> <br> <component :is="currentView"></component></div>
js code:
var vue = new Vue({ el:"#dynamic", data: { currentView: "home" }, components: { home:{ template: "Home" }, posts: { template: "Posts" }, archive: { template: "Archive" } }});document.getElementById("home").onclick = function(){vue.currentView = "home";};document.getElementById("posts").onclick = function(){vue.currentView = "posts";};document.getElementById("archive").onclick = function(){vue.currentView = "archive";};Components and v-for
<my-component v-for="item in items"></my-component>
Data cannot be passed to a component because the scope of the component is independent. To pass data to components, props should be used:
<my-component
v-for="item in items"
:item="item"
:index="$index">
</my-component>
The reason why the item is not automatically injected into the component is that this causes the component to be tightly coupled to the current v-for. Explicitly declare where the data comes from and can be reused elsewhere for components.
In-depth responsive principle
When a component binds data, how can the binding be effective and can dynamically modify and add attributes? Take a look at the following principles introduction.
How to track changes: Pass a different object to the vue instance as an option to data, vue.js will traverse its properties and convert it to getter/setter with Object.defineProperty. This is an ES5 feature, and all vue.js does not support IE8 or lower.
Each instruction/data binding in the template has a corresponding watcher object, which records the attributes as dependencies during the calculation process. After that, when the dependent setter is called, the watcher recalculation will be triggered. The process is as follows:
Change detection problem: vue.js cannot detect the addition or removal of object properties. The properties must be on data to enable vue.js to convert it to getter/setter mode to be responsive. For example:
var data = { a: 1 };var vm = new Vue({data: data});// `vm.a` and `data.a` are now responsive vm.b = 2// `vm.b` is not responsive data.b = 2// `data.b` is not responsiveHowever, there are ways to add attributes after instance creation and make it corresponding. You can use the set(key,value) instance method:
vm. set('b', 2)
// `vm.b` and `data.b` are now responsive
For normal objects, you can use global methods: Vue.set(object, key, value):
Vue.set(data, 'c', 3)
// `vm.c` and `data.c` are now responsive
Initialize data: Although Vue.js provides dynamic addition of corresponding properties, it is recommended to declare all corresponding properties on the data object.
Don't do this:
var vm = new Vue({ template: '<div>{{msg}}</div>'})// Then add `msg`vm.$set('msg', 'Hello!')This should be done:
var vm = new Vue({ data: { // Declare `msg` msg: '' }, template: '<div>{{msg}}</div>'})// Then set `msg`vm.msg = 'Hello!'Component complete case
The examples introduced below implement the modal window function and the code is relatively simple.
html code:
<!-- Implement script to define a template --><script type="x/template" id="modal-template"> <!-- Whether the template is displayed is set through v-show="show", transition sets animation effect --> <div v-show="show" transition="modal"> <div> <div> <div> <!--slot is equivalent to header placeholder--> <slot name="header"> default header </slot> </div> <div> <!--slot is equivalent to body placeholder--> <slot name="body"> default body </slot> </div> <div> <!--slot is equivalent to footer placeholder--> <slot name="footer"> default footer </slot> <button @click="show = false">OK</button> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </script><div id="app"> <!--Set the vue instance attribute when clicking the button. The value of showModal is true--> <button id="show-modal" @click="showModal = true">show modal</button> <!--modal is a custom plug-in. The plug-in's feature shows binds the showModal feature of the vue instance--> <modal :show.sync="showModal"> <!--Replace the content of slot in the modal plugin and then be the header--> <h3 slot="header">Custom Header</h3> </modal></div>
js code:
//Define a plug-in with the name modalVue.component("modal", { //The template of the plug-in is bound to the content of the DOM element with the id of modal-template template: "#modal-template", props: { //The type is boolean show:{ type: Boolean, required: true, twoWay: true } }}); //Instantiate vue, the scope is under the id of the app element, new Vue({ el: "#app", data: { //The default value is false showModal: false }});css code:
.modal-mask { position: fixed; z-index: 9998; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, .5); display: table; transition: opacity .3s ease;}.modal-wrapper { display: table-cell; vertical-align: middle;}.modal-container { width: 300px; margin: 0px auto; padding: 20px 30px; background-color: #fff; border-radius: 2px; box-shadow: 0 2px 8px rgba(0, 0, 0, .33); transition: all .3s ease; font-family: Helvetica, Arial, sans-serif;}.modal-header h3 { margin-top: 0; color: #42b983;}.modal-body { margin: 20px 0;}.modal-default-button { float: right;}/** the following styles are auto-applied to elements with* v-transition="modal" when their visibility is toggled* by Vue.js.** You can easily play with the modal transition by editing* these styles.*/.modal-enter, .modal-leave { opacity: 0;}.modal-enter .modal-container,.modal-leave .modal-container { -webkit-transform: scale(1.1); transform: scale(1.1);}This article has been compiled into the "Vue.js Front-end Component Learning Tutorial", and everyone is welcome to learn and read.
For tutorials on vue.js components, please click on the special topic vue.js component learning tutorial to learn.
Since I haven't used the functions of components in depth in the project, I don't have a deep understanding of components, and the introduction is relatively superficial. Thank you for your reading.