1. Development environment of the project
Development dependencies:
"dependencies": {
"axios": "^ 0.21.1"."babel-plugin-transform-remove-console": "^ 6.9.4"."core-js": "^ 3.6.5." "."echarts": "^ 5.1.2." "."element-ui": "^ 2.4.5"."moment": "^ 2.29.1"."nprogress": "^ 0.2.0." "."quill": "^ 1.3.6." "."vue": "^ 2.6.11." "."vue-quill-editor": "^ 3.0.6"."vue-router": "^ 3.2.0"."vue-table-with-tree-grid": "^ 0.2.4." "."vuex": "^ 3.4.0"
},
Copy the code
Element-ui is installed globally
Vue add element- UI // Enter in terminalCopy the code
You can see here that let’s choose to import all or import on demand, at this point we choose import on demandImport on demand \
Then select zh-cn and you can see that there is a plugins folder with an element.js file and an import in main.js. However, if we look closely, we can see that babel.config.js is also injected with relevant content.Copy the code
Element-ui —-> Form Form
<template>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="Activity Name" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">Immediately create</el-button>
<el-button @click="resetForm('ruleForm')">reset</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
ruleForm: {
name: ' '
},
rules: {
name: [{required: true.message: 'Please enter an activity name'.trigger: 'blur' },
{ min: 3.max: 5.message: 'Between 3 and 5 characters long'.trigger: 'blur'}]}}},methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) = > {
if (valid) {
// Verify successful execution of this code block
alert('submit! ')}else {
// Validate failed to execute this code block
console.log('error submit!! ')
return false}})},resetForm(formName) {
// Reset the form
this.$refs[formName].resetFields()
}
}
}
</script>
Copy the code
RuleForm: input Bidirectional binding data rules: verification rule of the form prop: field name to be verified
Element-ui —-> Cascader cascading selector
<el-cascader v-model="value" :options="options" @change="handleChange"></el-cascader>
Copy the code
Options: An optional data source. The key name can be configured using the Props property
Props:
Click /hover default ‘click’ checkStrictly: whether parent nodes are strictly observed not to associate with each other value: specifies the value of the option as an attribute value of the option object label: Children: Specifies that the children of the option are an attribute value of the option object
Element-ui —-> Pagination
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage4"
:page-sizes="[100, 200, 300, 400]." "
:page-size="100" layout="total, sizes, prev, pager, next, jumper"
:total="400">
</el-pagination>
Copy the code
Page-change and current-change: events to handle page size and current page changes page-sizes: Accepts an array of integer elements that are displayed as options for selecting the number of displays per page. [100, 200, 300, 400] represents four options for displaying 100, 200, 300, or 400 data per page. Total: indicates the total number of displays
2. Implement the login interface
When the user clicks the login button, the user will make a data request, and save the token after successful login to the sessionStorage of the client, and then jump to the route. At the same time, the token is carried in axios request interceptor. Finally, the global front-guard of the route is used to read the stored in sessionStorage to determine whether there is a value, if there is a value to jump, otherwise return to the login page.
Click event for the login button
submitForm(formName) {
this.$refs[formName].validate((valid) = > {
if(! valid)return
this.$http.post('login'.this.ruleForm).then(res= > {
console.log(res.data)
if(res.data.meta.status ! = =200) return this.$message.error('Login failed! ')
this.$message.success('Login successful')
// 1. Save the token in the sessionStorage of the client
// There are other API interfaces in the 1.1 project, which must be accessed after login
// 1.2 Token should only take effect while the current site is open, so save token in sessionStorage
window.sessionStorage.setItem('token', res.data.data.token)
// 2. Use the programmatic navigation to go to the background home page. The route address is /home
this.$router.push('/home')})})},})Copy the code
Request interceptor
axios.interceptors.request.use((config) = > {
// This config contains tokens
config.headers.Authorization = window.sessionStorage.getItem('token') | |' '
return config
})
Copy the code
Global front guard
router.beforeEach((to, from, next) = > {
// to Specifies the path to be accessed
// from indicates the path from which to jump
// next is a function that permits
// next() permits next('/login') forces a jump
if (to.path === '/login') return next()
/ / access token
const tokenStr = window.sessionStorage.getItem('token')
if(! tokenStr)return next('/login')
next()
})
Copy the code
3. The layout of the entire page is based on the Container layout Container in the common component of Element-UI
<el-container>
<el-header>Header</el-header> / / to the head
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
</el-container>
Copy the code
4. Project —-> Optimization
4.1. To add a progress bar to the project, use nProgress
NPM install nprogress -s // nprogress has two methods: start() done()Copy the code
Configuration:
1.Start by importing nProgress inside the wrapped AXIOSimport NProgress from 'nprogress'
2.Add nprogress.start () to the request interceptor// What time does it start
3.Add nprogress.done () to the response interceptor// When will it be finished
Copy the code
4.2. Modify warnings and errors during packaging
4.3 Unpacking console.log(unpacking console.log() during the release phase)
To automatically remove console.log(), use babel-plugin-transform-remove-console.
NPM install babel-plugin-transform-remove-console -dCopy the code
Configuration: In babel.config.js, configure the following
const proPlugins = []
if (process.env.NODE_ENV === 'production') {
proPlugins.push('transform-remove-console')}module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'].plugins: [
...proPlugins // Expand the array]}Copy the code
4.4. Complete multiple entry for packaging, separating the entry for development and release stages
Create a main-dev.js file and a main-prod.js file. Copy the contents of main.js to these two files and configure the following contents in vue.config.js:
module.exports = {
chainWebpack: config= > {
// Publish mode
config.when(process.env.NODE_ENV === 'production'.config= > {
// entry Finds the default packing entry. Clear deletes the default packing entry
// add adds a new packing entry
config.entry('app').clear().add('./src/main-prod.js')})// Development mode
config.when(process.env.NODE_ENV === 'development'.config= > {
config.entry('app').clear().add('./src/main-dev.js')}}}Copy the code
4.5. Replace references to local files with CDN loads
First add the following to the publishing mode configured above in vue.config.js
config.when(process.env.NODE_ENV === 'production'.config= > {
config.entry('app').clear().add('./src/main-prod.js')
config.set('externals', {
vue: 'Vue'.'vue-router': 'VueRouter'.axios: 'axios'.echarts: 'echarts'.nprogress: 'NProgress'.moment: 'moment'.lodash: '_'.quill: 'quill'
})
// html-webpack-plugin assigns index to isProd
config.plugin('html').tap(args= > {
args[0].isProd = true
return args
})
})
Copy the code
Add the CDN to the index. HTML file in the public directory as follows:
The < %if(htmlWebpackPlugin.options.isProd) { %> // Determine if it is a development phase, if it is, replace it with the contents of {}
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.core.min.js"></script><! -- moment --><script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js"></script><! -- elementUI --><script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.2/index.min.js"></script>< link href = "https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.2/theme-chalk/index.min.css" rel = "stylesheet" > < link Href = "https://cdn.bootcdn.net/ajax/libs/quill/1.3.6/quill.snow.min.css" rel = "stylesheet" > < %} % >Copy the code
4.6. Enable GZIP compression
Configure the following information in vue.config.js:
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js'.'css']
configureWebpack: {
plugins: [
// configure compression-webpack-plugin compression
new CompressionWebpackPlugin({
algorithm: 'gzip'.test: new RegExp('\ \. (' + productionGzipExtensions.join('|') + '$'),
threshold: 10240.minRatio: 0.8})]Copy the code
4.7. Enable lazy route loading
{
path: 'welcome'.component: () = > import('.. /views/Welcome.vue')},Copy the code