The prosperity of the front-end development community has created many excellent frameworks based on the MVVM design paradigm, and the idea of modular development is becoming more popular. This has to mention Vue.js, a framework that focuses on the VM layer.
This paper mainly discusses the asynchronous loading and life cycle of vue.js component development neutron components. Reading this article requires a certain understanding of vue.js.
Note: Some of the example code in this article is based on the project that VUE-CLI initializes with the Webpack template.
Asynchronous components
To discuss asynchronous loading, you need to understand the next asynchronous component. The asynchronous component of Vue.js is to define a component as a factory function that triggers the factory function when the component needs to render, and caches the result for subsequent rendering. For example, register a global asynchronous component:
Vue.component(‘async-demo‘, function(resolve, reject) { setTimeout(function() { // 将组件定义传入 resolve 回调函数 resolve({ template: ‘<div>I am async!</div>‘ // 组件的其他选项 }) }, 1000)})
Asynchronous subcomponents are similar to global registrations:
Vue.component(‘parent-demo‘, { // 父组件的其他选项 components: { ‘async-demo‘: function(resolve, reject) { setTimeout(function() { // 将组件定义传入 resolve 回调函数 resolve({ template: ‘<div>I am async!</div>‘ // 子组件的其他选项 }) }, 1000) } }})
The first parameter of the factory function resolve
is a successful callback , the second parameter reject
is a failed callback , which can prompt the user to load the failure, and so on.
This setTimeout
is used only to simulate asynchrony, and in a real project, it should be implemented in conjunction with the Webpack Code separation feature for asynchronous loading.
Asynchronous loading
In a real project, if you do not use asynchronous loading, the JS, CSS, and templates of the Vue.js component are packaged into a. js file, which can reach a few megabytes or more, seriously affecting the first screen load time. So in the project we need to enable the asynchronous loading of the component.
Webpack Code Separation
There are two types of Webpack code separation, the first, and the preferred way to use the syntax that conforms to the ECMAScript proposal import()
. The second is the use of Webpack-specific require.ensure
. Let's take a look at the first type:
The
import () call is used internally to promises. If you are using import () in an older version of the browser, remember to use a Polyfill library (such as es6-promise or Promise-polyfill) to shim promise.
Vue.component( ‘async-demo‘, // 该 import 函数返回一个 Promise 对象。 () => import(‘./async-demo‘))
In the above example, the factory function mentioned earlier supports returning a Promise object, so you can use import()
this code separation method.
Local registrations are similar:
Vue.component(‘parent-demo‘, { // 父组件的其他选项 components: { ‘async-demo‘: () => import(‘./async-demo‘) }})
Essentially, the import()
function returns a Promise instance, and you can customize the process, as explained below.
The second type of Webpack code separation is this:
Vue.component(‘async-demo‘, function(resolve) { require.ensure([], function(require) { resolve(require(‘./async-demo‘)) }, function(error) { // 加载出错执行这里 })})
Looks cumbersome, if you use Webpack 2 and later, the second method is not recommended .
Life cycle Control
When using subcomponents (or called partial registrations), we may need to do something after the subassembly is instantiated (or is called created). In non-async subcomponents, it's easy to do this:
<Template><Div><My-demoref="Demo" ></my-demo> </ div></template> <script> import Demo from './Demo ' export default {mounted () { //here you can get the instance of the subassembly through the $refs of the component //you can think of the subassembly instantiation here. console.log (this. $refs. Demo)}, components: {mydemo:demo}}</ SCRIPT>
In the previous example, the Vue.js reference is used, so it is convenient to get an instance of the subassembly in the life cycle function mounted
, so that you can handle some of the things you want to do after instantiating the subcomponents in this function.
However, in an async subassembly, there mounted
is no way to get instances of the subcomponents in the function, so we need some tricks to implement this function.
<Template><Div><My-demoref="Demo" ></My-demo></Div></Template><Script>ExportDefault {Components: {Mydemo:() =Import'./demo '). Then (Component = {Cleans up cached component Definitions Component.default._ctor = {}if (!component.default.attached) {Save the created life cycle function in the original component component.default.backupCreated = component.default.created}Inject a special created life-cycle function component.default.created =function ( Sub-component has been instantiated //This is a child component VM instance console.log (this) if ( component.default.backupCreated) { //perform created in the original assembly Life cycle functions component.default.backupcreated.call (this)}} //indicates that it has been injected component.default.attached = true return component})}}</SCRIPT>
In the example above, we can see that we have some special control over the asynchronous loading of the component, which import().then()
is, after loading the child component's. js file, instantiating the callback before the subassembly, if it is necessary to handle the error condition import().then().catch()
.
The above code simply injects a created
function, if you want to inject other life-cycle functions, for example mounted
, it is similar:
<Template><Div><My-demoref="Demo" ></My-demo></Div></Template><Script>ExportDefault {Components: {Mydemo: () = import ( "/demo"). Then ( Span class= "hljs-function" >component = { component.default._ctor = { } if (!component.default.attached) { component.default.backupMounted = component.default.mounted} component.default.mounted = function (if (component.default.backupMounted) { Component.default.backupMounted.call (this)}} component.default.attached = true return component})}}</ SCRIPT>
With the above discussion, we can fully control the entire process of asynchronous loading of the Vue.js component, which is very helpful for components that require precise control over the loading of subassemblies.
Demo Project
According to the above idea, wrote a Bootstrap based on the asynchronous pop-up window Demo project:
Https://github.com/hex-ci/vue-async-bootstrap-modal-demo
Asynchronous loading of Vue.js sub-components and its life cycle control