Today's goal
1. Realize the basic layout of the background home page 2. Realize the left menu bar 3. Display user list 4. Add users
1. Basic layout of background home page
Open home Vue components, layout:
<el-container class="home-container"> <!-- Head area --> <el-header>Header<el-button type="info" @click="logout"> sign out </el-button></el-header> <!-- Page body area --> <el-container> <!-- sidebar --> <el-aside width="200px">Aside</el-aside> <!-- Main structure --> <el-main>Main</el-main> </el-container> </el-container>
By default, the class name with the same name as the element UI component can help us quickly add styles to the corresponding components, such as:
.home-container { height: 100%; } .el-header{ background-color:#373D41; } .el-aside{ background-color:#333744; } .el-main{ background-color:#eaedf1; }
2. Top layout, sidebar layout
<template> <el-container class="home-container"> <!-- Head area --> <el-header> <div> <!-- dark horse logo --> <img src="../assets/heima.png" alt=""> <!-- Top title --> <span>E-commerce background management system</span> </div> <el-button type="info" @click="logout"> sign out </el-button> </el-header> <!-- Page body area --> <el-container> <!-- sidebar --> <el-aside width="200px"> <!-- Sidebar menu --> <el-menu background-color="#333744" text-color="#fff" active-text-color="#ffd04b"> <!-- First level menu --> <el-submenu index="1"> <!-- First level menu template --> <template slot="title"> <!-- Icon --> <i class="el-icon-location"></i> <!-- text --> <span>Navigation one</span> </template> <!-- Secondary submenu --> <el-menu-item index="1-4-1"> <!-- Secondary menu template --> <template slot="title"> <!-- Icon --> <i class="el-icon-location"></i> <!-- text --> <span>Single vegetable</span> </template> </el-menu-item> </el-submenu> </el-menu> </el-aside> <!-- Main structure --> <el-main>Main</el-main> </el-container> </el-container> </template>
3.axios request interceptor
In addition to the login interface, token permission verification is required in the background. We can add a token by adding an axios request interceptor to ensure that we have the permission to obtain data In main JS, add the following code before mounting axios to vue prototype
//Before the request reaches the server, the callback function in use will be called to add the request header information axios.interceptors.request.use(config=>{ //For the request header object, add the Authorization field of token authentication config.headers.Authorization = window.sessionStorage.getItem("token") return config })
4. Request sidebar data
<script> export default { data() { return { // Left menu data menuList: null } }, created() { // Request the left menu data in the created phase this.getMenuList() }, methods: { logout() { window.sessionStorage.clear() this.$router.push('/login') }, async getMenuList() { // Send request to get left menu data const { data: res } = await this.$http.get('menus') if (res.meta.status !== 200) return this.$message.error(res.meta.msg) this.menuList = res.data console.log(res) } } } </script>
Rendering the left menu through v-for double loop
<el-menu background-color="#333744" text-color="#fff" active-text-color="#ffd04b"> <!-- First level menu --> <el-submenu :index="item.id+''" v-for="item in menuList" :key="item.id"> <!-- First level menu template --> <template slot="title"> <!-- Icon --> <i class="el-icon-location"></i> <!-- text --> <span>{{item.authName}}</span> </template> <!-- Secondary submenu --> <el-menu-item :index="subItem.id+''" v-for="subItem in item.children" :key="subItem.id"> <!-- Secondary menu template --> <template slot="title"> <!-- Icon --> <i class="el-icon-location"></i> <!-- text --> <span>{{subItem.authName}}</span> </template> </el-menu-item> </el-submenu> </el-menu>
5. Set the style of the active submenu
By changing the active text color property of El menu, you can set the text color of the active item clicked in the sidebar menu By changing the class name of the i tag in the menu item template, you can set the icon in the menu bar on the left. We need to use the third-party Font Icon in the project Add a data in obikonsj:
iconsObj: { '125':'iconfont icon-user', '103':'iconfont icon-tijikongjian', '101':'iconfont icon-shangpin', '102':'iconfont icon-danju', '145':'iconfont icon-baobiao' }
Then bind the icon class name to the data in iconsObj:
In order to keep the left menu open only one at a time and display the submenus, we can add a property unique opened in El menu Or you can set it by data binding (at this time, true is considered a bool value instead of a string): unique opened = "true"
6. Make the telescopic function of the side menu bar
Add a div above the menu bar
<!-- sidebar ,The width is set according to whether it is folded or not --> <el-aside :width="isCollapse ? '64px':'200px'"> <!-- Telescopic sidebar button --> <div class="toggle-button" @click="toggleCollapse">|||</div> <!-- Sidebar menu,:collapse="isCollapse"(Set the collapse menu to bound isCollapse Value),:collapse-transition="false"(Turn off (default collapse animation) --> <el-menu :collapse="isCollapse" :collapse-transition="false" ......
Then add styles to the div and add events to the div:
|||
7. Add child routes on the background home page
Add a child routing component welcome vue In router JS, and set routing rules and default redirection of child routes Open home Vue, add a route placeholder in the main structure
After making the Welcome sub route, we need to transform all the side bar secondary menus into sub route links We only need to set the router attribute of El menu to true. At this time, when we click the secondary menu, it will be based on the index of the menu Property, such as: / 110, It is not appropriate to use index id as the jump path. We can rebind the value of index as: index = "/" + subitem path”
8. Complete the main area of the user list
New user list component user / users vue In router JS to import the child routing component users Vue and set routing rules
When clicking the secondary menu, the secondary submenu is not highlighted. We need to highlight the function being used We can set the index of the active menu by setting the default active attribute of El menu However, the default active attribute cannot be written dead and is fixed to a menu value So we can first add click events to all secondary menus and take the path value as the parameter of the method @click="saveNavState('/'+subItem.path)" Save the path to sessionStorage in the saveNavState method saveNavState( path ){ //Save the clicked secondary menu information when clicking the secondary menu window.sessionStorage.setItem("activePath",path); this.activePath = path; } Then add an activePath binding data to the data and set the default active property of El menu to activePath Finally, assign the data in sessionStorage to activePath in created this.activePath = window.sessionStorage.getItem("activePath")
9. Draw the basic structure of user list
A. Use the element UI breadcrumb component to complete the top navigation path (copy the breadcrumb code and import the components breadcrumb and breadcrumbitem in element.js) B. Use the element UI card component to complete the main table (copy the card component code and import the component card in element.js), and then use the element UI input box to complete the search box and search button, At this time, we need to use the grid layout to divide the structure (copy the card component code, import the component Row and col in element.js), and then use El button to make the add user button
<div> <h3>User list component</h3> <!-- Breadcrumb navigation --> <el-breadcrumb separator="/"> <el-breadcrumb-item :to="{ path: '/home' }">home page</el-breadcrumb-item> <el-breadcrumb-item>user management </el-breadcrumb-item> <el-breadcrumb-item>User list</el-breadcrumb-item> </el-breadcrumb> <!-- Card view area --> <el-card> <!-- Search and add areas --> <el-row :gutter="20"> <el-col :span="7"> <el-input placeholder="Please enter the content"> <el-button slot="append" icon="el-icon-search"></el-button> </el-input> </el-col> <el-col :span="4"> <el-button type="primary">Add user</el-button> </el-col> </el-row> </el-card> </div>
10. Request user list data
<script> export default { data() { return { //Get parameters for querying user information queryInfo: { query: '', pagenum: 1, pagesize: 2 }, //Save the requested user list data userList:[], total:0 } }, created() { this.getUserList() }, methods: { async getUserList() { //Send request to get user list data const { res: data } = await this.$http.get('users', { params: this.queryInfo }) //If the returned status is abnormal, an error is reported and returned if (res.meta.status !== 200) return this.$message.error('Failed to get user list') //If the return status is normal, save the requested data in data this.userList = res.data.users; this.total = res.data.total; } } } </script>
11. Display user list data
Use the table to display the user list data, and use the element UI table component to complete the list display data (copy the table code and import the components table and tablecolumn in element.js) When rendering the presentation state, the scope slot is used to obtain the data of each row Then use the switch switch component to display the status information (copy the switch component code and import the component switch in element.js) When rendering the operation column, the scope slot is also used for rendering, The operation column contains modify, delete and assign role buttons. When we put the mouse over the assign role button We hope to have some text prompts. At this time, we need to use the text prompt component (copy the text prompt component code and import the component tooltip in element.js) to include the role assignment button The code structure is as follows:
<!-- User list(form)region --> <el-table :data="userList" border stripe> <el-table-column type="index"></el-table-column> <el-table-column label="full name" prop="username"></el-table-column> <el-table-column label="mailbox" prop="email"></el-table-column> <el-table-column label="Telephone" prop="mobile"></el-table-column> <el-table-column label="role" prop="role_name"></el-table-column> <el-table-column label="state"> <template slot-scope="scope"> <el-switch v-model="scope.row.mg_state"></el-switch> </template> </el-table-column> <el-table-column label="operation" width="180px"> <template slot-scope="scope"> <!-- modify --> <el-button type="primary" icon="el-icon-edit" size='mini'></el-button> <!-- delete --> <el-button type="danger" icon="el-icon-delete" size='mini'></el-button> <!-- Assign roles --> <el-tooltip class="item" effect="dark" content="Assign roles" placement="top" :enterable="false"> <el-button type="warning" icon="el-icon-setting" size='mini'></el-button> </el-tooltip> </template> </el-table-column> </el-table>
12. Pagination of user list
A. Use the table to display the user list data. You can use the paging component to complete the list paging display data (copy the paging component code and import the component pagination in element.js) B. Change binding data in components
<!-- Paging navigation area @size-change(pagesize Triggered on change) @current-change(Triggered when the page number changes) :current-page(Set current page number) :page-size(Set the number of data pieces per page) :total(Set total pages) --> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[1, 2, 5, 10]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination>
C. Add the event handler functions @ size change and @ current change for two events
handleSizeChange(newSize) { //Triggered when pagesize changes. When pagesize changes, we should //Request data with the latest pagesize and display the data // console.log(newSize) this.queryInfo.pagesize = newSize; //Send the request again according to pagesize to request the latest data this.getUserList(); }, handleCurrentChange( current ) { //Triggered when the page number changes. When the current changes, we should //Request data with the latest current page number and display the data // console.log(current) this.queryInfo.pagenum = current; //Send the request again according to pagenum to request the latest data this.getUserList(); }
13. User implementation status
When the user clicks the switch component in the list, the user's state should change accordingly. A. First, listen to the event that the user clicks the switch component, and pass the data of the scope slot as an event parameter
<el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"></el-switch>
B. Send request completion status change in event
async userStateChanged(row) { //Send request for status modification const { data: res } = await this.$http.put( `users/${row.id}/state/${row.mg_state}` ) //If the returned status is abnormal, an error is reported and returned if (res.meta.status !== 200) { row.mg_state = !row.mg_state return this.$message.error('Failed to modify status') } this.$message.success('Update status succeeded') },
14. Realize the search function
Add data binding and click event of search button (when the user clicks the search button, call getUserList method to re request user list data according to the content of text box) After we enter the content in the input box and click search, we will search according to the search keyword. We hope to provide an X to delete the search keyword and re obtain all the user list data. We only need to add the clear attribute to the text box and add the clear event, and re request the data in the clear event
<el-col :span="7"> <el-input placeholder="Please enter the content" v-model="queryInfo.query" clearable @clear="getUserList"> <el-button slot="append" icon="el-icon-search" @click="getUserList"></el-button> </el-input> </el-col>
15. Add users
A. When we click the add user button, a Dialog box will pop up to realize the function of adding users. First, we need to copy the code of the Dialog box component and add it in element JS file
B. Next, we need to add a click event for the "add user" button. In the event, set addDialogVisible to true to display the dialog box
C. Change the content in the Dialog component
<!-- Dialog components :visible.sync(Sets whether the dialog box is displayed) width(Sets the width of the dialog box) :before-close(Event triggered before the dialog box closes) --> <el-dialog title="Add user" :visible.sync="addDialogVisible" width="50%"> <!-- Dialog body area --> <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px"> <el-form-item label="user name" prop="username"> <el-input v-model="addForm.username"></el-input> </el-form-item> <el-form-item label="password" prop="password"> <el-input v-model="addForm.password"></el-input> </el-form-item> <el-form-item label="mailbox" prop="email"> <el-input v-model="addForm.email"></el-input> </el-form-item> <el-form-item label="Telephone" prop="mobile"> <el-input v-model="addForm.mobile"></el-input> </el-form-item> </el-form> <!-- Bottom area of dialog box --> <span slot="footer" class="dialog-footer"> <el-button @click="addDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="addDialogVisible = false">determine</el-button> </span> </el-dialog>
D. Add data binding and validation rules:
data() { //Rules for validating mailboxes var checkEmail = (rule, value, cb) => { const regEmail = /^\w+@\w+(\.\w+)+$/ if (regEmail.test(value)) { return cb() } //Returns an error message cb(new Error('Please enter a legal email address')) } //Rules for verifying mobile phone numbers var checkMobile = (rule, value, cb) => { const regMobile = /^1[34578]\d{9}$/ if (regMobile.test(value)) { return cb() } //Returns an error message cb(new Error('Please enter a valid mobile phone number')) } return { //Get parameters for querying user information queryInfo: { // Query criteria query: '', // Current number of pages, i.e. page number pagenum: 1, // Number of data pieces displayed per page pagesize: 2 }, //Save the requested user list data userList: [], total: 0, //Show add user pop-up addDialogVisible: false, // Add user's form data addForm: { username: '', password: '', email: '', mobile: '' }, // Add validation rule object for form addFormRules: { username: [ { required: true, message: 'Please enter user name', trigger: 'blur' }, { min: 3, max: 10, message: 'User name in 3~10 Between characters', trigger: 'blur' } ], password: [ { required: true, message: 'Please input a password', trigger: 'blur' }, { min: 6, max: 15, message: 'User name in 6~15 Between characters', trigger: 'blur' } ], email: [ { required: true, message: 'Please enter email address', trigger: 'blur' }, { validator:checkEmail, message: 'The email format is incorrect, please re-enter', trigger: 'blur'} ], mobile: [ { required: true, message: 'Please enter your mobile phone number', trigger: 'blur' }, { validator:checkMobile, message: 'The mobile phone number is incorrect, please re-enter', trigger: 'blur'} ] } } }
E. Resets the form when the dialog box is closed Add the @ close event to the El dialog, and add the code to reset the form in the event
methods:{ .... addDialogClosed(){ //After the dialog box closes, reset the representation this.$refs.addFormRef.resetFields(); } }
F. Click OK in the dialog box to send a request to complete the operation of adding users First, add a click event to the OK button, and complete the business logic code in the click event
methods:{ .... addUser(){ //Click OK to add a new user //Call validate to validate the form this.$refs.addFormRef.validate( async valid => { if(!valid) return this.$message.error("Please complete the user information"); //Send a request to complete the operation of adding users const {data:res} = await this.$http.post("users",this.addForm) //Judge if the addition fails, give a prompt if (res.meta.status !== 200) return this.$message.error('Failed to add user') //Add successful prompt this.$message.success("User added successfully") //close dialog boxes this.addDialogVisible = false //Re request the latest data this.getUserList() }) } }
Today's goal
1. Modify user and delete user
2. Push code to code cloud
3. Permission list
4. Role list
5. Assign roles
1. Modify user information
A. Bind the click event for the Modify button in the user list B. Add and modify the user dialog box in the page and modify the properties of the dialog box C. Query the user data to be modified according to the id
//Displays the dialog box for editing users async showEditDialog(id) { //Send a request to obtain user information according to the id const { data: res } = await this.$http.get('users/' + id) //Judge if the addition fails, give a prompt if (res.meta.status !== 200) return this.$message.error('Failed to get user information') //Save the obtained data to the data editForm this.editForm = res.data //Show pop ups this.editDialogVisible = true }
D. In the pop-up window, add and modify the form of user information and respond to data binding and data verification
<!-- Dialog body area --> <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="70px"> <el-form-item label="user name"> <el-input v-model="editForm.username" disabled></el-input> </el-form-item> <el-form-item label="mailbox" prop="email"> <el-input v-model="editForm.email"></el-input> </el-form-item> <el-form-item label="Telephone" prop="mobile"> <el-input v-model="editForm.mobile"></el-input> </el-form-item> </el-form>
Data binding and validation:
//Controls whether the modify user dialog box is displayed editDialogVisible: false, //Modify user's form data editForm: { username: '', email: '', mobile: '' }, //Modify the validation rule object of the form editFormRules: { email: [ { required: true, message: 'Please enter email address', trigger: 'blur' }, { validator: checkEmail, message: 'The email format is incorrect, please re-enter', trigger: 'blur' } ], mobile: [ { required: true, message: 'Please enter your mobile phone number', trigger: 'blur' }, { validator: checkMobile, message: 'The mobile phone number is incorrect, please re-enter', trigger: 'blur' } ] }
E. Listen to the dialog box closing event and reset the form after the dialog box is closed
<el-dialog title="Modify user" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed"> editDialogClosed(){ //After the dialog box closes, reset the representation this.$refs.editFormRef.resetFields() }
F. When the user clicks the OK button, send a request to complete the modification after the data is verified successfully
editUser() { //After the user clicks the OK button in the modify form, verify the form data this.$refs.editFormRef.validate(async valid => { if (!valid) return this.$message.error('Please complete the user information') //Send a request to complete the operation of modifying the user const { data: res } = await this.$http.put( 'users/' + this.editForm.id, this.editForm ) //Judge if the modification fails, give a prompt if (res.meta.status !== 200) return this.$message.error('Failed to modify user') //Prompt for successful modification this.$message.success('User modified successfully') //close dialog boxes this.editDialogVisible = false //Re request the latest data this.getUserList() }) }
2. Delete user
When clicking the delete button, we should jump out of the prompt message box and let the user confirm the deletion operation. If you want to use the confirmation cancellation prompt box, we need to mount the prompt message box to vue first. A. Import the MessageBox component and mount the MessageBox component to the instance. Vue.prototype.$confirm = MessageBox.confirm B. Add an event to the delete button in the user list, pop up the confirm cancel window in the event handling function, and finally send the request to delete the user according to the id
async removeUserById(id){ //Click OK to cancel to delete the user const confirmResult = await this.$confirm('Do you want to permanently delete this user','Delete prompt',{ confirmButtonText:'confirm deletion', cancelButtonText:'cancel', type:'warning' }).catch(err=>err) //If the user clicks confirm, the confirm result is' confirm ' //If the user clicks cancel, confirmResult will get the error message 'Cancel' of catch if(confirmResult != "confirm"){ return this.$message.info("The deletion has been cancelled") } //Send a request to complete the deletion operation according to the id const {data:res} = await this.$http.delete('users/'+id) //Judge if the deletion fails, give a prompt if (res.meta.status !== 200) return this.$message.error('Failed to delete user') //Prompt for successful modification this.$message.success('User deleted successfully') //Re request the latest data this.getUserList() }
3. Push code
Create a user sub branch and push the code to the code cloud A. Create user sub branch git checkout -b user B. Add the code to the staging area git add C. Submit the code and comment git commit -m 'add complete user list function' D. Push the local user branch to the code cloud git push -u origin user E. Merge the user branch code into the master: Switch to master git checkout master Merge user git merge user F. Push the code of the local master branch to the code cloud git push
Create rights sub branch A. Create rights sub branch git checkout -b rights B. Push the local rights branch to the code cloud git push -u origin rights
4. Permission list
A. Add permission list route
Create a rights management component (Rights.vue) and run it in router JS add the corresponding routing rule
import Rights from './components/power/Rights.vue' ...... path: '/home', component: Home, redirect: '/welcome', children: [ { path: "/welcome", component: Welcome }, { path: "/users", component: Users }, { path: "/rights", component: Rights } ] ......
B. Add breadcrumbs navigation
At rights Add breadcrumb component to Vue to show navigation path
C. Display data
Add a rightsList data in data, provide a getRightsList method in methods to send request to get permission list data, and call this method in created to get data.
<el-table :data="rightsList" stripe> <el-table-column type="index"></el-table-column> <el-table-column label="Permission name" prop="authName"></el-table-column> <el-table-column label="route" prop="path"></el-table-column> <el-table-column label="privilege level" prop="level"> <template slot-scope="scope"> <el-tag v-if="scope.row.level === 0">First level authority</el-tag> <el-tag v-if="scope.row.level === 1" type="success">Secondary authority</el-tag> <el-tag v-if="scope.row.level === 2" type="warning">Three level authority</el-tag> </template> </el-table-column> </el-table> <script> export default { data(){ return { //Permissions in list form rightsList:[] } }, created(){ this.getRightsList(); }, methods:{ async getRightsList(){ const {data:res} = await this.$http.get('rights/list') //If the returned status is abnormal, an error is reported and returned if (res.meta.status !== 200) return this.$message.error('Failed to get permission list') //If the return status is normal, save the requested data in data this.rightsList = res.data } } } </script>
5. Role list
A. Add role list route
Add the role list sub component (power/Roles.vue) and add the corresponding rules
path: '/home', component: Home, redirect: '/welcome', children: [ { path: "/welcome", component: Welcome }, { path: "/users", component: Users }, { path: "/rights", component: Rights }, { path: "/roles", component: Roles } ]
B. Add breadcrumbs navigation
In roles Add breadcrumb component to Vue to show navigation path
C. Display data
Add a roleList data in data, provide a getRoleList method in methods to send request to get permission list data, and call this method in created to get data.
<!-- Role list area --> <!-- row-key="id" It is a new feature provided in March 2019, if there's nested data, rowKey is required. If this is a nested data, rowkey Is a property that must be added --> <el-table row-key="id" :data="roleList" border> <!-- Add expanded column --> <el-table-column type="expand"></el-table-column> <el-table-column type="index"></el-table-column> <el-table-column label="Role name" prop="roleName"></el-table-column> <el-table-column label="Role description" prop="roleDesc"></el-table-column> <el-table-column label="operation" width="300px"> <template slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">edit</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">delete</el-button> <el-button size="mini" type="warning" icon="el-icon-setting">Assign permissions</el-button> </template> </el-table-column> </el-table> <script> export default { data(){ return { roleList:[] } },created(){ this.getRoleList(); },methods:{ async getRoleList(){ const {data:res} = await this.$http.get('roles') //If the returned status is abnormal, an error is reported and returned // if (res.meta.status !== 200) // return this.$message.error('failed to get role list ') // //If the return status is normal, save the requested data in data // this.roleList = res.data console.log(res.data) this.roleList = res.data; } } } </script>
D. Supplementary notes
I have learned similar methods before, such as adding roles, deleting roles and editing roles. Please refer to the previously written code and interface documents to complete the effect.
E. Generate permission list
Generate permission drop-down list using triple nested for loop
<!-- Add expanded column --> <el-table-column type="expand"> <template slot-scope="scope"> <el-row :class="['bdbottom',i1===0?'bdtop':'']" v-for="(item1,i1) in scope.row.children" :key="item1.id"> <!-- Render first level permissions --> <el-col :span="5"> <el-tag> {{item1.authName}} </el-tag> <i class="el-icon-caret-right"></i> </el-col> <!-- Rendering Level 2 and 3 permissions --> <el-col :span="19"> <!-- adopt for Loop nested rendering secondary permissions --> <el-row :class="[i2===0?'':'bdtop' ]" v-for="(item2,i2) in item1.children" :key="item2.id"> <el-col :span="6"> <el-tag type="success">{{item2.authName}}</el-tag> <i class="el-icon-caret-right"></i> </el-col> <el-col :span="18"> <el-tag type="warning" v-for="(item3) in item2.children" :key="item3.id"> {{item3.authName}} </el-tag> </el-col> </el-row> </el-col> </el-row> </template> </el-table-column>
F. Beautification style
By setting global The #app style min width: 1366px in CSS solves the problem of three-level permission line breaking , by adding display: flex, align items: Center to the first level permission El row, the problem of vertical centering of the first level permission can be solved. The second level permission is also added similarly, because multiple contents need to be added, this style can be set to one vcenter{display:flex;align-items:center}
G. Add permission delete function
Add the closable attribute to the El tag of each permission. Yes, an "X" icon appears on the right side of the permission Add rightscope.byid to remove.scope (handle the event again) removeRightById(scope.row,item2.id) removeRightById(scope.row,item3.id)
async removeRightById(role,rightId){ //The pop-up window prompts the user whether to delete it const confirmResult = await this.$confirm('Do you want to delete this permission','Delete prompt',{ confirmButtonText:'confirm deletion', cancelButtonText:'cancel', type:'warning' }).catch(err=>err) //If the user clicks confirm, the confirm result is' confirm ' //If the user clicks cancel, confirmResult will get the error message 'Cancel' of catch if(confirmResult != "confirm"){ return this.$message.info("The deletion has been cancelled") } //The user clicks OK, which means he really wants to delete it //After sending the delete request, the returned data is the latest role permission information const {data:res} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`) if (res.meta.status !== 200) return this.$message.error('Failed to delete role permissions') //There is no need to reload all permissions //You only need to update the existing role permissions role.children = res.data // this.getRoleList(); }
H. Complete the permission assignment function
Add an event to the assign permission button first < El button size = "mini" type = "warning" icon = "El icon setting" @ click = "showSetRightDialog" > assign permissions Request permission tree data in the showSetRightDialog function and display the dialog box
async showSetRightDialog() { //When you click the assign permission button, the corresponding dialog box will be displayed this.setRightDialogVisible = true; //Get data for all permissions const {data:res} = await this.$http.get('rights/tree') //If the returned status is abnormal, an error is reported and returned if (res.meta.status !== 200) return this.$message.error('Failed to get permission tree') //If the return status is normal, save the requested data in data this.rightsList = res.data }
Add the assign permission dialog box and add the binding data setRightDialogVisible
This is a message. Cancel confirmation
1. Complete the pop-up window of tree structure
In element JS, and register the Tree
<!-- Assign permissions dialog box --> <el-dialog title="Assign permissions" :visible.sync="setRightDialogVisible" width="50%" @close="setRightDialogClose"> <!-- Tree component show-checkbox:Show check boxes node-key:Set the value corresponding to the selected node default-expand-all:Expand all nodes by default :default-checked-keys Sets the array of default selected items ref:Set reference --> <el-tree :data="rightsList" :props="treeProps" show-checkbox node-key="id" default-expand-all :default-checked-keys="defKeys" ref="treeRef"></el-tree> <span slot="footer" class="dialog-footer"> <el-button @click="setRightDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="allotRights">determine</el-button> </span> </el-dialog> <script> export default { data() { return { //Role list data roleList: [], //Controls the display of the assign permissions dialog box setRightDialogVisible: false, //Permission tree data rightsList: [], //Property binding object of tree control treeProps: { //Set the tree node text through label to display authName label: 'authName', //Set to display the child node information through the children attribute children: 'children' }, //Sets the default selection in the tree control defKeys: [], //Save the role id being operated roleId:'' } }, created() { this.getRoleList() }, methods: { async getRoleList() { const { data: res } = await this.$http.get('roles') //If the returned status is abnormal, an error is reported and returned if (res.meta.status !== 200) return this.$message.error('Failed to get role list') //If the return status is normal, save the requested data in data // this.roleList = res.data console.log(res.data) this.roleList = res.data }, async removeRightById(role, rightId) { //The pop-up window prompts the user whether to delete it const confirmResult = await this.$confirm( 'Do you want to delete this permission', 'Delete prompt', { confirmButtonText: 'confirm deletion', cancelButtonText: 'cancel', type: 'warning' } ).catch(err => err) //If the user clicks confirm, the confirm result is' confirm ' //If the user clicks cancel, confirmResult will get the error message 'Cancel' of catch if (confirmResult != 'confirm') { return this.$message.info('The deletion has been cancelled') } //The user clicks OK, which means he really wants to delete it //After sending the delete request, the returned data is the latest role permission information const { data: res } = await this.$http.delete( `roles/${role.id}/rights/${rightId}` ) if (res.meta.status !== 200) return this.$message.error('Failed to delete role permissions') //There is no need to reload all permissions //You only need to update the existing role permissions role.children = res.data // this.getRoleList(); }, async showSetRightDialog(role) { //Add role The ID is saved for use when saving rights are limited this.roleId = role.id; //Get data for all permissions const { data: res } = await this.$http.get('rights/tree') //If the returned status is abnormal, an error is reported and returned if (res.meta.status !== 200) return this.$message.error('Failed to get permission tree') //If the return status is normal, save the requested data in data this.rightsList = res.data //Call getLeafKeys to recurse and add three-level permissions to the array this.getLeafKeys(role, this.defKeys) //When you click the assign permission button, the corresponding dialog box will be displayed this.setRightDialogVisible = true console.log(this.defKeys) }, getLeafKeys(node, arr) { //This function will obtain all three-level permission IDs of the current role and add them to defKeys //If the current node does not contain the children attribute, it indicates that the node is a three-level permission if (!node.children) { return arr.push(node.id) } //Recursive call node.children.forEach(item => this.getLeafKeys(item, arr)) }, setRightDialogClose() { //When the user closes the tree permission dialog box, all selected states are cleared this.defKeys = [] }, async allotRights() { //When the user clicks OK in the tree permission dialog box, the user selected //Permission to send request for update //Get all selected and semi selected contents const keys = [ ...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys() ] //Convert an array to a concatenated string const idStr = keys.join(',') //Send request to complete update const { data: res } = await this.$http.post( `roles/${this.roleId}/rights`, { rids:idStr } ) if (res.meta.status !== 200) return this.$message.error('Failed to assign permissions') this.$message.success("Permission assignment succeeded") this.getRoleList(); //close dialog boxes this.setRightDialogVisible = false; } } } </script>
6. Assign roles
Open users Vue, which completes the function of assigning roles A. Add assigned role dialog box
<!-- Assign role dialog box --> <el-dialog title="Assign roles" :visible.sync="setRoleDialogVisible" width="50%"> <div> <p>Current user:{{userInfo.username}}</p> <p>Current role:{{userInfo.role_name}}</p> <p>Assign new roles:</p> </div> <span slot="footer" class="dialog-footer"> <el-button @click="setRoleDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="setRoleDialogVisible = false">determine</el-button> </span> </el-dialog>
B. Add a click event to the assign role button. After clicking, a dialog box pops up for role assignment
<!-- Assign roles --> <el-tooltip class="item" effect="dark" content="Assign roles" placement="top" :enterable="false"> <el-button type="warning" icon="el-icon-setting" size='mini' @click="setRole(scope.row)"></el-button> </el-tooltip> data(){ ...... //Controls the display of the assign role dialog box setRoleDialogVisible:false, //Save the information of the user who is operating userInfo:{}, //Save all role information rolesList:[], //Save the role id selected by the user selectedRoleId:'' }, methods:{ ...... async setRole( userInfo ){ //Save it for later use this.userInfo = userInfo; //Get all role information for use in the drop-down list //Send a request to complete the deletion operation according to the id const { data: res } = await this.$http.get('roles') //Judge if the deletion fails, give a prompt if (res.meta.status !== 200) return this.$message.error('Failed to get role list') this.rolesList = res.data; //Show the assign role dialog box this.setRoleDialogVisible = true; } }
C. In element JS, and register Select, Option
<!-- Role selection drop-down box v-model: Set after the user selects the role id Binding data --> <el-select v-model="selectedRoleId" placeholder="Please select a role"> <!-- :label Display text,:value Selected value --> <el-option v-for="item in rolesList" :key="item.id" :label="item.roleName" :value="item.id"> </el-option> </el-select>
D. When the user clicks OK in the dialog box, the operation of assigning roles is completed
<!-- Assign role dialog box --> <el-dialog title="Assign roles" :visible.sync="setRoleDialogVisible" width="50%" @close="setRoleDialogClosed"> <div> <p>Current user:{{userInfo.username}}</p> <p>Current role:{{userInfo.role_name}}</p> <p>Assign new roles: <!-- Role selection drop-down box v-model: Set the after the user selects the role id Binding data --> <el-select v-model="selectedRoleId" placeholder="Please select a role"> <!-- :label Display text,:value Selected value --> <el-option v-for="item in rolesList" :key="item.id" :label="item.roleName" :value="item.id"> </el-option> </el-select> </p> </div> <span slot="footer" class="dialog-footer"> <el-button @click="setRoleDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="saveRoleInfo">determine</el-button> </span> </el-dialog> methods:{ ....... async saveRoleInfo(){ //When the user clicks the OK button //Judge whether the user has selected the role to be assigned if(!this.selectedRoleId){ return this.$message.error('Please select the role to be assigned') } //Send a request to complete the assignment of roles const {data:res} = await this.$http.put(`users/${this.userInfo.id}/role`,{rid:this.selectedRoleId}) //Judge if the deletion fails, give a prompt if (res.meta.status !== 200) return this.$message.error('Failed to assign role') this.$message.success('Role assignment succeeded') this.getUserList(); //close dialog boxes this.setRoleDialogVisible = false }, setRoleDialogClosed(){ //Reset the contents of the drop-down box when the dialog box is closed this.selectedRoleId = '' this.userInfo = {} } }
7. Push the code to the code cloud
A. Push the code to the temporary storage area git add B. Submit the code to the warehouse git commit -m 'completed the permission function development' C. Push the rights branch code to the code cloud git push D. Merge code into master git checkout master git merge rights E. Push master code to code cloud git push
Today's goal
1. Complete commodity classification
2. Complete parameter management
1. Commodity classification
A. New branch goods_cate
New branch goods_ Cat and push to the code cloud git checkout -b goods_cate git push -u origin goods_cate
B. Create child route
Create sub level routing components of categories and set routing rules
import Cate from './components/goods/Cate.vue' path: '/home', component: Home, redirect: '/welcome', children: [ { path: "/welcome", component: Welcome }, { path: "/users", component: Users }, { path: "/rights", component: Rights }, { path: "/roles", component: Roles }, { path: "/categories", component: Cate } ]
C. Add component basic layout
At cate Add breadcrumb navigation in Vue component and add category button in card view
<template> <div> <h3>Commodity classification</h3> <!-- Breadcrumb navigation --> <el-breadcrumb separator="/"> <el-breadcrumb-item :to="{ path: '/home' }">home page</el-breadcrumb-item> <el-breadcrumb-item>Commodity management</el-breadcrumb-item> <el-breadcrumb-item>Commodity classification</el-breadcrumb-item> </el-breadcrumb> <!-- Card view area --> <el-card> <!-- Add category button area --> <el-row> <el-col> <el-button type="primary">Add classification</el-button> </el-col> </el-row> <!-- Classification table --> <!-- paging --> </el-card> </div> </template>
D. Request classification data
Request classification data and save the data in data
<script> export default { data() { return { // Commodity classification data list cateList: [], //Conditions for querying classified data queryInfo: { type: 3, pagenum: 1, pagesize: 5 }, //Total number of data saved total: 0 } }, created() { this.getCateList() }, methods: { async getCateList() { //Get commodity classification data const { data: res } = await this.$http.get('categories', { params: queryInfo }) if (res.meta.status !== 200) { return this.$message.error('Failed to get commodity list data') } //Assign data list to cateList this.cateList = res.data.result //Total number of data saved this.total = res.data.total // console.log(res.data); } } } </script>
E. Using plug-ins to display data
Use the third-party plug-in Vue table with tree grid to display classified data 1). In the vue console, click dependency - > install dependency - > Run dependency - > Enter vue table with tree gird - > click Install 2). Open main JS, import Vue table with tree grid import TreeTable from 'vue-table-with-tree-grid' ..... Vue.config.productionTip = false
//Global registration component Vue.component('tree-table', TreeTable) 3).Use components to display classified data
<!-- Classification table :data(set up data sources) :columns(Set column configuration information in the table) :selection-type(Is there a check box) :expand-type(Expand data) show-index(Set index column) index-text(Set index column header) border(Add vertical border) :show-row-hover(Whether mouse over highlighting) --> <tree-table :data="cateList" :columns="columns" :selection-type="false" :expand-type="false" show-index index-text="#" border :show-row-hover="false"> </tree-table> Add to data columns: columns: [ {label:'Classification name',prop:'cat_name'} ]
F. Custom data column
Use Vue table with tree grid to define template columns and add custom columns
//First add a column in columns columns: [ {label:'Classification name',prop:'cat_name'}, //type:'template' (set this column as a template column), template:'isok' (set the name of this column template as isok) {label:'Is it valid',prop:'',type:'template',template:'isok'}, {label:'sort',prop:'',type:'template',template:'order'}, {label:'operation',prop:'',type:'template',template:'opt'} ] <!-- Set the corresponding template column according to the valid region: slot="isok"(And columns Set in template agreement) --> <template slot="isok" slot-scope="scope"> <i class="el-icon-success" v-if="scope.row.cat_deleted === false" style="color:lightgreen"></i> <i class="el-icon-error" v-else style="color:red"></i> </template> <!-- sort --> <template slot="order" slot-scope="scope"> <el-tag size="mini" v-if="scope.row.cat_level===0">class a</el-tag> <el-tag size="mini" type="success" v-else-if="scope.row.cat_level===1">second level</el-tag> <el-tag size="mini" type="warning" v-else>Tertiary</el-tag> </template> <!-- operation --> <template slot="opt" slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">edit</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">delete</el-button> </template>
G. Complete paging function
<!-- paging --> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[3, 5, 10, 15]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> //Add corresponding event function methods:{ ....... handleSizeChange(newSize){ //Triggered when pagesize changes this.queryInfo.pagesize = newSize; this.getCateList(); }, handleCurrentChange(newPage){ //Triggered when pagenum changes this.queryInfo.pagenum = newPage; this.getCateList(); } }
H. Finish adding categories
...... <!-- Add category button area --> <el-row> <el-col> <el-button type="primary" @click="showAddCateDialog">Add classification</el-button> </el-col> </el-row> ...... <!-- Add classification dialog box --> <el-dialog title="Add classification" :visible.sync="addCateDialogVisible" width="50%" @close="addCateDialogClosed"> <!-- Add classification form --> <el-form :model="addCateForm" :rules="addCateFormRules" ref="addCateFormRuleForm" label-width="100px"> <el-form-item label="Classification name" prop="cat_name"> <el-input v-model="addCateForm.cat_name"></el-input> </el-form-item> <el-form-item label="Parent classification" prop="cat_pid"> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="addCateDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="addCate">determine</el-button> </span> </el-dialog> //Used to show or hide the add classification dialog box addCateDialogVisible: false, //Add classified form data object addCateForm:{ //Classification name cat_name:'', //Add the parent id of the classification, 0 means the parent is 0 Add primary classification cat_pid:0, //Add a level of classification, 0 means add a level of classification cat_level:0 }, //Add classification verification rule addCateFormRules:{ //Validation rules cat_name:[ {required:true , message:'Please enter the classification name',trigger:'blur'} ] }, //Save the list of 1 and 2 parent classifications parentCateList:[] ....... showAddCateDialog() { //Call getParentCateList to get the classification list this.getParentCateList() //The add classification dialog box is displayed this.addCateDialogVisible = true }, async getParentCateList(){ //Get parent classification data list const { data: res } = await this.$http.get('categories', { params: {type:2} }) if (res.meta.status !== 200) { return this.$message.error('Failed to get commodity classification list data') } this.parentCateList = res.data }
Add cascading menu to display parent classification First import the Cascader component and register Then add the use cascading menu component:
<el-form-item label="Parent classification" prop="cat_pid"> <!-- expandTrigger='hover'(Mouse over trigger cascade) v-model(Set cascading menu binding data) :options(Specify cascading menu data source) :props(Rules used to configure data display) clearable(Provide“ X"No. complete the function of deleting text) change-on-select(Can I select any level of menu) --> <el-cascader expandTrigger='hover' v-model="selectedKeys" :options="parentCateList" :props="cascaderProps" @change="parentCateChange" clearable change-on-select></el-cascader> </el-form-item> Add data //How to display data in the configuration cascade menu cascaderProps:{ value:'cat_id', label:'cat_name', children:'children', expandTrigger:'hover' }, //Bind the classification value selected by the user selectedKeys:[] ..... methods:{ ..... parentCateChange(){ //Triggered when the selection item in the cascade menu changes console.log(this.selectedKeys) //If the user selects a parent classification if(this.selectedKeys.length > 0){ //Set the last item in the array as the parent classification this.addCateForm.cat_pid = this.selectedKeys[this.selectedKeys.length - 1] //level should also change with it this.addCateForm.cat_level = this.selectedKeys.length return }else{ this.addCateForm.cat_pid = 0 this.addCateForm.cat_level = 0 return } }, addCateDialogClosed(){ //Reset the form when the add classification dialog box is closed this.$refs.addCateFormRef.resetFields() this.selectedKeys = []; this.addCateForm.cat_pid = 0 this.addCateForm.cat_level = 0 }, addCate() { //Click OK to finish adding classification console.log(this.addCateForm) this.$refs.addCateFormRef.validate(async valid => { if (!valid) return //Send request to finish adding classification const { data: res } = await this.$http.post( 'categories', this.addCateForm ) if (res.meta.status !== 201) { return this.$message.error('Failed to add classification') } this.$message.success('Classification added successfully') this.getCateList() this.addCateDialogVisible = false }) } }
1. Push code
After making and adding categories, submit the code to the warehouse and push it to the code cloud to add goods_ Merge the cat branch into the master git add . git commit -m 'complete product classification' git push git checkout master git merge goods_cate
2. Parameter management
Parameters can only be set for three-level classification content. Parameters are divided into dynamic parameters and static parameter attributes
A. Add child component
Add params Vue sub components, and in router JS and set the routing rules
import Params from './components/goods/Params.vue' ...... path: '/home', component: Home, redirect: '/welcome', children: [ { path: "/welcome", component: Welcome }, { path: "/users", component: Users }, { path: "/rights", component: Rights }, { path: "/roles", component: Roles }, { path: "/categories", component: Cate }, { path: "/params", component: Params } ]
B. Complete the basic layout of components
Complete params Basic layout of Vue components The warning message uses El alert, which is displayed in element JS introduces the component and registers it
<template> <div> <h3>Classification parameters</h3> <!-- Breadcrumb navigation --> <el-breadcrumb separator="/"> <el-breadcrumb-item :to="{ path: '/home' }">home page</el-breadcrumb-item> <el-breadcrumb-item>Commodity management</el-breadcrumb-item> <el-breadcrumb-item>Classification parameters</el-breadcrumb-item> </el-breadcrumb> <!-- Card view area --> <el-card> <!-- Warning area :closable="false"(Show or not“ X"number) show-icon(Display icon) --> <el-alert title="Note: only relevant parameters can be set for the third level classification" type="warning" :closable="false" show-icon> </el-alert> <!-- Select commodity classification area --> <el-row class="cat_opt"> <el-col> <span>Select product category:</span> <!-- Select the cascading selection box for the product category --> </el-col> <el-col></el-col> </el-row> </el-card> </div> </template>
C. Complete cascade selection box
Complete the cascading selection box of commodity classification
<!-- Select commodity classification area --> <el-row class="cat_opt"> <el-col> <span>Select product category:</span> <!-- Select the cascading selection box for the product category --> <el-cascader expandTrigger='hover' v-model="selectedCateKeys" :options="cateList" :props="cateProps" @change="handleChange" clearable></el-cascader> </el-col> <el-col></el-col> </el-row> ...... <script> export default { data() { return { //Classification list cateList:[], //The category id selected by the user in the cascade drop-down menu selectedCateKeys:[], //How to display data in the configuration cascade menu cateProps: { value: 'cat_id', label: 'cat_name', children: 'children' } } }, created() { this.getCateList() }, methods: { async getCateList(){ //Get a list of all product categories const { data: res } = await this.$http.get('categories') if (res.meta.status !== 200) { return this.$message.error('Failed to get classification data') } //Assign data list to cateList this.cateList = res.data // //Total number of data saved // this.total = res.data.total // console.log(res.data); }, handleChange(){ //Triggered when the user selects a content change in the cascade menu console.log(this.selectedCateKeys); } } } </script>
D. Display parameters
Display dynamic parameter data and static attribute data
<!-- tab Tab area --> <el-tabs v-model="activeName" @tab-click="handleTabClick"> <!-- Add panel of dynamic parameters and change the tab to many --> <el-tab-pane label="dynamic parameter " name="many"> <el-button size="mini" type="primary" :disabled="isButtonDisabled">Add parameter</el-button> <!-- Dynamic parameter table --> <el-table :data="manyTableData" border stripe> <!-- Expand row --> <el-table-column type="expand"></el-table-column> <!-- Index column --> <el-table-column type="index"></el-table-column> <el-table-column label="Parameter name" prop="attr_name"></el-table-column> <el-table-column label="operation"> <template slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">edit</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">delete</el-button> </template> </el-table-column> </el-table> </el-tab-pane> <!-- Add a panel with static properties and change the tab to only --> <el-tab-pane label="Static properties" name="only"> <el-button size="mini" type="primary" :disabled="isButtonDisabled">Add attribute</el-button> <!-- Static attribute table --> <el-table :data="onlyTableData" border stripe> <!-- Expand row --> <el-table-column type="expand"></el-table-column> <!-- Index column --> <el-table-column type="index"></el-table-column> <el-table-column label="Attribute name" prop="attr_name"></el-table-column> <el-table-column label="operation"> <template slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">edit</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">delete</el-button> </template> </el-table-column> </el-table> </el-tab-pane> </el-tabs> <script> export default { data() { return { ...... //Tab activate the displayed tab items activeName: 'many', //Used to save dynamic parameter data manyTableData: [], //Used to save static attribute data onlyTableData: [] } methods: { ....... async handleChange() { //Triggered when the user selects a content change in the cascade menu console.log(this.selectedCateKeys) //Send a request and obtain parameter data according to the three-level classification and panel selected by the user const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('Failed to get parameter list data') } console.log(res.data) if (this.activeName === 'many') { //Dynamic parameters are obtained this.manyTableData = res.data } else if (this.activeName === 'only') { //Get static properties this.onlyTableData = res.data } }, handleTabClick() { console.log(this.activeName) this.handleChange() } }, computed: { //Add a calculation attribute to get whether the button is disabled or not isButtonDisabled() { return this.selectedCateKeys.length !== 3 }, //Get the selected three-level classification id cateId() { if (this.selectedCateKeys.length === 3) { return this.selectedCateKeys[this.selectedCateKeys.length - 1] } return null } }
E. Add parameter
Finish adding parameters or attributes
<!-- Add parameter or property dialog box --> <el-dialog :title="'add to'+titleText" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed"> <!-- Add form --> <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px"> <el-form-item :label="titleText" prop="attr_name"> <el-input v-model="addForm.attr_name"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="addDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="addParams">determine</el-button> </span> </el-dialog> export default { data() { return { ....... //Controls the addition of parameters Display or hide of the properties dialog box addDialogVisible: false, //Form data object for adding parameters addForm: { attr_name: '' }, //Add form validation rule addFormRules: { attr_name: [{ required: true, message: 'Please enter a name', trigger: 'blur' }] } } },methods: { ....... addParams() { //When the user clicks OK in the dialog box, the form will be verified this.$refs.addFormRef.validate(async valid => { //Failed verification, return if (!valid) return //If the verification is passed, send the request to complete the addition of parameters or attributes const { data: res } = this.$http.post(`categories/${this.cateId}/attributes`, { attr_name: this.addForm.attr_name, attr_sel: this.activeName, attr_vals: "a,b,c" } ) console.log(res) if (res.meta.status !== 201) { return this.$message.error('add to' + this.titleText + 'Data failure') } this.$message.success('add to' + this.titleText + 'Data success') this.addDialogVisible = false this.getCateList() }) } }
F. Edit parameters
Finish editing parameters or attributes
<!-- Modify parameters or properties dialog box --> <el-dialog :title="'modify'+titleText" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed"> <!-- Add form --> <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="100px"> <el-form-item :label="titleText" prop="attr_name"> <el-input v-model="editForm.attr_name"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="editDialogVisible = false">Cancel</el-button> <el-button type="primary" @click="editParams">determine</el-button> </span> </el-dialog> export default { data() { return { ....... //Control and modify parameters Show or hide the properties dialog box editDialogVisible:false, //Modify parameters Form in properties dialog box editForm:{ attr_name:'' }, //Modify the validation rules of the form editFormRules:{ attr_name:[ { required: true, message: 'Please enter a name', trigger: 'blur' } ] } } },methods: { ....... async showEditDialog(attr_id){ //Initiate a request to obtain the parameter data to be modified const {data:res} = await this.$http.get(`categories/${this.cateId}/attributes/${attr_id}`, {params:{ attr_sel:this.activeName }}) if (res.meta.status !== 200) { return this.$message.error('Failed to get parameter data') } this.editForm = res.data; //Display modified parameters properties dialog this.editDialogVisible = true; }, editDialogClosed(){ //Modify parameters when closing Properties dialog box this.$refs.editFormRef.resetFields() }, editParams(){ //validate form this.$refs.editFormRef.validate(async valid => { if(!valid) return; //Send request to complete modification const {data:res} = await this.$http.put(`categories/${this.cateId}/attributes/${this.editForm.attr_id}`, {attr_name:this.editForm.attr_name,attr_sel:this.activeName}) if (res.meta.status !== 200) { return this.$message.error('Failed to get parameter data') } this.$message.success('modify' + this.titleText + 'Data success') this.editDialogVisible = false this.handleChange(); }) } }
G. Delete parameter
Delete parameter or attribute
Add events to the two delete buttons <el-button size="mini" type="danger" icon="el-icon-delete" @click="removeParams(scope.row.attr_id)">delete</el-button> <el-button size="mini" type="danger" icon="el-icon-delete" @click="removeParams(scope.row.attr_id)">delete</el-button> Add the corresponding event handler function async removeParams(attr_id){ //Delete the corresponding parameter or attribute according to the id //The pop-up window prompts the user whether to delete it const confirmResult = await this.$confirm( 'Would you like to delete this'+this.titleText, 'Delete prompt', { confirmButtonText: 'confirm deletion', cancelButtonText: 'cancel', type: 'warning' } ).catch(err => err) //If the user clicks confirm, the confirm result is' confirm ' //If the user clicks cancel, confirmResult will get the error message 'Cancel' of catch if (confirmResult != 'confirm') { return this.$message.info('The deletion has been cancelled') } //If you don't cancel, you just want to delete. Send a request to complete the deletion const {data:res} = await this.$http.delete(`categories/${this.cateId}/attributes/${attr_id}`) if (res.meta.status !== 200) { return this.$message.error('Failed to delete parameter data') } this.$message.success('delete' + this.titleText + 'Data success') this.handleChange() }