Description of project
The project was not independently developed by me. After all, it was my first VUE project. I was just a chicken who saw the dark horse project on B website.
-
Interested students can download the source code of the project on my Github: github.com/Angus2333/v…
-
Functions: The e-commerce background management system is used to manage user accounts, commodity classification, commodity information, orders, data statistics and other business functions
-
Development mode: E-commerce background management system adopts the development mode of front and back end separation, in which the front end project is SPA project based on Vue technology stack
-
Technical selection of e-commerce background management system
- Front-end project technology stack
- Vue
- Vue-router
- Element-UI
- Axios
- Echarts
- Back-end project technology stack
- Node.js
- Express
- Jwt
- Mysql
- Sequelize
- Front-end project technology stack
Login/logout functions
I. Login overview
1. Login service process
- Enter the user name and password on the login page
- Click the login button to invoke the background interface for verification
- After passing the verification, jump to the project home page according to the response status of the background
2. Log in to technical points related to the service
- HTTP is stateless
- If there are no cross-domain problems between the front-end and back-end interfaces, you are advised to use cookies and sessions to record the login status
- If there is a cross-domain problem, the token mode is recommended to maintain the status
Logon-token principle analysis
Realization of login function
1, preparation,
- Open the project folder in VS Code and start with a new terminal input
git status
Check that your workspace is clean - If the workspace appears clean, continue typing
git checkout -b login
Create a branch and switch to that branch (try to do different functions on different branches) - Open the visual panel of Vue, select the task bar –> Server –> Start, and click start APP after the project is compiled
- Open the code editor and select the SRC folder –>main.js, which is the entry file for the entire project
- Comb through the app. vue file and remove some HTML tags, styles, and JS code generated by default when the project is created
- Remove some unused components generated by default when the project file is created
2. Create a login component
-
Create a Login component login.vue in the Component folder
// Support less syntax, need to install less-loader and less development dependency, scoped control component style effect range
-
Import the login component in the routing file and add routing rules
import Login from '.. /components/ login. vue' const routes = [// redirect: '/', redirect: '/ Login '}, // Login component route {path: '/login', component: Login } ]Copy the code
-
Add a placeholder to the root component
3. Basic layout of login page
-
You need to create a CSS folder under assets folder
-
Create a global style file called global.css in the CSS folder and write:
html, body, #app { height: 100%; margin: 0; padding: 0; } Copy the code
-
Import the global style into the entry file main.js
import './assets/css/global.css' Copy the code
-
On Element’s website, select the component code you want and paste it in the corresponding location of the login component
Log in to reset
-
Because the Element plug-in was configured to import on demand when you installed it, you need to import the components you need to use in the element.js file in the plugins folder and register them as globally available
-
Add a small icon to the input field to distinguish the text field from the password field
-
There are two ways to add an icon to an input field on Element’s website. Here, use the prefix-Icon property to add display ICONS at the beginning and end of the input component
-
Go to the icon library provided on Element’s website to find the icon you want
-
You can also go to the third-party icon library to find the required icon. The prerequisite is to import the third-party icon library into the entry file main.js
-
4. Login form data binding
Add type=’password’ to the password box to hide the password by binding the data we need in the form component we select on Element’s website
<el-form class="form_box" :model="loginForm"> <el-form-item> <el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input> </el-form-item> <el-form-item> <el-input v-model="loginForm.password" prefix-icon="iconfont icon-3702mima" type="password"></el-input> </el-form-item> <el-form-item class="btns"> <el-button Type ="primary"> log </el-button> <el-button type="info"> reset </el-button> </el-form-item> </el-form> <script> export default { Data () {return {// loginForm: {username: ", password: "}}}} </script>Copy the code
5. Login form data verification
-
According to the Form component in Element’s official website, the Form component provides the function of Form verification. You only need to bind the rules attribute to the Form, pass in the agreed verification rules, and set the prop attribute of form-item to the field name to be verified, i.e
Log in to reset
Data () {return {// form data binding object loginForm: {username: ", password: "}, // form data validation loginFormRules: {username: ", password: "}, // form data validation loginFormRules: {username: [{required: true, message: 'Please enter user name ', trigger: 'blur'}, {min: 3, Max: 10, message:' length between 3 and 10 characters ', trigger: 'blur'}], password: [{required: true, message: 'Please input password ', trigger: 'blur'}, {min: 6, Max: 15, message: 'Length between 6 and 15 characters ', trigger: 'blur'}}}}Copy the code
6. Click reset button to reset the form
-
To reset the Form, you need to get the instance object of the Form. According to the method provided by Element’s website for the Form component, you need to add a reference object to the Form by ref. Then you can get the instance object of the Form by getting the reference object (you can name it any way you like, if it’s legal)
-
Add a stand-alone event to the reset button and name the event handler
<el-button type="info" @click="loginFormReset"> resetCopy the code
-
In behavior define event handlers, this event handler is the component object, through print this this can see there is a $ref property, its value is an object, the object is contained in the before add the ref to form reference object, get the reference object, is access to the login form an instance of the object.
-
You can reset the Form using the resetFields method provided on Element’s website in the Form component (resets the entire Form, resetting all field values to their original values and removing validation results)
Methods: {// reset the form event loginFormReset () {// console.log(this); this.$refs.loginFormRef.resetFields() } }Copy the code
7. Click Login to pre-validate form data (before sending request)
-
Add a form reference object
-
Add a stand-alone event to the login button and name the event handler
<el-button type="primary" @click="login"Copy the code
-
Define event handlers
-
Use the validate method provided on Element’s website in the Form component, which validates the entire Form as a callback function. The callback function is called after the verification is complete, passing in two parameters: whether the verification succeeded and the field that failed. The form instance method returns a Promise if the callback function is not passed, which prevalidates the form
login () { this.$refs.loginFormRef.validate(bool => { console.log(bool) }) } Copy the code
8. Send login request (after passing pre-verification)
-
Import AXIos in the entry file, mount it to Vue’s prototype object, and configure the request root path
/ / introduce axios import axios from 'axios / / configuration request root axios. Defaults. BaseURL =' http://127.0.0.1:8888/api/private/v1/ '/ / Prototype.$HTTP = axiosCopy the code
-
Send the request (asynchronously) in the login event handler, process the asynchronous code with the async/await keyword, and return value is an object in which only the data property contains useful data returned by the server, so deconstruct it and assign it to a variable
login () { this.refs.loginFormRef.validate(async bool => { if (! Bool) return // this.loginForm const {data: res } = await this.http.post('login', this.loginForm) console.log(res) }) }Copy the code
9. Tell the user the login result
-
The Element website provides a Message notification component. Import the required component into the element.js file. The component needs to be mounted globally, not registered globally
import { Message } from 'element-ui' Vue.prototype.$message = Message Copy the code
-
The status code returned by the received login request prompts the user whether the login is successful
login () { this.refs.loginFormRef.validate(async bool => { if (! Bool) return // this.loginForm const {data: res } = await this.http.post('login', this.loginForm) if (res.meta.status ! == 200) return this.message.error(' Login failed! ') return this.message.error(' Login failed! ') return this.message. Success (' Login succeeded! ')})}Copy the code
10. Behavior after successful login
-
After a successful login, the token returned by the server is saved to the sessionStorge of the client to keep the login status. (sessionStorge and localStorge have different retention durations. SessionStorge deletes the saved data after the window is closed. LocalStorge has no shelf life); Except for the login interface, all API interfaces can be accessed only after login
-
Navigate programmatically to the background home page, where the routing address is /home. (Inside the Vue instance, you can access the routing instance through $router. So you can call this.$router.push.)
login () { this.refs.loginFormRef.validate(async bool => { if (! Bool) return // this.loginForm const {data: res } = await this.http.post('login', this.loginForm) if (res.meta.status ! == 200) return this.message.error(' Login failed! ') this.message.error(' Login failed! ') this.message. Success (' Login successful! ') window.sessionStorage.setItem('token', res.data.token) this.$router.push('/home') }) }Copy the code
-
Create the HOME component, import the component in the routing file, and add routing rules
11. Route navigation guard
-
Add a navigation guard to the routing file: If the user is not logged in, the user can access the page by entering the URL address directly, which is not reasonable, so you need to re-navigate to the login page
import Vue from 'vue' import VueRouter from 'vue-router' import Login from '.. /components/Login.vue' import Home from '.. /components/Home.vue' Vue.use(VueRouter)const routes = [ { path: '/', redirect: '/login' }, { path: '/login', component: Login }, { path: '/home', component: Home}] const router = new VueRouter({routes}) // Router. BeforeEach ((to, from,) Next) => {// to path to be accessed // from path to be left // next() Allows jump next('/home') Force jump path if (to.path === '/login') return next() // Access token const tokenStr = window. The sessionStorage. The getItem (' token ') if (! tokenStr) return next('/login') next() }) export default routerCopy the code
12. Realize the exit function
-
Temporarily add an exit button to the Home component
-
Bind the button to a stand-alone event and name the event handler
-
An event handler is defined to enable the token-based exit function by destroying the local token
13. Submit the login function code
- Add all the changed files to the staging area on the Login branch
git add .
- The local repository to which files from the staging area are submitted
Git commit -m
- Switch to the
master
The primary branch incorporates the login branch codegit merge login
- Push the latest native code to the code cloud
git push
- Push the local login branch to the code cloud
- Let’s switch to the Login branch
git checkout login
- First push branch
git push -u origin login
- Let’s switch to the Login branch
The home page layout
1. Overall layout
- Find the required layout container components in Elment’s official website, copy the code to home.vue, and comb according to specific requirements
- Import the required components in the element.js file and register them as global components
- Perfecting CSS Styles
2. Head layout
- More requirements for complete HTML layout
- Perfecting CSS Styles
3. Basic layout of the left column
- Find the menu components that match the requirements on Elment’s website and copy the code to home.vue
- Import the required components in the element.js file and register them as global components
- Organize the structure according to specific requirements, and remove unused components from the element.js file
4, through the interface to get menu data rendering to the page
-
As required in the API interface documentation, you need to provide a token in the entry file main.js using the AXIos interceptor to add an Authorization field in the request header for all API requests
/ / add fields to request header axios. Interceptors. Request. Use ((config) = > {. / / the console log (config) config. Headers. The Authorization = window.sessionStorage.getItem('token') return config })Copy the code
-
Call the API to get all menus before the page starts loading, so call the lifecycle function created() in the behavior area.
-
Define a function in Methods that sends a request to the server for menu data (note the need to handle request failures) so that it is called immediately in the lifecycle function created()
-
Immediately mount the retrieved data to data, and define an array (according to the data format returned by the API interface) in data to store the returned data
export default { data () { return { menuList: [] } }, created () { this.getMenuList() }, methods: { async getMenuList () { const { data: res } = await this.http.get('menus') // console.log(res) if (res.meta.status ! Return this.http.get(' menus') //console.log(res) if(res.meta.status! ==200) returnthis.message.error(' Failed to get data! ') this.menuList = res.data // console.log(this.menuList) } } }Copy the code
-
Based on the returned data structure, render the menu data to the left menu bar of the home page.
5. Left menu bar style and function optimization
-
The third-party icon library is used to add font ICONS to the first-level menu. The font ICONS are added dynamically by adding class names. The following is the solution:
-
Create an object in the behavior area data to store the third-party font icon that needs to be used. The key is the ID of the first-level menu in the menu data, and the value is the class name of the corresponding font icon
data () { return { menuList: [], iconsObj: { 125: 'iconfont icon-users', 103: 'iconfont icon-tijikongjian', 101: 'iconfont icon-shangpin', 102: 'iconfont icon-danju', 145: 'iconfont icon-baobiao' } } }, Copy the code
-
Dynamically bind classes in templates
-
-
Only one level 1 menu is allowed to be expanded in the left menu bar. Elemnet website navigation menu component provides an attribute unique-Opened,
-
To solve the problem of uneven menu bar border line, open the page debugging tool can find that the menu is a border, remove it
6. Folding and expanding function of left menu bar
-
Add functional structure
-
Perfect style
-
Bind the click event and name the event function
-
Define event functions to achieve collapse and expansion functions
-
Elemnet website navigation menu component provides a property collapse control menu to collapse and expand
-
Define a variable in data to hold the Boolean value isCollapse: false, and bind it dynamically with collapse: :collapse=”isCollapse”
-
Control the Boolean toggle of this variable in the event function
toggloBtn () { this.isCollapse = ! this.isCollapse }
-
Elemnet website navigation menu component provides a property collapsor-Transition to control whether to start the folding and unfolding animation
-
The width of the sidebar is dynamically bound using a ternary expression based on the state of collapse and expansion
<el-aside :width="isCollapse ? '64px' : '200px'"> <div class="togglo_button" @click="toggloBtn">|||</div> Copy the code
-
7. Route redirection on the home page
-
Create a new welcome.vue component
-
Import this component in the routing file
-
Add routing rule /welcome, which is a child route of the /home route, and redirect /home to this routing rule
const routes = [ { path: '/', redirect: '/login' }, { path: '/login', component: Login }, { path: '/home', component: Home, redirect: '/welcome', children: [ { path: '/welcome', component: Welcome } ] } ] Copy the code
-
Add a route placeholder in the right body area of the Home page
8. The menu on the left is transformed into routing connection
- Elemnet provides a property in the navigation menu component
router
, you can control whether to enable vue-Router mode (enabling this mode will redirect routes with index as path when navigation is activated). - There is one in the menu data obtained earlier
path
Keyword, which stores the value can be used as a route, as a secondary menuindex
The value of the attribute
User management development
Define a child route to the Home page for the user list page
-
Create a new user folder in the Component folder and create a user.vue component in it
-
Import the user.vue component in the routing file
-
Add a /user child routing rule to the child routing of the /home route
-
The navigation menu component of Elemnet website provides an attribute default-active. Assign the index value of the currently active menu to default-Active to highlight the currently active menu
-
Bind the click event to the currently active menu, passing the value of index as an argument to the event handler
-
Define event handling functions: The index value is stored in sessionStorage, and the activePath variable in data is dynamically assigned
saveClkStatus (activePath) { window.sessionStorage.setItem(‘activePath’, activePath) this.activePath = activePath }
-
Define a variable activePath in data to hold active links. The default value is an empty string :activePath:”
-
The life cycle function created() assigns the activePath variable to the index stored in sessionStorage. (This way, even if the page is refreshed, the default-Active property still gets the index of the current activation menu.) To keep the menu active)
created () { this.getMenuList() this.activePath = window.sessionStorage.getItem(‘activePath’) },
-
2. Draw UI structure of user list page
- Find the breadcrumb navigation component on Elemnet and comb it out
- Import the required components as needed in element.js and reference them globally
- Find the appropriate card view components from Elemnet website, comb them out and import them as required
- If you need to override the default styles, you can write the related styles to a global style file
- The appropriate search component can be found on the official website of Elemnet, and the layout component provided on the official website of Elemnet can be used for layout, sorting and import as required
3. Get user list data
- The user list data is retrieved when the page loads, so in the lifecycle function
created()
To call a function that gets user list data - in
methods
Defines a function to get user list data - in
data
Define a variable to hold the parameters to be passed when retrieving user list data (as required by the API documentation), optimize asynchronous requests with async/await keywords (need to handle the state returned by data request success or failure) - According to the returned user list data, in
data
To define variables to hold data that may be needed
4. User list data rendering
-
Find the appropriate table components in the official website of Elemnet, sort them out and import them as required
-
Optimize the table according to the table component properties provided on the official website of Elemnet
-
Custom column status bar render using scope slot: Scoped Slot for row, column, $index and Store (state management within the table component)
-
Custom column action bar render using scope slot
-
Add three icon button components, more need to comb
-
Add a text prompt component to the button
-
-
Achieve data paging effect
- Find the appropriate paging components from Elemnet website, comb them out and import them as required
- Implement paging based on component methods and properties
- Perfect style
5. Modify user status
-
The switch component provides a change event. When the switch state changes, this function binds the change event to the switch and passes a scope.row argument
<el-table-column prop="mg_state" label=" state" > <template slot-scope="scope"> <! -- {{scope.row}} --> <el-switch v-model="scope.row.mg_state" active-color="#13ce66" inactive-color="#ff4949" @change="usersStatus(scope.row)"></el-switch> </template> </el-table-column> Copy codeCopy the code
-
Define an event handler and accept arguments
-
Send a request to the server to change the state in the handler function, and process the asynchronous requestor function with async/await keyword, and deconstruct the return value (note that if the request fails, the switch switch will restore the original state, i.e. the state value stored in the parameter is reversed).
async usersStatus (userSta) { console.log(userSta) const { data: res } = await this.$http.put(`users/${userSta.id}/state/${userSta.mg_state}`) // console.log(res) if (res.meta.status ! == 200) { userSta.mg_state = ! Usersta.mg_state return this.$message.error(' Failed to update user status! ')} this.$message.success(' Update user status successfully! ')} copy the codeCopy the code
6. Realize user search function
-
Reqparams.query is the data object bound to the search box
-
Bind the search button with a click event whose handler is the previously defined function getUsersList() that retrieves user list data.
-
Elemnet provides the clearable attribute for the input field component to clear the field
-
Elemnet provides the clear event to the input field component. Bind this event to the input field and call getUsersList() to display all data when the search field is empty
<el-input placeholder=" insert content "V-model =" reqams. Query" clearable @clear="getUsersList"> <el-button slot="append" </el-button> </el-input> Copy codeCopy the code
7. Realize the function of adding users
-
Add user dialog box show and hide
-
Find the Dialog Dialog component on the Elemnet website, comb it out and import it as needed
-
Define a variable in data that controls the display and hiding of the dialog box addDialogVisible: false and dynamically bind it to the dialog box component’s visible.sync property and to the button’s click event, assigning it the opposite value in the button’s click event
This is a piece of information
Decipher copy code
-
Bind the display of the click event control dialog box to the button that previously added the user, assigning the variable invert in the click event
<el-button type="primary" @click="addDialogVisible = ! AddDialogVisible "> Add a userCopy the code
-
-
Render an Add user form in the Add User dialog box
- Change the header prompt of the dialog box
- Find the Form box components in the official website of Elemnet, sort them according to the requirements, and import the required components as required
- Bind the form to data and set the
data
Define the data to bind according to the requirements and API interface requirements - Bind the form to validation rules, and set the
data
To define form validation rules based on requirements - with
ref
Property to add a reference object to the form
-
Implement custom authentication rules
-
Customize the required verification rules in data based on the component instance provided by Elemnet website
Data () {var checkMobile = (rules, val, CallBack) => {const regMobile = /^[1][3,4,5,7,8][0-9]{9}$/ if (regmobile.test (val)) {return callBack()} CallBack (' Please enter the correct phone number ')}Copy the code
-
Reference a custom validation rule in the Add Validation rule area
{ validator: checkMobile, trigger: ['blur', 'change'] } Copy the code
-
-
Add user form reset function (reset when the form is closed)
-
Bind the dialog box to a close event (Elemnet’s close event) and name the event handler
<el-dialog title=" add user ":visible. Sync ="addDialogVisible" width="50%" @close="addFormClose"> Copy codeCopy the code
-
Define event handlers that reset the form with reference objects of the form
/ / add user dialog box is closed to reset the form addFormClose () {this. $refs. AddFormRef. ResetFields ()}Copy the code
-
-
Add user pre-validation, name and define the event handler for the button click event, and add pre-validation via the validate() method provided by the Elemnet form component
-
After successful pre-validation, initiate the request to add users, process the request with async/await keyword, and deconstruct and receive useful returned data
-
According to the returned status code, the system prompts the user whether the user is successfully added
-
At the same time, close the dialog box to add users, call the function to obtain the user list data to re-render the user list page
/ / add the user submits addFormSub () {this. Refs. AddFormRef. Validate (async bol = > {the if (! bol) return const { data: res } = await this.http.post('users', this.addForm) if (res.meta.status ! Error (res.meta. MSG)} this.message. Success (' Add user successfully! ') // Close the dialog this.addDialogVisible =! This.adddialogvisible // Retrieve user list data this.getUserslist ()})}Copy the code
8. Realize the function of modifying users
- Modify the display and hide of user dialogs
- Click the modify button to pop up a dialog box for modifying user information. Bind the click event to the modify button and name it
- Define event handler functions to control the display of the dialog box for modifying user information and query the user information to be modified
- Add a dialog box to modify user information in the page structure area
- Query old user data by ID
- Of the slot scope in which the edit button resides
Scope. The row. id
Is stored as the user ID, which can be passed as an argument to the function that controls the display of the modify user information dialog - Send a request to query user information based on this ID
- According to the returned user information data format, in
data
A variable that defines the same data format is used to hold the obtained user data
- Of the slot scope in which the edit button resides
- Render a modify user form in the Modify User dialog box
- Introduce appropriate form components into the page structure and comb them out as needed
- Render the obtained data into the form as required (user name cannot be changed)
- Add and define validation rules for the required data
- Modify user dialog box closed when the form reset function
- Implement modification form submission and pre-validation before submission according to API interface document
9. Realize the function of deleting users
- Bind the delete button to a click event and define an event handler that passes as an argument the ID of the user to be deleted
- When the carding function is executed, a prompt box will pop up to prompt the user whether to continue the deletion operation
- In the official website of Elemnet, the MessageBox component has the method to realize the use of popup, import the used components as required, and mount the method to be used globally
- When the user clicks OK, a request to delete the user is sent to the server according to the passed user ID, prompting the user to delete the user successfully, and retrieving the user list data again
- When the user clicks cancel, it prompts the user to cancel the deletion operation
10, submit the user list function code
- Create a new User branch in Git and commit all the code that implements the user list to the staging area
- Submit the finished code to the User branch
- Push the new user branch to the cloud
- Switch to the main branch and merge the code in User into the main branch
- Commit the latest native code to the cloud
Rights management development
First, create a new branch rights and upload it to the cloud. Then, develop permissions management functions on this branch
2. Permission list page
1. Create a permission list page
- Create a new Power folder in the Component folder and create the permission list page component in that folder
- Import the component into the routing file and run the
/home
Create a routing rule for the permission list page in the child route of the route
2. Basic layout of permission list page
- Breadcrumb navigation component
- Card components
3. Obtain permission list data
- There are two types of data to get as suggested in the API interface documentation: List and tree. Send appropriate requests according to requirements
4. Render the permission list data to the page
- Beautify the permission level column with scope slots (find the appropriate tag component on the Elemnet website)
Role list page
1. Rights management service analysis
- Assign roles with different permissions to users
2. Create a role list component
- Create a new role list component in the Power folder
- Import the component into the routing file and run the
/home
Create a routing rule for the permission list page in the child route of the route
3. Basic layout of permission list page
4. Obtain permission list data
5. Render the permission list data to the page
- Scope slots are used to render details of the permissions that the role has
- Use the components in the Layout Layout to Layout the permission details
- Perfect style, at the same time to add a minimum width to the page, in case the browser width becomes small, page style deformation
- Bind an event handler to the third-level permission closure event, which is used to control the deletion of the current permission. To prevent the browser from obtaining data again after the deletion, you can directly reverse assign the return value of the deletion request to the permission data of the current role
6. Assign permission button function
-
Show and hide the Assign Permission dialog box
-
Get a list of all permissions, which is in the form of the required data tree (when displayed in the dialog)
-
Render the retrieved data into a dialog (Tree components are available on Element’s website)
-
According to the default-Checked -keys attribute available on Element’s website, it dynamically binds an array of checked privileges to the ids of the selected privileges
-
Get the ids of all permissions that need to be checked by default through a recursive function
-
Each time you close the permission assignment dialog box, you need to clear the array that holds the permission IDS
-
Add and reduce permissions for roles
-
Bind the click event to the ok button of the dialog box
-
Define event handlers that send requests to the server to modify role permissions
- As required by the API interface, the argument passed should be a comma-separated string of ids containing half-selected and selected permissions
- Element’s website provides a way to get ids containing half-selected and half-selected items in tree controls
getCheckedKeys
andgetHalfCheckedKeys
(These methods can be invoked by obtaining reference instances.)
-
Refresh the page and close the dialog box after the request is successful
Async rightsAllotSub () {// Array of ids of selected and half-selected items... As an operator const keysArr = [... this. Refs. GetKeysRef. GetCheckedKeys (), ... this. Refs. GetKeysRef. GetCheckedKeys (),... this. Refs. GetKeysRef. GetHalfCheckedKeys ()] / / converted to string const idStr = Keysarr.join (',') const {data: Post (' Roles /{this.rolesid}/rights', {rids: idStr}) if (res.meta.status! == 200) {return this.message.error(' Failed to assign role permissions! ')} this.message.success(' Role permissions assigned successfully! ') this.getRolesList() this.rightAllotShow = false }Copy the code
-
7. Improve the role assignment function in the user list
8. Improve the functions of adding roles, deleting and editing the role list
9. Submit code
Commodity management development
I. Commodity classification page
1. Basic page layout
2. Obtain commodity classification data
3. Render commodity classification data to the page
- Install third-party dependent plug-ins
vue-table-with-tree-gird
To run dependencies - Refer to the plug-in documentation for rendering data
4. Add categories
- Complete the dialog box display and hide, improve the form structure
- Get the parent class data, the third level that is not required (define the request separately)
- Render the parent category data into the form using the cascading selector component provided by Element (mandatory when using the props property)
- Send the add request as required by the API
5. Edit classification function
6. Delete the classification function
7. Code submission
2. Commodity Parameter page
1. Create components, import routing files, and create routing rules
2. Basic page layout, and commodity classification cascade selector data rendering
3. Determine whether the add parameter and Add attribute buttons are enabled or disabled based on whether the cascade selector has options
- Use the computed properties of the Vue to listen for elements in the array generated by the selected items generated by the cascading selector to determine whether the button is disabled or enabled
4. Get the parameter data list and attribute list according to the selected item category in the cascade selector
- Uses the compute property to listen for selected categories in the selector, returning the category ID if it does, and null if it does not
- Required in the request
sel
The parameter can be the value of the TAB page selected by default - The function that gets the argument list can be placed in a method to prevent multiple calls
- The function that sends the request needs to determine whether the received function is a dynamic parameter or a static attribute. They need to be stored in different variables because they need to be rendered under different tabs
5. Render data to tabs
-
Render optional parameters and static attribute values, need to return the data into an array form to facilitate loop rendering
- Resolve the situation when rendering target values are empty strings
-
Click the Add Label button to add parameter options and attribute values
-
Since the data is rendered by the template, you need to solve the problem that clicking the Add label button will add all parameters and attributes synchronously
-
To make the added text box get focus automatically, you can use:
this.nextTick(_ => { this.refs.saveTagInput.$refs.input.focus(); });
The $nextTick method is used to execute the callback function after the page element has been re-rendered, in this case after the textbox has been rendered
- Send a request to save the values of the added parameter options and properties to the server side
- The ability to delete parameter options and attribute values is complete
-
6. Add Parameters and Properties button function (common dialog box)
7. Modify parameter or attribute button function (common dialog box)
8. Delete parameter or property button function
9. Submit code
Product list page
1. Create a new branch and synchronize to the cloud repository
2. Create components, import routing files, and create routing rules
3. Basic page layout
4. Obtain commodity list data
5. Data list rendering
- Define a global time handler in the entry file to transform the time display style (vue.js allows you to customize filters that can be used for some common text formatting. Filters can be used in two places: double curly brace interpolation and V-bind expressions.
6. Paging
7. Product search function
8. Add functions to goods
- Click the Add Item button to jump to the Add Item page
- Add Add commodity page components, import routing files, and create routing rules
- Add the product page layout
- Step bar and TAB page synchronization (Data linkage)
- Notice where the form components are placed
- Prevents tabs from switching when necessary (using the TAB component provided)
before-leave
Attributes) - Get server parameters list data, render to commodity parameters panel and commodity properties panel, style optimization
- Upload the image using the upload component (note the use of absolute path, upload the image also requires login permission, so add the request header, and according to the format requirements of the parameters in the request to add goods, synchronize the image temporary path to the data of the add goods form)
- Perfect the function of deleting pictures after uploading
- Improve the image preview function
- Renders a rich text editor in the goods content area (requires running dependencies to be installed
vue-quill-editor
) - Click the add Product button in the product content area to send the request
- Prospective validation
- In accordance with the server-side request data format conversion products category id of array, if its in the heart of the original data format conversion, then run the code will be an error, because choose the classification of goods in the region of the basic information of cascade selector binding data array, complains after changing string (the solution is to install a run
lodash
, provides a method for deep copy of datacloneDeep()
) - Handles dynamic parameters and static properties
- Send the request
9. Product deletion function
10. Submit code
Order Management development
1. Create a branch and synchronize it to the cloud
2. Create components, import components, and create routes
3. Basic layout, order data acquisition and rendering
4. Modify the address dialog box to show the hidden function and the linkage of provincial and urban three-level addresses (there are provincial and urban address data in the material)
5. Hidden function displayed in the logistics progress dialog box (the time line component is not in the installed Element-UI plug-in, and the component of the new version needs to be imported manually)
6. Submit code
Data statistical development
1. Create a branch and synchronize the report to the cloud
2. Create components, import components, and create routes
3. Basic layout, acquisition of report data and rendering
- Install run dependency
echats
- According to the
echats
Official documentation provides basic steps for rendering reports- Send a request for data
- As prompted by the server interface documentation, merge the obtained report data with the data in the documentation before rendering (yes
lodash
Provided in themerge()
Method merge data)
4. Submit code
Project optimization
1. Project warning processing and function optimization in visual UI panel console
- The installation
nprogress
Dependencies, import the plugin and styles in the entry file, add a progress bar to the top of the page as per the official documentation (using request interceptors and response interceptors) - Put all of the code in production
console.log
Code is removed (install development dependency plug-ins in dependenciesbabel-plugin-transform-remove-console
Finally in the babel.config.js file in the project root directoryplugins
In the configuration"transform-remove-console"
- The problem to be resolved is that the configuration in the babel.config.js file is globally effective, which affects the way we debug code in the development environment
- The solution is to define a save in the header of the babel.config.js file
"transform-remove-console"
This variable defaults to an empty array, then determines whether the current environment is a development or production environment, and adds to the array if it is a production environment"transform-remove-console"
Config item, otherwise the array is empty, and adds the variable to the expansion operatorplugins
The configuration of
2. Generate a package report
-
View the console and analysis panels in the visual UI panel to see if there are problems in the project, and whether file sizes such as resource files and dependency files need to be optimized
-
By default, all webpack configuration items are hidden in the project generated by vuE-cil3.0. If you need to modify the default webpack configuration items, You can create the vue.config.js configuration file as required in the project root directory (see cli.vuejs.org/zh/config/#…
-
Specify different package entry points for development and release modes: by default, the development and release modes of Vue projects share the same packaged entry file (SRC /main.js). To separate the development process from the release process of a project, we can specify packaged entry files for both modes
- The entry file for development mode is SRC /main-dev.js
- The entry file for publish mode is SRC /main-prod.js
-
ConfigureWebpack and chainWebpack: ConfigureWebpack or chainWebpack is added to the configuration object exported from vue.config.js, which defines the packaging configuration of WebPack. ConfigureWebpack and chainWebpack have the same function. The only difference is the way they modify the WebPack configuration
- ChainWebpack modifies the default WebPack configuration through chained programming
- ConfigureWebpack by manipulating the objects of the form, to modify the default webpack configuration (both the use of specific differences, may refer to the following url: cli.vuejs.org/zh/guide/we…
-
Use chainWebpack to customize the package entry. First, create a release entry file named main-dev.js, copy the code in the file, and paste the code in the release entry file main-prod.js
-
Configure the following code in the vue.config.js file
chainWebpack: Config => {// Publish mode config.when(process.env.node_env === ‘production’, Config => {config.entry(‘app’).clear().add(‘./ SRC /main-prod.js’)}) // Development mode config.when(process.env.node_env === ‘development’ config = > {config. Entry (‘ app ‘). The clear (), add (‘ the. / SRC/main – dev. Js’)})} copy code
-
3. Enable CDN for the third-party library
-
Load external CDN resources using externals: By default, third-party dependency packages imported through the import syntax are packaged and merged into the same file. As a result, if a single file is too large after packaging, external CDN resources can be configured and loaded through the externals node of webpack. Any third-party dependencies declared in externals will not be packaged
-
The specific configuration code of the publishing mode in the vue.config.js file is as follows
config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios', lodash: '_', echarts: 'echarts', nprogress: 'NProgress', 'vue-quill-editor': 'VueQuillEditor' }) Copy the code
At the same time, add the following CDN resource reference to the header of the public/index.html file:
-
At the same time, add the following CDN resource reference to the header of the public/index.html file:
-
4. Element-ui components are loaded on demand
-
Optimizing ElementUI packaging with CDN: Although we enabled on-demand loading of Element-UI components during development to minimize the volume of packaging, components that were loaded on demand still took up a large file volume. At this point, we can also load the components in the Element-UI through the CDN, which further reduces the size of the packaged file
-
In main-prod.js, comment out the code that Element-UI loads on demand
-
In the header of index.html, load the JS and CSS styles of element-UI via CDN (version number to be the same as in package.json)
-
5. Lazy route loading
-
JavaScript packages can become very large when packaging build projects, affecting page loading. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed
-
Install @ Babel/plugin – syntax – dynamic – the import packages
-
Declare the plug-in in the babel.config.js configuration file
-
Example code for changing the route to load on demand is shown below
const Foo = () => import(/ webpackChunkName: "group-foo" / './Foo.vue') const Bar = () => import(/ webpackChunkName: "Group-foo"/'./ bar.vue ') const Baz = () => import(/ webpackChunkName: "group-boo"/'./ baz.vue ') copy codeCopy the code
-
Detailed documentation about routing lazy loading, may refer to the following link router.vuejs.org/zh/guide/ad…
-
6, home page content customization
-
The content of the home page may vary depending on the packaging environment. We can customize it by means of plug-ins, which are configured as follows:
chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { config.plugin('html').tap(args => { args[0].isProd = true return args }) }) config.when(process.env.NODE_ENV Plugin (' HTML ').tap(args => {args[0].isprod = false return args})})} Copy codeCopy the code
-
In the public/index.html home page, you can decide how to render the page structure according to the value of isProd:
<! - on-demand render the title of the page - > < % = htmlWebpackPlugin. Options. IsProd? "' : 'dev -' < % % > electrical contractor background management system the if (htmlWebpackPlugin. Options. IsProd) {% > < %} % >Copy the code
Project online
1. Use Node to create a Web server
-
Create node project, install Express, quickly create web server through Express, package vue to generate dist folder, hosting as static resources, key codes are as follows:
Const express = require('express') // Create web server const app = Express () // Host static resource app.use(express.static('./dist')) // start Web server app.listen(80, () => {console.log('web server running at http://127.0.0.1')})Copy the code
2. Enable gzip configuration
- You can use gzip to reduce file size and make transfers faster.
- Install corresponding packages
npm install compression -S
- Import packages
const compression = require('compression');
- Enabling middleware
app.use(compression());
- Install corresponding packages
3. Configure the HTTPS service (back-end).
-
The traditional HTTP protocol transmits data in plain text, which is not secure
-
HTTPS is used to encrypt the transmitted data, preventing the data from being stolen by the middleman
-
Applying for an SSL Certificate (freessl.org)
- Go to freessl.cn, enter the domain name you want to apply for and select the brand
- Enter your email address and select the relevant options
- Verify DNS (add TXT records in domain name management background)
- After the authentication succeeds, download the SSL certificate (full_chain.pem public key; . Private key private key)
-
Configuring the HTTPS service: Import the certificate in the background project
const https = require('https'); const fs = require('fs'); const options = { cert: fs.readFileSync('./full_chain.pem'), key: fs.readFileSync('./private.key') } https.createServer(options, app).listen(443); Copy the code
Part of the article is reproduced at: jujin.im/post/684490…