The path to the migration of jquery to Vue

Source: Internet
Author: User

Background

After doing the three-terminal project of some super-complex L10 in the previous period, the group's small partners agreed that it was time to find a way to unify the development model in the group. Because with NIE that set of Jquery/zepto (the following jquery by default includes Zepto), 10 people have 10 habits, whether it is code organization, page structure, logical processing or ...

In fact, if like the general topic, short development cycle, short life cycle, with the traditional way of development is also good, do not need to post-maintenance, do not need to collaborate with many people. However, if the project is a little more complex, the problem comes, when the need for more collaborative projects, different people have different organizational code habits, maintenance efficiency is very low. So, we decided it was time to use some specific technology in a slightly more complex project, so that we could develop a project in some agreed-upon way to minimize the cost of collaborative development and maintenance.

As a result of this, I have used some mv* techniques to develop projects that require long-term maintenance, such as react, Vue. Considering the usability of Vue, I and my colleagues in the group decided to use Vue's technology, Vue for the view layer, Vue-router for single-page applications, Vuex I think we can do it for the time being, because most of the projects we do now do not require long-term maintenance. The data structure is not complex enough to be used in a dataflow tool, and management data can implement a very simple simplified version of Vuex according to Vuex's ideas.

Vue V.s. JQuery

Reason to put Vue and jquery together is not quite appropriate, one is the mv* architecture of the view layer of a library, one is the DOM operation with a relatively tight JS library, dry things are different, there is no direct opposition relationship. Many people in the community compare the two technologies that may be based on Vue's advocacy 数据驱动视图 and jquery's 直接操作DOM idea of writing pages in a completely different way. Although the two ideas are completely different, but can not be said to be used together, in some no way (will say later), the jquery and Vue with a piece is absolutely no problem, just said in the project is not pure 数据驱动视图 .

Of course, the combination of these two technologies is certainly not in the best practice, because there is no special case, so the use is a little trouble. The awkward thing is that none of the above-mentioned scenarios have occurred, and the components in our department's component libraries are all based on jquery, which has a pure UI component and a UI component that is strongly associated with the business. Where the pure UI component is good, write one with Vue or find a replacement in the Vue community (especially now that Vue's community resources are booming, there are many well-established Vue component libraries that are already very well-maintained), but business-related components are out of the question, That's why Vue and jquery are used together.

Fortunately, jquery and Vue are just different in programming thinking, two technology scenarios do not conflict, but in the development process need to pay more attention to, in 数据驱动视图 the code, but also mixed with some directly manipulate the DOM code.

Code Organization Build Tool

Before you say code organization, you have to talk about building tools, after all, construction is closely related to how your code is organized.

You are using Vue, building tools have what to say, no webpack and other better?

Yes, with VUE development project, Webpack is definitely the first choice, various loader help you simplify your code, there are a variety of other separate packaging schemes, JS lazy loading, etc. help you optimize the loading speed of the page.

however , the second embarrassing situation has arisen, all the projects within the department are built on FIS3, which means that all test machines and the fis3 of the system, you can not publish the local Webpack packaging.

Given the cost of migration, it is impossible for the department to move from Fis3 to webpack in the short term. So if you want to use Vue comfortably, you have to think of other ways. If you read the document carefully, in fact, Vue can be directly introduced to the JS file for non-building development, the need to do is to introduce the Vue JS file and then use the Vue object to initialize the application on the line, very simple. But without the build process, it means that we need to write the Vue component with a hard-to-read string template or a more difficult-to-read render function, rather than writing it like Webpack 单文件组件 .

This is obviously not tolerated. Written or read Webpack loader students should be clear, loader is actually a function of string processing, not what black technology, the reason Webpack added Vue-loader can use a single file component, is because Vue-loader will enter the .vuefile as a string, and then according <template> to, <style> and <script> tags to compile the corresponding content of the corresponding file type, and then to the downstream building plug-in processing. The Vue-loader works roughly as follows:

The so-called 单文件组件 allow developers to write in a file in the development phase, html模板 js and css then configure vue-loader the Webpack will help you do the next. In simple terms, split + Register components .

Then, in the process of building the FIS, it is not vue-loader that the construction process of the online machine is accurate. Because even if we write a FIS3 plug-in locally, and implement a string compilation like Vue-loader, the online machine is not installed, so the desire to write in a file is dashed. Then take a step back to think, in fact, written in three files can also be accepted, put them in a folder, the folder is named after the component name, although it is a bit less than a single component, but also is a (force) Single folder components, the code organization is still good. The __inline () feature in our FIS3 can be html introduced as a string js , so that the template can be written out of the component logic file so that it can be written as a js single-file component, such as templates and logic, and styles. And where you can reach it.

Code Organization

Although it is not possible to write single-file components, we can write and separate individual components and html js css put them in a single folder. Since the project is currently moving to Vue, there are a number of areas that need to be optimized in terms of code organization. The current code structure is:

There is a src folder and a file under the root directory fis-conf.js . The src folder loads the project code, fis-conf.js which is the FIS3 configuration file, which can be configured according to the project situation. Here src 's a look at the structure of the other files.

Components & containers & Plugins

The three parts are put together because they are part of the Vue component category, as the name implies, the + components components, the containers = container, and the plugins plug-in. The structure of the three folders is the same, the following component for example:

If we have a called some-component component, we will put this component, html the js css file in the some-component folder. Where, in the writing component's template, the style of the component is written, the logic of the index.html index.less index.js component is written, and finally, we will initialize the entire application place, that is, the component that will be mentioned later /src/js/app/app.js in the registration.

The difference between components,containers,plugins

In my application, I divided the Vue components into three categories, namely, components, container components, and plug-ins.

Container component: the outer component used for routing initialization. It's a bit like the part of the React-redux technology stack that's linked to the store, but instead of differentiating components by the flow of data layers, they're divided by the structure of the page. The container component is used only for vue-router the <router-view> replaced component, and the components contained in the container component are entered as normal components.

components: Other components that are called through HTML tags in addition to container components. In addition to the container components, other components that have been called with HTML tags are entered as normal components. Common components are a bit like higher-order components in React-redux. In react, higher-order components are recommended to be used as pure render (purely rendered) components, that is, to render the view based only on the props passed in by the parent component (the container component), without its own state. But here again, for the time being, the data layer is not discussed, and ordinary components are simply used as subcomponents of container components. The internal state of the component needs to be retained and discussed later.

plugin: the component that needs to be called in JS. Libraries that use data-driven views such as Vue or react, if you just use HTML tags to write components to HTML, and then update the view by modifying the data, are possible in most cases, but there are limitations in some scenarios, such as the need to develop an alert component. The call alert is obviously supposed to be in JS, so Vue has another component called a plugin.

Component (component, container) notation

The notation is the same for a component, whether it is a normal component or a container component, except that there is a difference in how it is registered. First of all, we can write the HTML template of the component first:

// some-component/index.html<div class="some-component">    ...</div>

After that, we can start to write the logic of the component:

// some-component/index.jsnie.define(‘someComponent‘, function() {    var component = {        template: __inline(‘./index/html‘),  // 引入刚刚的html模板        data() {            return {                state: $store.state,     // 绑定全局视图状态                ...                      // 组件内部状态            }        },        created() {            ...        },        ...    };    return component;});

In the case of the FIS configuration file, there is no way to use the COMMONJS or ES6 modular scheme, so here directly using the NIE class Requirejs modular scheme to define our Vue components, anyway, the beginning also mentions that in the short term is not able to get rid of the NIE library based on jquery ┑ ( ̄д ̄) ┍, rather than use it.

After that is the style of writing components, there is nothing to say, only with the attention of the loader without webpack to the component class plus namespace, we need to be careful not to have the same class global. My approach is that each component's outer layer writes class as the component name, and the inside of the component is wrapped in this class so that the style does not conflict as long as the component name is not duplicated:

// some-component/index.less.some-component {    ...}
Plugin (plugin) notation

The plugin is a bit more complicated to use, in the returned object we need to manually add a install method, in the subsequent registration process, Vue will call this method, and the Vue object as the first parameter passed this method:

nie.define(‘Alert‘, function() {    var Alert = {};    Alert.install = function(Vue, options) {        Vue.prototype.$alert = {            show: function() {            },            hide: function(callback) {            }        };    };    return Alert;});
Common components (component) registration and use

In the Initialize Vue app app.js , register the component:

// /src/js/app/app.js// 引入组件的js文件__inline(‘/src/components/some-component/index.js‘);// 加载之前定义的nie组件var someComponent = nie.require(‘someComponent‘);// 注册全局组件var components = {    ‘some-component‘: someComponent,    // ...};for (var key in components) {    Vue.component(key, components[key]);    // 注册全局组件}

Once registered, you can use some-component tags to invoke components in HTML.

// another-component/index.html<div class="another-component">    <some-component></some-component></div>
Container components (container) registration and use

Because the container component is a component of an element that overrides Vue-router, the registration of the <router-view> container component is performed when the Vue-router is initialized. In the same way app.js :

// /src/js/app/app.js// 引入容器组件的js文件__inline(‘/src/containers/Main/index.js‘);// 加载之前定义的nie组件var Main = nie.require(‘Main‘);// 路由对象var router = new VueRouter({    routes: [        // ...        {path: ‘/main‘, component: Main},        // ...    ]});// 初始化vue应用new Vue({    el: ‘#app‘,    router: router, // 注册路由,路由组件也就跟着一起注册了    // ...})

Next, in the place where the route view is switched, the registered routing component automatically replaces the element based on the routing match <router-view> .

Plug-in (plugin) registration and use

Plug-in JS, called the Vue.install() method, next in app.js :

// /src/js/app/app.js// 引入插件的js文件__inline(‘/src/plugins/Alert/index.js‘);// 加载之前定义的nie组件var Alert = nie.require(‘Alert‘);// 注册插件var plugins = [    Alert,    // ...];plugins.forEach(function(plugin) {    Vue.use(plugin);});

Once registered, there will be one more object on all the component instance objects $alert , including show and hide methods, such as in an object:

// some-component/index.jsvar component = {    // ...    methods: {        alert() {            this.$alert.show(); // 调用Alert插件        }    }}
As1

The CSS folder will contain a index.less style file for the application portal, which introduces the styles of each component:

// /src/css/index.less// 容器组件@import "../containers/Main/index.less";// 组件@import "../components/some-component/index.less";// 插件@import "../plugins/Alert/index.less";

You can also put some other style files according to the project requirements.

IMGs

IMGs folder to put the picture resources used in the project.

Inline

The inline folder will need to edit the content of the HTML file, and then through the FIS inline into other HTML, easy to edit to find the corresponding content location.

Js

The JS folder structure is as follows:

Among them, app/app.js is our application of the entry file, that is /src/index.html directly introduced in the JS, in which the registration of components, register plug-ins, initialization of the route, the application of the initialization Vue.

Common folder in the JS file each corresponding to a global object, the object has some specific methods can be called at any time, this structure can be organized according to the different habits of individuals, my structure is:

Api.js: stores all interfaces that interact with the background. Called through in the component logic $api.someApi(params, successCallback, errorCallback) .

Common.js: tool method. by $common.someFunc() calling.

store.js: A Vuex Store object that holds the global view state, which is the $store.state that was previously bound to the component. The Data Flow section will be mentioned later.

About Data Flow

In the framework of data-driven views, there is the part of the data that the view relies on. Because there are different views in the application that may depend on the same data, multiple copies of the data may be dependent on the same view. Conversely, there may be many places where the same data is updated, and multiple copies of the data may be updated in the same place. This data is referred to as the state of the view, and is globally called the Global view state . Because of the mapping relationships mentioned above, it is a nightmare to maintain when the view state is complex to a certain extent. To do this, you have the following data flow tool.

Redux

Redux was originally a data flow scheme that used react to develop a single-page application with a higher degree of acceptance. Redux advocates absolute data flow unidirectional and data immutable (immutable). React components are also derived from the redux of the container components and high- order components two kinds. The container component is used to connect to the Redux store, and the store passes the state through props to the container component, and the container component has a non-global state inside it. Other components that are located inside the container component are considered best practices in best practice as high-level components, which are pure render components. The pure rendering component renders the view based on the props passed into the container component without an internal state. This, coupled with the redux itself reducer immutable to change the state process, can improve the rendering performance of the react component.

The above paragraph seems to be very complex, rather than complicated, rather cumbersome. Because redux in order to ensure the controllability and traceability of data flow in complex projects , pre-defined a lot of rules and regulations, when writing code is more cumbersome, in exchange for large projects in the data layer maintainability.

So I think, in the project data layer is not complex to a certain extent, the use of Redux is not cost-effective. By the way attach an article of Redux author you might not need Redux.

Vuex

Vuex is a data flow tool for Vue developed by VUE authors. The general idea is similar to Redux , but there is a little difference in the way that API calls and data flow. For example, the value you want to change needs to be called, which is similar to the vuex state store.dispatch(‘some action‘) action one action in which Redux action you can perform an asynchronous operation and then action invoke the store.commit(‘some mutation‘) trigger mutation mutation in the redux reducer , the operation is state straightforward and cannot be done asynchronously. ( vuex-v2.0.0 it can also be called from the beginning Vuex external store.commit() mutation ).

With Vuex, you can change and receive changes to a container component as a bridge, rather than as redux, but you can alter the global state by an action from any component, dispatch and then automatically update the corresponding view of the component that relies on the global state. This architecture is relatively easy to use in less complex projects , and we can track changes in data flow and have some maintainability. I personally think that the practice of not limited to redux is more comfortable to write, but when the application is complex to a certain extent, the maintainability of the data will be reduced. Because that's when the logic of the data is distributed inside each component, not just the container components, which can be cumbersome to maintain.

So, if the application is more complex, we can use Vuex to implement the best practices for Redux, which is the container components and common components I mentioned earlier. The container component is used to deal with the Vuex store, while the internal common components are rendered as pure rendering components through the props passed into the container component. This enables redux best practices for complex projects through Vuex.

The Data flow tool used in the current project

Said for a long time, in fact, now in the project does not use any data flow tool, the reason is mentioned at the beginning of the article, that is, currently we do the project data layer is not complex, even can be said to be very simple. so I think, in the current complexity of the data, there is no need to use development efficiency to replace the maintainable line, especially the current majority of projects are not required for long-term maintenance of the topic type.

So there is a global store mentioned in the previous Code organization section, which is bound to the top of each component $store.state , which becomes data $store.state the global view state . Updates can be made anywhere in the app, and $store.state other views that depend on it are updated state accordingly. The current scheme is fully sufficient for the present complexity, and does not affect efficiency in writing.

The meaning of migrating from jquery to Vue

Facilitates team collaboration, multi-maintenance

The opening point is that the root cause of the migration to Vue or the development of complex projects requires teamwork, and without a set of agreed-upon project architectures, it can be painful to collaborate in multiple people or across-the-board maintenance.

With Vue, you can encapsulate the templates, styles, and logic of reusable components for future use. Because Vue provides a set of component lifecycle hooks, so when we write component logic, we don't jump out of the life cycle, and without jquery, 10 people have 10 kinds of writing problems.

In addition, we have introduced vue-router to be used as a single-page routing scheme. Without this before, the same, the thematic structure is uneven, some of their own implementation of the single page, some pseudo-single page, useful third-party routing library, and some have not even made a single page. In the face of such a problem, if just a person development is OK, only use according to their own habits to be good, but once more people need to collaborate or later maintenance, the problem comes. So with the Vue-router, a single page of the scheme unified, different projects with a single page solution, whether it is team collaboration, or future maintenance, are at a glance.

With regard to the data flow tool, which has been analyzed in detail, my opinion is based on the complexity of the data associated with the view, from low to High, 简版全局store > vuex > redux .

Thus, for the project as a whole, from the perspective of MVVM, the M (data model) layer unified the scheme, the V (view) Layer Unified the scheme, front-end routing is also unified scheme, the rest of the VM (view Model ViewModel, which is the state of the component) is free to play when the project is not complex, That is, not too much to consider whether the component should maintain a local state, if the project has reached a certain degree of complexity, we can consider the practice of Redux respected container components and pure rendering components of the idea.

Therefore, I think that through this integration in the technical solution, can greatly reduce the cost of team collaboration and post-maintenance.

Help improve development efficiency

For items that need to render data that is sent back to the background:

Before using Vue, we took the data from behind the scenes, then processed the data to some extent, then converted the processed data into rendering logic, and manually manipulated the DOM update

With Vue, after we get the data from the backstage, we process the data and hand it over to the data layer, Vue automatically compares the data before and after the change, automatically updates the DOM

So the improvement in development efficiency is mainly reflected in the use of Vue, we do not have to consider the rendering logic, do not have to handle the DOM manually, this part of the thing Vue help us do, we only use the mind on the business logic. I think that's what we should be thinking about when we do data-type projects. Of course, the pure display class, show animation category except items.

Helps improve rendering performance

This is often the case in a project: Get an array from the background and render the array as a long list. During user interaction, users can filter or sort by entering specific search criteria. In this scenario, in addition to the benefits of using the data only to manipulate the rendering logic mentioned above, Vue caches each element of the list and makes a comparison with the new data (if v-for the key is set for each element in the feed), and the error is updated, Thus improving rendering performance.

The shortcomings of Vue

Animation

Even in projects with partial data types, there may be strong animation requirements, especially in game department projects. In contrast, using Vue to write animations is not as intuitive as jquery. The reason, I think the idea of animation and business is the opposite. The core of the business is data, so when we write the business code, the center should be in the processing of data, the rest of the update DOM is given to the framework, but when writing animation, the body of the animation is the DOM, so if we want to change the data to control the animation is a bit strange.

Vue Animations:

jquery animations:

But although the idea is not the same as before, but jquery can be achieved by the animated Vue can be achieved, so it is not a big problem, but in writing animation may be more than jquery directly manipulate the DOM to take a few more steps.

Where it needs to be improved

Component JS File Introduction method

In the previous code in the organization part of the details of how to write a component, the component's JS file needs to be __inline() introduced into the portal file using the Fis3 method, app.js and then through the nie.require() method to load the Component object, and then use the object to register the component. The whole process is a little cumbersome to use because it is a compromise without the use of ES6 module modules. In the same group of research found that now FIS3 plug-ins and babel other plug-ins to work with the conflict, and so after this conflict resolution, with the ES6 modular scheme, the code will be more concise.

Places to note with Vue + jquery

Notice how the two technologies update the DOM

Using jquery, we are directly manipulating the Dom,dom update is synchronous . With Vue, which wants to update the DOM, we manipulate the data directly, and because Vue avoids frequent updates against old and new data, Vue places the update Dom in the next event loop , meaning that the DOM update is asynchronous .

As we said earlier, we now have a very awkward situation where we have to use both techniques at the same time, so we need to pay attention to the two methods of DOM update when we are developing, to avoid the DOM not being updated when the DOM is taken.

Note the Vue component life cycle + Vue-router Routing hooks

The life cycle of the Vue component is not directly related to the DOM in terms of the entire process from initialization to destruction, so with jquery, there are times when you need to be especially careful when accessing the DOM, It is possible that the DOM has not been rendered in some life cycle hooks.

Vue-router also has the Route hook function , in the use of the time also need to pay attention to the corresponding hooks can not get to the DOM problem, especially the container components with the transition situation.

Reference

    1. Vue
    2. Vue-router
    3. Fis3
    4. You might not need Redux
    5. Vuex
    6. Vux
    7. Element

This article from the NetEase cloud community, by the author Chamacuaro authorization issued.

Original: jquery to Vue's migration path

More NetEase research and development, product, operation experience Share please visit NetEase Cloud Club

The path to the migration of jquery to Vue

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.