Project warehouse address: github.com/konglingwen…
Online preview of the project: http://123.57.204.48:3000
Related articles: Vue Full Stack Technology reconstructs Bytedance recruitment Website
preface
Vue -bytedanceJob 2.0 is finally completed, and this article is a continuation of vue’s full stack technology reconstruction of Bytedance recruitment website. This article will focus on the main functions added in the new version of the website, and will analyze the interesting places in detail, as well as the resummary of the whole project (technology stack) and the implementation analysis of some typical business logic in the project. At the same time, the 2.0 version of the project also added several API types of custom components, such as progress bar pop-up window, message notification, data loading and other components, I will also analyze the function characteristics and development process of these components. So the following introduction is full of dry goods, after reading don’t forget to like the message!
Increased demand
The implemented
- A user logs in to an account by email
- Select local resume file to upload
- Parse the locally uploaded resume file
- Save your newly written resume
- Preview your latest resume
- Download the resume file to your local PC
- Load data on each page
loading
prompt - Dynamic top of the job search box
- resume
Save the cancel
Operation bar dynamic bottom suction - Add some animations when switching pages
- Overall project optimization
Unrealized.
- Email Account Registration
- Mobile phone Login
- A resume
- Further project optimization
Partial screen shots
Resume Preview page
Resume editing page
In addition to all of the requirements listed above, there are many refactorings for some functions. The inclusion of several components that can be invoked using an API was also implemented through a manual development package, replacing components introduced in the previous release using a third-party component library. After the actual test of the final display effect of the project, the overall integration of the business and the customization of the basic functions of components have been greatly improved. Not only are the redundant codes reduced, but also the business logic is more consistent.
There are a lot of improvements, but also some shortcomings, compared with the third-party mature class library in the test case is not comprehensive, some areas still need further test improvement. Second, if you need to introduce these components into your own projects, you need to do secondary development because these are business components and not generic components. If you have any questions or good suggestions in the process of using, please feel free to mention issues!
Three new additionsAPI
component
The following components support API calls. The calling methods of each component in this project are mounted to the prototype object of the Vue instance. Depending on the specific use case, you can also import them into specific files for use
Data loading unitLoading
The basic way of using Loading components is the same as that of most class libraries. I also refer to their API design methods and parameter passing methods to achieve this. As shown in the figure, loading has two kinds of invocation states, one is local invocation (by instruction), and the other is method invocation. Here is a simplified version of the code to demonstrate.
Unified note: code demo this are Vue instances
API mode
/* @params' position 'is the specific positioning information for full-screen loading. The default position is 0. You can adjust the position as required */
const loading = this.$loading({ position: { top: 0.left: 0.right: 0.bottom: 0}});// Actual close in place
loading.close()
Copy the code
Call as an instruction
<template>
<div v-loading.scrollFixed="true"></div>
</template>
Copy the code
The binding value of the instruction can be replaced by a component state variable to flexibly control the loading state. ScrollFixed is the instruction modifier that supports transfer. Its function is that when the DOM element bound to loading is rolled out of the page viewport, the loading icon is always displayed in the center. You don’t have to worry about the trouble that element scrolling brings loading and disappears into the viewport.
View the component code point here
Progress bar popup componentpopup-progress
The popup-progress component can be thought of as a pop-up progress bar component, but for lack of a better name, it will be called that. For those of you who have used some of the library components, it’s easy to imagine that this is a combination of the pop-up alert and progress bar. Since it is a full-screen component, the concept of singleton pattern, one of js’s many design patterns, is introduced here. This component design is also the use of this mode, with most of the components of the box class is also a more classic way to achieve it. So what makes it different from other modal box components?
Because the scroll bar is a constantly changing state, this component is called differently from other components that return promises, such as alert,confirm,prompt, and so on. The reason why these components can return promises is that after the component is mounted, it needs to wait for the user to operate the state. The state of the component itself is fixed without manual operation by the user, which is quite similar to the promise in JS. So it’s not surprising that the component call returns a promise. However, popup-progress in this article is different. The progress of the progress bar is a value that needs to be changed after the component is mounted to meet business requirements. Obviously, passing a fixed state value property to the component is not an option, so it is more appropriate to return the instance itself after the component is created. Such processing returns the component instance itself in the context of the live text in which the component is invoked, rather than passing complex data type parameters such as functions at component initialization time for processing within the component. This approach also makes it convenient for components to register to listen for custom events. Not only can it chain-call the API, but I personally find it more elegant than passing listener function arguments to components. Having said all that, the only thing that makes the code demo more intuitive is that it’s not.
// Create a progress bar popup
const popPro = this.$popupProgress();
// Update the popPro progress value in a specific use case, demonstrated here by 'setInterval' simulation
const timer = setInterval(() = > {
// The value of the progress bar is' value '. The value must be between '1' and '100'
popPro.value += 10;
}, 300);
// Listen for upload termination event (triggered after clicking 'cancel' button)
popPro.$on("abort".() = > {
// Stop the upload process and close the popup progress bar
popPro.close()
});
// The 'SUCCESS' event is triggered when the progress bar is installed to '100%'
popPro.$on("success".() = > {
clearInterval(timer);
// Close the popup progress bar
popPro.close()
});
Copy the code
The code for registering events above can be abbreviated as
this.$popupProgress()
.$on("abort".() = > {
})
.$on("success".() = >{});Copy the code
This concludes the analysis of the Popup-Progress component. If you have a good suggestion or question, feel free to issue it
Check out the code point github.com/konglingwen…
Message notification componentmessage
The introduction
The Message component is one of the most commonly used components in everyday business development, and for those of you who are looking for quick development, you can simply introduce a generic library (which IS what I did before). Common library components are common because they are designed with a lot of business scenarios and use cases in mind, and naturally contain a lot of functionality. However, for projects requiring long-term maintenance and update, there will be many problems. First, the UI style of common components is not exactly consistent with its own business requirements, and secondly, the amount of code will be heavy, which are unavoidable problems. Therefore, when we encounter similar business requirements, it is often better to implement ourselves, which not only makes the overall code of the project more cohesive, but also improves our own technical level.
Basic introduction
The Message component has three message states: success, failure, and warning, which should be sufficient for projects of average complexity. Small as a sparrow is, it has all the functions that a message notification component should have, but not as many parameters as a wheel can transmit. Just the use case for this project is enough, and interested students can use this as a basis for secondary development. Welcome to mention PR and issue. The use of component apis also maintains a common design approach. The specific demonstration is as follows
// The successful message status is used as an example. This.$message({message:" success",type:"success"}) // support this.$message. Success (' success ') Default: '3000ms' this.$message({message:" success ",duration:2000})Copy the code
In contrast to the Popup-Progress component described above, the design pattern underlying the API is factory pattern. All created component instances are placed in a queue before being destroyed. Methods like creating components in the code add a new message to the view each time they are called. The display is arranged as shown in the picture. So in the use of time can be called multiple times.
Check out the code point github.com/konglingwen…
The application of recursion in business
These two typical use cases seem to have nothing to do with recursion in the title, but one of the functions in this example is actually implemented using recursion. Going back to the features in the image itself, it’s not complicated to dynamically suck the bottom or top of a page in a certain part of the scrolling process, but this is one of the details of the implementation.
We know that one of the DOM elements has an attribute value offsetTop. This represents the distance offset from the top of the nearest parent element, so here we have another property offsetParent, which represents the nearest parent element of the element. With these two attributes, we can easily get the offset from the parent element in each direction. So if we want to get the distance of the element from the top of the page how do we get it? If the offsetParent attribute of the element is the root element HTML, simply get the offsetTop attribute of the element. If there are multiple parent location elements, we need to manually find the offsetTop of the element’s offsetParent element for summation. This approach will eventually get the results right. The problem is that this approach doesn’t work well in scenarios with complex page layouts. If the element hierarchy to be calculated is deeply nested and there are many parent positioning elements, the calculation is very heavy and error prone. I view the stepwise search for the offsetTop value of the parent element as a manual recursive process, and everything that can be solved programmatically will be solved programmatically. Let’s just put the code out there
function getOffsetTop(node, targetOffsetParentNode, offsetTopSum = 0) {
offsetTopSum += node.offsetTop;
if(node.offsetParent ! == targetOffsetParentNode) {return getOffsetTop(node.offsetParent, targetOffsetParentNode, offsetTopSum);
}
return offsetTopSum;
}
// Use case: Get 'offsetTop', the distance from '$0' to the top of the root element
const offsetTop = getOffsetTop($0.document.documentElement)
Copy the code
How does this top distance relative to the root relate to the effect in the implementation diagram? By comparing this value with the scroll coordinate of the scroll container, we can achieve the function of the scroll toggle positioning element, which is not analyzed here.
Function implementation source code
The job search bar scrolls to the top here
Resume editing operation bar dynamic suction bottom github.com/konglingwen…
See more tool functions for this project here
Server interface fetching
In terms of how the server interface is fetched, I will also briefly talk about the whole process of the project’s back-end interface proxy. Start by looking in the Network panel provided by browser developer tools, then go through the actual debugging one by one using Postman. Having said that, I’d like to say a few things about climbing data interfaces. Debugging interfaces with tools and debugging interfaces with code emulation are really two different things. Unexpected problems often arise due to inconsistent operating environments. Here I will take the interface request of login class that strongly depends on the interface state as an example. This kind of interface requires many private fields to be carried in the request header and sent to the server due to the need for authentication. Some request header fields are not allowed to be carried by the browser by default, such as referer, Origin and so on. So you need to carry this kind of information request of interface in the browser could not be achieved, so we often need a proxy server to forward these interfaces, actually this project is to do so, and forward agent request way is to use a third party middleware, interested students can click here to view the specific implementation.
In addition to the above mentioned, the request interface of token authentication type has made me dig deeper, and this project is implemented by token authentication. Students who are interested in the specific implementation process are here
Continuous integration
Continuous integration is essential for a complete online project. This project uses a simplified version of continuous integration configuration. The server that goes online is purchased from an e-commerce company, and the continuous deployment plug-in of the project itself draws on yorkie of the well-known open source project Vue. The package.json file is configured as
{
"gitHooks": {
"pre-push": "sh deploy.sh"}}Copy the code
The premise is to write a deployment script deploy.sh that fires the gitHooks script every time the project is committed to the remote repository, and then wait for the application to deploy automatically.
The content of the script deployment file can be configured as follows. If you need to add more steps, you can write the script directly.
! /usr/ npm run buildNeed to build into the 'server' directorySCP - r server [email protected]: / var/WWW/projectnameCopy the code
After the project is built and released, you need to log in to the cloud server to start the service. Pm2 is used in this project. Run the following command on the terminal to start the service
cd /var/www/projectname
pm2 start app.js
Copy the code
conclusion
Through the new reconstruction and upgrading of the vUe-based single page application, in addition to improving my understanding and understanding of Vue, I became proficient in the project reconstruction and upgrading of this series of work again. It starts with API analysis and crawling, followed by analysis of requirements, and then code is finally written, followed by testing and continuous integration again and again. As a result, I have a better understanding of the development process of the project. Meanwhile, I also have many shortcomings that need to be supplemented and learned continuously.
In addition, I also hope that you have read this article in the study of help, mutual encouragement, come on together!
support
If you feel good after reading the article, please like it, thank you!
If you have good ideas and suggestions, please leave them in the comments section!
Welcome to point out any mistakes in this article, thank you!
To view
Project warehouse address: github.com/konglingwen…
Online preview of the project: http://123.57.204.48:3000
Author: Kong Lingwen.