preface

At the end of last year, the company needed to launch a new line of business, and it needed a new front-end framework technology, Vue, to do it. I am very happy to be one of the pioneers. Before this, I did not have much experience in Vue development, and I just stayed in the learning stage. Moreover, the front-end framework the company has been using is jQuery, so the company has no experience in Vue framework development. The outside world is changing rapidly and I am always interested in new technologies, so I always hope to have the opportunity to develop projects with a new framework. I am very happy to have this opportunity, although there is a long way to go, everything from scratch to explore.

But what is a pioneer? This is!


Vue 

Needless to say, Vue is one of the hottest front-end frameworks out there today. There are just two pieces of advice for beginners:

  1. How to learn: I recommend going directly to the official Vue documentation, which is pretty good and has a smooth learning curve. This is also an advantage of Vue.
  2. What to look out for: Understand the framework. The idea behind the previous generation of frameworks, represented by jQuery, was to manipulate the DOM directly and update the view. At present, the mainstream front-end frameworks represented by Vue and React are data-driven, leaving the work of data operation and view update to the framework. The two ideas are quite different. If you have been exposed to jQuery a lot before, you need to pay attention to not be affected by the development thinking of jQuery. If necessary, you can discard the previous thinking and accept and develop in a new way of thinking. There is no more talk about how to get started with Vue, go directly to the official documentation to start the learning journey of Vue. I would like to share with you some typical business scenarios, solutions and experiences in the process of this project, which I hope will be helpful to you.


Common service scenarios

1. Selection of global registration and local registration

Based on Vue development, the most exposed is componentized development, which is one of the front-end development pain points solved by the framework. In Vue, component registration is divided into global registration and local registration. What are the differences between the two and common business scenarios?

  • Global registration

    Vue.component('component-name', {
      / /... Options...
    })Copy the code

    A web page, generally by the basic function block, and then by the box model reasonable layout, then formed our common web page. These basic functional blocks, in turn, are made up of basic elements, such asbuttonLabel,inputTags and so on. I think you all know that. On this basis, the entire page basically complies with the principle of uniform page design, basic elements are generally designed to be uniform, but also to be reused in multiple places, so this is where the global component comes into play. We package multiple reusable elements into global components, unified maintenance of functions and design, and call directly where needed, without secondary development. This is where global components come in handy.

  • Local registration

    var ComponentA = { /* ... */ }
    new Vue({
      el: '#app',
      components: {
        'component-a': ComponentA
      }
    })
    Copy the code

    A web page generally corresponds to a Vue instance, which is the root component, the outermost component. On this basis, we usually divide the interior into several modules based on functions, such as headers, content areas and so on. These modules are individual components. This is the business scenario of local registration, where internal functions and business logic can be maintained independently, although some reusability is sacrificed (but it can be reused in internal components as well). This way, the code and business logic are clear, rather than being all jumbled up in the outer components.

Therefore, global components are more inclined to build basic components, while local components are more inclined to business modules, and different components are divided according to business.

Conclusion:

  • The biggest feature of global components is reuse, to play this feature to register into the global, otherwise it will cause a certain waste. The most common business scenario is the base component, such asbutton,inputAnd so on. There are also many good component libraries out there, such asiView 。
  • The biggest feature of local components is that the related business logic is maintained independently, which reduces the degree of coupling and improves the clarity of business.



2, how to grasp the business boundary

As mentioned above, when we componentize development, we need to divide modules by function. The division of modules, being too detailed or not specific enough, can have an impact on the development process. Therefore, how to divide modules, or how to grasp the functional boundary of a module, clear its business scope, also need our attention. Generally, we can think from the following questions:

  • What does it need to do? What don’t you have to do?
  • What does it expose? At the same time to accept what?

After considering these problems, the module structure is basically clear.

  1. What the module needs to do and what it does not need to do first, let’s start with these two questions, which are also to determine the functional boundaries of the module. For example, if we design a popover component, we start with these two questions, what does it need to do, pop up, show content, close, and nothing. It doesn’t care what it shows, that’s what it doesn’t have to do. Starting from these two problems, to grasp the functional boundary of the module, the module structure will be more clear.
  2. What the module exposes to the outside, what the module accepts to the outside is really thinking about how the data is communicated. In Vue, the most common communication is between parent and child components. The parent component passes data to the child component via props, and the child component sends information to the parent component via emit triggering custom events. This is the correspondence between father and son. But one point that is easily overlooked is that when props is a reference type, the pass is not a one-way data flow. Because the child gets a reference, it can change the value on the reference object, and the parent’s data changes accordingly, so it becomes a two-way data flow. This should not be done, child components should not directly modify the parent’s data, and when you do, Vue will tell you not to do so. Therefore, in general, only basic types of props are passed, and reference types are not passed. In addition, when defining props, write the types and default values, and verify them once. However, there are some scenarios where passing a reference type is more convenient. I personally fall into two categories:
    1. When the component is globally reusable, such as input, button, and other globally reusable custom components, only primitive types are passed.
    2. When the component is used within a functional module, such as a locally registered component, because it is confined to a module and has a large amount of data, passing the reference type is easier. Remember, however, that you cannot directly modify the value of a reference object. If you want to operate on a reference value, you can assign the value to the data or computed property and perform the corresponding operation. This is also done to constrain data changes to the top-level component, which has the advantage of having a clear data flow with only one place to modify the data. The traceability data is also easier to follow. Because frameworks are data-driven and the problems they face are all about data, constraints on how data is structured, where it comes from, where it goes, and how it is modified, or data management.)

This is the way to think about outward acceptance. What about exposure to the outside, or what to offer to the outside?

Componentized development has a high degree of internal autonomy, so when a piece of logic goes to a component, it needs to be told to the outside world after the component has finished processing it. Here is a principle to note:

I should be told what happened to me, not what are you doing?


It’s a bit of a mouthful, but if you think about it, it’s the latter that determines the external behavior, so there’s coupling, and it doesn’t make sense. The former just tells the outside world what’s going on, and it doesn’t care what the outside world does in response to that information, and that’s what makes sense. Although it may sound, it may seem similar.


3. Data configuration

As mentioned earlier, restrict the structure, source, direction, and modification of data, or manage data well. Because data is driven, we need to pay close attention to data, properly design data structures and manage data. Data configuration is one of the data management methods I use most frequently in projects, and it can be seen everywhere in many framework details.

What is data configuration?

For example, the most common business scenario, background management.



The general code structure is as follows:

<div id="manage" class="manage">
    <div class="header"></div>
    <div class="main">
        <div class="sidebar">
	    <ul class="menu" v-for="menu in menuDef" :key="menu.type">
	        <div class="menu-title">{{ menu.name }}</div>
		<li class="sub-menu" v-for="submenu in menu.submenu" :key="submenu.type">{{ submenu.name }}</li>
	    </ul>
	</div>
	<div class="content"</div> </div> </div> <script>type: 'manage', name: 'Management Services', extClass: 'server-manage' },
        { type: 'list', name: 'Service List', extClass: 'server-list'},]; Var subNews = [{type: 'internation', name: 'International News', extClass: 'i-news' },
        { type: 'home', name: 'National News', extClass: 'home-news'},]; Var menu = [{type: 'server', name: 'service', extClass: 'server', submenu: subServer },
        { type: 'news', name: 'news', extClass: 'news', submenu: subNews } ]; Var manage = new Vue({el:'#manage',
        data: {
            menuDef: menu
        }
    });
</script>
Copy the code

This is a simple background management page, the left panel has a series of menu items, the right content area changes based on the left menu switch. The menu on the left has the same structure, just different data. It can also be seen in this example:

  • The relationship between page structure and data. The page structure is just an outer representation of the data and varies based on the data structure
  • So a little more abstraction, abstracting the data away from the page structure, is the data structure that the page needs.
  • If we take the data structures that are stripped out and maintain them separately, that’s what I mean by data configuration.

What are the benefits of data configuration?

  • I just focus on the data structure, not the page structure, so even if I add or remove menu items, or change the structure level, I just make adjustments in the data layer, and I don’t need to go to the logical layer or the page layer to make changes.
  • This approach is quite maintenance friendly. Both extension and maintenance are quite convenient. I remember that during the development of my project, the background management page had been changed to some extent. When PM told me what needed to be changed, I had basically changed it. Because I only need to change the data layer, like IF I modify a configuration document, as long as the document annotation is written clearly, it is the same convenience for anyone to change.

Suitable scene:

  • Similar structure, just different data.
  • This is suitable for a wide range of scenarios, the basic can also be reused with components to achieve.

As mentioned above, the content area on the right is changed based on the menu switch on the left. This implementation is based on the implementation of routing, Vue also provides vue-Router official routing library, specific documentation is also available to see the official documentation. In this case, for the management of routes, the way of data configuration can also be used to manage the configuration items of routes in a unified place, and can also be nested with other data structures. For example, follow the example above:

Var serviceRoutes = {serviceManage: {path: // route configuration // compons.serviceList is the content component of the content area.'/serviceManage', name: 'serviceManage', component: compons.serviceManage },
    serviceList: { path: '/serviceList', name: 'serviceList', component: compons.serviceList} }; / /... Var subServer = [{type: 'manage', name: 'Management Services', extClass: 'server-manage', router: serviceRoutes.serviceManage },
    { type: 'list', name: 'Service List', extClass: 'server-list', router: serviceRoutes.serviceList }, ]; / /... // How to use // All the routing configuration objects configured above are put in. var routerList = [serviceRoutes, articleRoutes, ...] ; Var router = []; routerList.forEach(router => { router.push(router); }); Var manage = new Vue({router, //'#manage',
    data: {
        menuDef: menu
    }
});
Copy the code

In the later maintenance of this piece, only the configuration and maintenance of data structure and routing are needed.


4. How to use jQuery elegantly

In the development of Vue, most of the time you don’t need to manipulate the DOM yourself, you just need to pay attention to the data layer, through the data driven, by the framework to complete the view update.

But in some special cases, you do need to perform some low-level DOM operations, such as hover a module to appear in a tip, or hover a structure to appear in a toolbar. In this business scenario, you might expect this logic to be handled within the module while mouseEnter and Mouseleave events are being processed. This is a typical JQuery approach to this problem, and there are many disadvantages to this approach:

  • It can’t be reused, so what you’re doing, you’re only doing it in one module, you can’t reuse it anywhere else.
  • High coupling, because the business itself can be spun off and maintained as a separate component. If it is included in other modules, the internal logic and structure of the module will be unclear.
  • Later maintenance is difficult.

What if it’s implemented in Vue?

Vue provides an interface for us to customize directives, which is a good way to solve the problem in this business scenario. In Vue, it is not recommended that you do some DOM manipulation directly inside the instance. If you need to do some low-level DOM manipulation, you can pull it out of the custom instructions. And when needed, I directly use it, perfect solution to the problems of the above solution.

<div id='app' @mouseenter='handleMouseEnter' @mouseleave='handleMouseLeave'></div>
<div id='tip'></div>
var app = new Vue({
    el: '#app',
    data: {},
    methods: {
        handleMouseEnter: function () {
            document.querySelector('#tip').style.display = 'block';
        },
        handleMouseLeave: function () {
            document.querySelector('#tip').style.display = 'none'; }}}); // Vue way to correctly select <div id='app' v-tip='{ text: tipText }'></div>

Vue.directive('tip', {
    inserted: function(el, binding) {
	var tipDom = document.querySelector('#tip');
	if(tipDom) {// If it already exists, there is no need to create DOM //do something
	} else{// Create DOM tipDom = document.createElement('div');
            tipDom.setAttribute('id'.'tip');
            document.body.appendChild(tip);
            // doSomething} // Register the event el.adDeventListener ('mouseenter'.function() {
            // do something
	});
	el.addEventListener('mouseleave'.function() {
            // dosomething }); }}); var app = new Vue({ el:'#app',
    data: {
        tipText: 'Hello, world! '}});Copy the code

This is an elegant implementation of Vue in this kind of business scenario. The business logic is well separated into custom instructions, one implementation, multiple reuse. Code logic is clear, low coupling, good maintenance and so on. It’s like a spring breeze

For specific knowledge points and application of custom instructions, you can go to view the official documents of custom instructions.


At the end

During the development process, there were a lot of scenarios that were a little bit more detailed, such as how to animate gracefully with Vue, how to communicate with father and son, how to communicate with brother, etc. These details are relatively trivial and would be too long to explain. Later readers encounter related problems, can also be another length, and then give you chit-chat ~

That’s all for this article.

Hello, world!


Zhihu: Chen Yongsen