Vue.js learning notes
First stop
Initial use
js
// Let / const how to create variables const app = new Vue({ el:'#app ', / / used to mount elements to be managed data:{ // Define data message: 'How do you do!', name: 'hello How do you do' }, // Method area, in which methods can be called in HTML methods: { // Define a click method click: function() { alert("Hello") } }, // Calculation properties computed: { upChar(message) { message.up } } // Execute this zone method before the web page is created beforeCreate: function (){ console.log("beforeCreate"); }, // Execute this zone method after the web page is created created: function() { console.log("created"); }, // mounted: function() { console.log("mounted"); }, })
In HTML
<!-- app Module name and vue Used in el Consistent mount name --> <div id="app"> <!-- moustache grammar: use: {}To introduce data Data in moustache Simple calculations can be used in: + - * / --> <h2>{{message}}</h2> <h1>{{name}}</h1> </div> <!-- Import vue modular --> <script src="../js/vue.js"></script>
Primary grammar
- v-on: used to bind events
- Syntax: "@"
- example:
- v-on:click="click"
- @click="click"
- v-for="item in movies" traverse every data in the array moves, and item is every data
- v-html="url" is displayed in HTML
- v-text="message" displayed as text
- v-pre displays the contents of the label intact
- v-cloak displays the label content only after the vue code is executed
- After v-once modification, the content will not change, only the first value will be displayed
- v-bind dynamic binding
- Syntax:
- example:
- v-bind:style="color:blue";
- :style="color:blue";
assembly
-
Create a component (similarly, the component also has its own data field, which can be used like the attributes of vue instances, but the data attribute in the component must be a function)
const cpn1 = Vue.extend({ template: ` <div> <h1>Component 1</h1> </div> `, data() { return { message: "hello" } } })
-
Register components
-
Global registration component
// Component name component instance Vue.component('my-cpn', cpn1)
-
Grammatical sugar writing
Vue.component('my-cpn', { template: ` <div> <h1>Component 1</h1> </div> ` })
-
Local registration component
Vue({ el: "#app", components: { //Component name component instance my-cpn: cpn1 }, data: { message: "Hello" } })
-
-
Using components (components created must be within Vue managed instances)
<div id="app"> <!--Can be used multiple times--> <my-cpn></my-cpn> </div>
-
Create subcomponents in components
Vue.extend({ template: ` <div> <div>Parent component</div> <cpn1></cpn1> </div> `, components: { cpn1: cpn1 } })
-
Extract the template from js and put it into the html tag
-
Method 1:
<!--Write template to script In the label, script Type must be: text/x-template--> <script type="text/x-template" id="cpn"> <div>I'm a component</div> </script>
-
Mode 2:
<template id="cpn"> <div>I'm a component</div> </template>
-
-
Register components
Vue.component("cpn", { template: "#cpn" })
Second stop
Communication between parent and child components
-
Passing information to subcomponents
<body> <div id="app"> <div>{{message}}</div> <!--The name of the accepted information in the subcomponent is hello, hello2,The name of the data information passed in the parent component is message,message2--> <!--If not used v-bind(:)The string will be message and message2 Passed to child components, not·Information in parent component--> <cpn :hello="message" :hello2="message2" :child-message-info="info"/> </div> </body> <template id="cpn"> <!--vue2 The template must contain a root tag--> <div> <div>I am a subcomponent</div> <div>Information in parent component:</div> <div>{{hello}}</div> <div>{{hello2}}</div> <div>{{childMessageInfo}}</div> </div> </template> <script> cpn = { template: "#cpn", // It is used to store the information passed in the parent component // Mode 1: props: ['hello', 'hello2'] // Method 2: (at this time, the information types transmitted to the sub components are limited, here is the string type) props: { hello: string, hello2: string } // Method 3: (at this time, not only the type is limited, but also the default value. When the parent component does not send information, the default value will be used) props: { hello: { type: string, default: "I'm the default", // Indicates that information must be passed required: true }, hello2: { type: Array, // An error will be reported when the default value is [] // default: [] // When the type is an object or array, the default value must be a function default() { return [] } } // When the sub information receiving variable is hump identification variable, it shall be indicated by adding "-" in other places childMessageInfo: { type: Object, default() { return {} } } } } new Vue({ el: "#app", components: { cpn }, data: { message: "Hello, I'm the parent component", message2: "Hello, this is the second message", info: { name: "Zhang San", age: 18 } } }) </script>
-
Pass information to parent component
<body> <div id="app"> <!--Bind the name of the event emitted by the subcomponent to the listening function. The bound here is childClick event--> <!--vue2 Hump writing cannot be resolved in, but in vue Can be resolved in scaffold--> <cpn @item-click="childClick"></cpn> </div> </body> <template id="cpn"> <div> <h1>I am a subcomponent</h1> <!--When the button is clicked, the function is triggered to send events--> <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button> </div> </template> <script> const cpn = { template: "#cpn", data() { return { categories: [ {id: '01', name: 'Mobile digital'}, {id: '02', name: 'Household Electric Appliances'}, {id: '03', name: 'Clothing decoration'}, {id: '04', name: 'Practical small pieces'} ] } }, methods: { btnClick(item) { // Launch event (user-defined event). The name of the launch event is the first parameter, and the second parameter is the sent content this.$emit('item-click', item) } } } new Vue({ el: "#app", components: { cpn }, date: { message: "Child to parent communication between parent and child components" }, methods: { // The variables received here by default are those sent by the subcomponent childClick(item) { console.log("Received", item) } } }) </script>
watch
-
watch is used to listen for property changes
<body> <div id="app"> <div>{{message}}</div> </div> </body> <script src="vue/vue.js"></script> <script> const app = new Vue({ el: "#app", data: { message: "hello world" }, watch: { // Here, the watch function name must be the data name in data, where newVal and oldVal are the new value and old value respectively message(newVal, oldVal) { console.log(newVla, oldVal) } } }) </script>
Access mode of parent-child components
Parent component accessing child components:
c h i l d r e n : t h i s . children: this. children: this.children is an array type that contains all child component objects
$refs
Child component access parent component:
$parent
-
The parent component calls the method in the child component
<body> <div id="app"> <!--adopt ref Property to use the subcomponent in the component--> <cpn ref="cpn1"></cpn> <cpn ref="cpn2"></cpn> <button @click="btnClick">Call from component method</button> </div> </body> <template id="cpn"> <div>Subcomponents</div> </template> <script> const cpn = Vue.component("cpn", { template: "#cpn", data() { return { message: "I am the information in the subcomponent" } }, methods: { showMSG() { alert("Call succeeded!") } } }) new Vue({ el: "#app", components: { cpn }, data: { message: "hello world" }, methods: { btnClick() { // Generally, $refs is used instead of the $children attribute this.$children[0].showMSG() alert(this.$children[0].message) // This method is recommended this.$refs.cpn1.showMSG() console.log(this.$refs.cpn2.message) } } }) </script>
-
The child component calls the method in the parent component
<body> <div id="app"> <cpn></cpn> </div> <template id="cpn"> <div> <div>I am a subcomponent</div> <button @click="btnClick">Call method in parent component</button> </div> </template> </body> <script> const cpn = Vue.component("cpn", { template: "#cpn", methods: { btnClick() { // Use the $parent attribute to access the parent component, but this method is not recommended (there may be multiple parent components due to high coupling) this.$parent.showMSG() console.log(this.$parent.message); // Access to the root component uses $root. In this example, $parent is the same as $root console.log(this.$root.message) } } }) new Vue({ el: "#app", components: { cpn }, data: { message: "Hello, I'm the parent component" }, methods: { showMSG() { alert("Access succeeded!") } } }) </script>
slot
Using slots in functional components with similar structure can bring great convenience
-
Define slot
<body> <div id="app"> <cpn><button>Introduced through slot button Button</button></cpn> <cpn><a>Add by slot a label</a></cpn> <cpn></cpn> </div> <template id="cpn"> <div> <div>Subcomponents</div> <!--When a component contains multiple slots, they are all used by name, and the slots in the component will be replaced by the contents in the component--> <slot></slot> <!--This slot contains a default value. When this slot is introduced, if no element is added to the component, it will be added to the element by default. If there are elements, the default element will be replaced with the specified element--> <slot><button></button></slot> </div> </template> </body> <script> const cpn = { template: "#cpn" } new Vue({ el: "#app", components: { cpn } }) </script>
-
Named slot
<body> <div id="app"> <!--Use when replacing slot Property to replace a slot with a specific name. The scope of the slot only works under a template. Here input Will not be displayed because isShow stay vue In the instance false Therefore, it will not be displayed--> <cpn><input v-show="isShow" slot="center"/></cpn> </div> <template id="cpn"> <div> <!--When using a named slot, you must select the name of the slot to replace--> <slot name="left"><span>left</span></slot> <slot name="center"><span>middle</span></slot> <slot name="right"><span>right</span></slot> </div> </template> </body> <script> const cpn = { template: "#cpn", data() { return: { isShow: true } } } new Vue({ el: "#app", components: { cpn }, data: { isShow: false } }) </script>
-
Reference the data in the child component in the parent component
<body> <div id="app"> <cpn></cpn> <cpn> <!-- In 2.5.x Must be used before template Template, in 2.5.x Later, this constraint is cancelled and data is referenced in the template --> <template slot-scope="slot"> <span v-for="item in slot.data">{{item}} --- </span> </template> </cpn> <cpn> <!-- among slot-scope It is a fixed writing method, and the subsequent value is the referenced sub component --> <div slot-scope="sl"> <!-- From subcomponents data Domain value --> <a href="#" v-for="item in sl.data"> --{{item}}-- </a> </div> </cpn> <cpn2></cpn2> <cpn2> <div slot-scope="s"> <!--join Function will be used in the middle of the array - To split--> <!-- Due to the use of message To store variables, so it must also be used when referencing message --> <i>{{s.message.join(' - ')}}</i> </div> </cpn2> </div> <template id="cpn"> <div> <div>I am a subcomponent</div> <!--data You can name yourself, you can data Change to another variable name. You must also use another variable name when referencing--> <slot :data="arr"> <ul> <li v-for="item in arr">{{item}}</li> </ul> </slot> </div> </template> <template id="cpn2"> <div> <div>I am sub component 2</div> <slot :message="arr"> <ul> <li v-for="item in arr">{{item}}</li> </ul> </slot> </div> </template> </body> <script> new Vue({ el: "#app", components: { cpn: { template: "#cpn", data() { return { arr: ['java', 'c', 'c++', 'php'] } } }, cpn2: { template: "#cpn2", data() { return { arr: ['Tomatoes', 'tomato', 'Pumpkin', 'White gourd'] } } } } }) </script>
In vue-cli3 and above versions, the following methods shall be used for slot use
<!-- Use here v-slot: To specify a named slot --> <template v-slot:header> <h1>Here might be a page title</h1> </template> <template v-slot:footer> <p>Here's some contact info</p> </template>
life cycle
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-GFZaIs0n-1626776658174)(D:\Dahui\DesktopApp \ learning materials \ learning notes \ front end \ JavaScript forgetting knowledge points \ Vue.js\Vue.js learning notes \ img\lifecycle.png)]
Modular development
-
commonjs syntax
-
a.js
let name = "Xiao Ming" let age = 18 let sayHello = function () { console.log("hello: " + name) } modlue.export = { name, age, sayHello }
-
b.js
let name = "Xiao Hong" let age = 19 let sayHello = () => { console.log("hello: " + name) } modlue.exports = { name, age, sayHello }
-
main.js
let {name, age, sayHello} = require("./a.js")
-
Use in main page
<!--Add on import type Properties will not have naming conflicts--> <script src="main.js" type="module"></script> <script src="a.js" type="module"></script> <script src="b.js" type="module"></script>
-
-
ES6 syntax
-
a.js
let name = "Xiao Ming" let age = 18 let sayHello = (msg) => { console.log("hello, " + msg) } // Export method 1: export { name, age, sayHello } // Export method 2: (when defining variables, export directly) export let num = 1 // derived function export function sum(num1, num2) { return num1 + num2 } // Export class // ES5 syntax export function Person() { let name let age } // ES6 syntax export class Person{ let name let age } // (for the above export methods, you can only use the name when exporting in other files.) // Export default can be unnamed during export. There can only be one export default in a file. When importing, you can rename export default Perosn
-
b.js
import {name, age, sayHello} from './a.js' // At this time, the default export data of the export file is imported, which can be renamed during import import presonA from './a.js' // At this time, it is imported and stored in an obj object. When accessing, you can use "obj "Form of import * as obj from './a,js' console.log(obj.name) (() => { console.log(name + "The age of the students is:" + age) })() sayHello(name + ",pet name:")
-
Packaging with webpack
Initial use
The instruction webpack is used when packaging/ src/main. js -o ./ dist/
If the webpack is above 4.0, the - o option should be used to specify the output address. In previous versions, the - o option is not required. It is not necessary to specify the name of the output file. If it is specified, it will be displayed in the form of a folder and a main. File will be generated by default JS file
When packaging, you only need to specify the entry file, and other js files do not need to be packaged
webpack configuration
The configuration file name of webpack is fixed as webpack config. js
During configuration, it is necessary to introduce node related packages to dynamically obtain paths. It is necessary to execute npm init instruction at the terminal to generate a package JSON file
-
webpack.config.js
// Obtain the absolute path through the module introducing node const path = require('path') module.exports = { // Imported entry entry: './src/main.js', // Exported exit output: { // It is required that path must be an absolute path, and the resolve function of path can dynamically obtain the path // __ dirname is the global variable of node. The join function can be used to splice two paths. Here is the absolute path and 'dist' path of the file // In webpack4 0 used the resolve function to splice paths path: path.join(__dirname, 'dist'), filename: "bundle.js" } }
-
package.json
Comment code snippets are not allowed in json files
{ "name": "meet", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", // A mapping is built here. At this time, only the build instruction needs to be executed to execute packaging (npm run build is executed at the terminal) // An instruction (build) is defined here. When the instruction is executed, the local search will be given priority. If the local search does not exist, the global search will be taken // The commands you type in the command window will be found globally "build": "webpack" }, "author": "", "license": "ISC", "description": "" }
- At this time, just click the webpack or npm run build command on the terminal to realize automatic packaging
-
Development time dependency: npm install webpack@3.6.0 --save-dev
-
Runtime dependency: npm install vue --save
-
Automatically generated package JSON file
-
package.json
{ "name": "meet", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode development", // Configure the webpack service startup instruction. Parameters: - open set self startup "server": "webpack-dev-serve --open" }, "author": "", "license": "ISC", "description": "", // During development, the package downloaded through the -- save dev instruction will be saved here "devDependencies": { "webpack": "^3.6.0" }, // Runtime dependency "dependencies": { } }
-
webpack loader
-
Use the npm install package name -- save dev to download the corresponding loader, and then webpack config. JS
-
Then main js can rely on related css files or other js files. You only need to import the packaged js file after packaging, rather than in index Introducing css or other js files into HTML
-
webpack.config.js
// Obtain the absolute path through the module introducing node const path = require('path') module.exports = { // Imported entry entry: './src/main.js', // Exported exit output: { // It is required that path must be an absolute path, and the resolve function of path can dynamically obtain the path // __ dirname is the global variable of node. The resolve function can be used to splice two paths. Here is the absolute path and 'dist' path of the file path: path.join(__dirname, 'dist'), filename: "bundle.js" }, module: { rules: [{ // Regular expressions are used for matching, and the following two loader s will be used for matching test: /\.css$/, // CSS loader is only responsible for loading // The style loader is responsible for adding styles to the DOM // When using multiple loader s, load from right to left use: ['style-loader', 'css-loader'] }, { test: /\.less$/i, use: [ // compiles Less to CSS "style-loader", "css-loader", "less-loader", ], }] } }
webpack.config.js detailed configuration
An error may be reported when importing vue directly: prompt that you are using runtime only. This template cannot be compiled. You should use compiler included. To solve this problem, you need to go to webpack config. Configuration vue information in JS
// Obtain the absolute path through the module introducing node const path = require('path') // Import the package of webpack, and then you can import the plug-in of webpack const webpack = require("webpack") // Import automatically generated index HTML plugin const HtmlWebPackPlugin = require('html-webpack-plugin') // Import the auto ugly js code plug-in const uglifyJsPlugin = require("uglifyjs-webpack-plugin") module.exports = { // Imported entry entry: './src/main.js', // Exported exit output: { // It is required that path must be an absolute path, and the resolve function of path can dynamically obtain the path // __ dirname is the global variable of node. The resolve function can be used to splice two paths. Here is the absolute path and 'dist' path of the file path: path.join(__dirname, 'dist'), filename: "bundle.js", // When the file is packaged, there will be a path error for the file imported through css or other files. At this time, a public address needs to be configured. When other files are loaded, the public address will be spliced automatically publicPath: "dist/" }, module: { rules: [{ // Regular expressions are used for matching, and the following two loader s will be used for matching test: /\.css$/, // CSS loader is only responsible for loading // The style loader is responsible for adding styles to the DOM // When using multiple loader s, load from right to left use: ['style-loader', 'css-loader'] }, { test: /\.less$/i, use: [ // compiles Less to CSS "style-loader", "css-loader", "less-loader", ], }, { test: /\.(png|jpg|gif|jpeg|webp)$/i, use: [{ loader: 'url-loader', // Limit the size of the file introduced by the url. The unit here is bytes and the size here is 8kb options: { // When the loaded image is less than the limit, the image will be compiled into base64 string form limit: 1000, // Here, the file naming method "[]" is set for the packaged file, indicating the meaning of variable. Here, the packaged file is stored in the img folder, and the name is the name of the original file. 8 is the hash value Extension name: 'img/[name].[hash:8].[ext]' } }], }, { test: /\.(png|jpe?g|gif|webp)$/i, use: [{ loader: 'file-loader' }], }, { // This loader is a loader that converts es6 to es5 test: /\.m?js$/, // exclude, the following files will not be used by this loader exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } },{ test: /\.vue$/, use: ['vue-loader'] }] }, resolve: { // Using this configuration eliminates the file extension extensions: ['.js', '.vue', '.css'], // Alias: alias. When vue is introduced, vue will be found in the specified folder. When this configuration is added, the problem that the template cannot be loaded will be solved alias: { 'vue$': 'vue/dist/vue.esm.js' } }, plugins: [ // This plug-in can add copyright notes to each packaged file new webpack.BannerPlugin("The final copyright belongs to Xiao Ming"), // This plug-in will automatically generate the index after packaging HTML file, there will be no need to configure the publicPath path path at this time new HtmlWebPackPlugin({ // According to index Generate index.html template HTML file template: "index.html" }), // Using the ugly plug-in, the js code will be automatically ugly after packaging to compress the js file new uglifyJsPlugin() ], // This configuration is only required during development and can be deleted during publishing devServer: { // Specify the folder for the service contentBase: "./dist", // Specifies whether to listen in real time inline: true, // Specify the server port. The default is port 8080 port: 8080 } }
-
When there are both El attribute and template attribute in the vue instance, template will replace everything mounted by el
-
App.vue
<template> <h1>{{message}}</h1> </template> <script> export default { name: "App", data() { return { message: "hello world" } } } </script> <style scoped> body { background-color: green; } </style>
-
main.js
// Introduction of vue module import Vue from 'vue' // Import components import App from './vue/App' new Vue({ el: "#app", // At this point, the template template will replace el the mounted content template: "<App/>", components: { // Component mount App } })
-
webpack. config. Separation of JS files
-
base.config.js basic configuration
// Obtain the absolute path through the module introducing node const path = require('path') // Import the package of webpack, and then you can import the plug-in of webpack const webpack = require("webpack") // Import automatically generated index HTML plugin const HtmlWebPackPlugin = require('html-webpack-plugin') module.exports = { // Imported entry entry: './src/main.js', // Exported exit output: { // It is required that path must be an absolute path, and the resolve function of path can dynamically obtain the path // __ dirname is the global variable of node. The resolve function can be used to splice two paths. Here is the absolute path and 'dist' path of the file // After the webpack configuration file is separated, the packaging path needs to be modified and added before the second parameter/ // path: path.join(__dirname, 'dist'), path: path.join(__dirname, '../dist'), filename: "bundle.js", // When the file is packaged, there will be a path error for the file imported through css or other files. At this time, a public address needs to be configured. When other files are loaded, the public address will be spliced automatically publicPath: "dist/" }, module: { rules: [{ // Regular expressions are used for matching, and the following two loader s will be used for matching test: /\.css$/, // CSS loader is only responsible for loading // The style loader is responsible for adding styles to the DOM // When using multiple loader s, load from right to left use: ['style-loader', 'css-loader'] }, { test: /\.less$/i, use: [ // compiles Less to CSS "style-loader", "css-loader", "less-loader", ], }, { test: /\.(png|jpg|gif|jpeg|webp)$/i, use: [{ loader: 'url-loader', // Limit the size of the file introduced by the url. The unit here is bytes and the size here is 8kb options: { // When the loaded image is less than the limit, the image will be compiled into base64 string form limit: 1000, // Here, the file naming method "[]" is set for the packaged file, indicating the meaning of variable. Here, the packaged file is stored in the img folder, and the name is the name of the original file. 8 is the hash value Extension name: 'img/[name].[hash:8].[ext]' } }], }, { test: /\.(png|jpe?g|gif|webp)$/i, use: [{ loader: 'file-loader' }], }, { // This loader is a loader that converts es6 to es5 test: /\.m?js$/, // exclude, the following files will not be used by this loader exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } },{ test: /\.vue$/, use: ['vue-loader'] }] }, resolve: { // Using this configuration eliminates the file extension extensions: ['.js', '.vue', '.css'], // Alias: alias alias: { 'vue$': 'vue/dist/vue.esm.js' } }, plugins: [ // This plug-in can add copyright notes to each file new webpack.BannerPlugin("The final copyright belongs to Xiao Ming"), // This plug-in will automatically generate the index after packaging HTML file new HtmlWebPackPlugin({ // According to index Generate index.html template HTML file template: "index.html" }) ] }
-
dev.config.js development time dependent configuration
const webpackMerge = require("webpack-merge") const baseConfig = require("./base.config") module.exports = new webpackMerge(baseConfig, { devServer: { // Specify the folder for the service contentBase: "./dist", // Specifies whether to listen in real time inline: true, // Specify the server port. The default is port 8080 port: 8080 } })
-
pro.config.js project depends on when publishing
const webpackMerge = require("webpack-merge") // Import the auto ugly js code plug-in const uglifyJsPlugin = require("uglifyjs-webpack-plugin") const baseConfig = require("./base.config") module.exports = (baseConfig, { plugins: [ // Using the ugly plug-in, the js code will be automatically ugly after packaging to compress the js file new uglifyJsPlugin() ] })
-
In this case, you need to enter package Add webpack. JSP to the JSON file config. JS file, otherwise an error will be reported, and the configuration file of webpack cannot be found
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", // --config specifies the path "build": "webpack --mode development --config ./build/pro.config.js", "dev": "webpack-dev-serve --config ./build/dev.config.js" }
-
Third stop
vue-cli
If you are using the version of vue - cli 2, use the command: vue init webpack project name to create
vue - cli higher version creation command: vue create item name creation
render function
vue execution principle:
runtime - complier execution principle:
tempalte --> ast(abstract tree) --> render --> virtual dom --> UI
runtime - only execution principle:
render --> virtual dom --> UI
// Create an object using the render function render: function (createELement) { retun createELement('div', {class: 'box'}, ['I am by render Function to render the label', createELement('button', {id: 'btn'}, ['Button'])]) } // Pass in the component object using the render function const cpn = { template: '<div>{{message}}</div>', data() { return { message: "I'm a component" } } } render: function (createELement) { retun createELement(cpn) }
In vue3, the configuration file is hidden by default. If you want to import your own configuration, you need to create: Vue config. JS file, the file name is fixed
vue.config.js
module.export = { ... }
Vue - Router
Prelude:
There are some ways to change the url, but the page does not refresh
Use location hash = ‘a’; You can add a after the address bar, that is, the original is www.baidu.com Com can be transformed into: www.baidu.com com/a
Use history Pushstate ({}, '' and 'a') can achieve the same effect as hash. This method is to put the newly added connection into the stack and then use history Back() function, it will return layer by layer
- Parameters:
- data
- title
- url
history.replaceState({}, ',' b ') in this way, the original url will be overwritten and cannot be returned to the previous page through the back() function
history.back() returns to the previous page
history.go()
- history.go(-1) and history Back() equivalent
- history.go(-2) will pop up two addresses in the stack, that is, return twice
- history.forword() is equivalent to history go(1)
- history.go(2) will be pushed into two addresses in the stack, that is, forward twice
Vue router configuration
Create the router folder in the src directory, and create the index JS file, which configures routing related information
router – > index. JS (vue3 and below)
// The import vue is used to register components in subsequent import Vue from 'vue' // Import route, used to configure route related information import VueRouter from 'vue-router' // Install plug-ins Vue.use(VueRouter) // Import components import App from '../App.vue' import About from '../components/About' import Profile from '../components/Profile.vue' // Configure path related variables const routes = [ { path: '', // Use redirection to navigate to the / home path at the beginning of the page redirect: '/home' },{ path: '/about', component: About },{ // Use /: userId to dynamically splice url paths. In the Profile component, you can use: this$ route. params. userId gets the incoming userId information path: '/profile/:userId', component: Profile }] // Create routing object const router = new VueRouter({ routes, // Change the default mode of the path. The default mode is hash (this mode will make the path contain #). Here, change the edge to history mode mode: 'history', // Change to the class name of the rendered label after clicking router link linkActiveClass: 'active' }) // Export router export default router
router – > index. JS (vue3 above usage)
// Import routing related objects import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' import Home from '../views/Home.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) export default router
On app How to guide to this page in Vue
<template> <div id="app"> <!-- router-link and router-view Label is router Automatically registered components can be used directly --> <!-- use router-link Label, which will change to by default after rendering a label --> <router-link to="/about">about</router-link> <!-- use tag Property changes the rendered result to button label, replace Property causes the path change to use substitution instead of stack pressing, that is, it cannot be returned --> <!-- When clicking on a router-link After rendering the label, vue Two are automatically added before the change class Class( router-link-active and router-link-exact-active),This class name can be used to set the style after clicking. Use active-class Property can be changed after the tag is clicked class Property, here change to active ,Can be in router Make changes uniformly in the configuration file--> <router-link to="/profile" tag="button" replace active-class="active">my</router-link> <!-- Change the of the page by url Page Jump --> <button @click="aboutClick">about</button> <button @click="profileClick">my</button> <!-- Dynamic splicing path, add dynamic path splicing information after the jump --> <router-link to="/profile/xiaoming">my</router-link> <!-- Dynamic splicing path, add dynamic path splicing information after the jump. Here is at data Search in userId variable --> <router-link :to="'/profile/' + userId">my</router-link> <!-- router-view Components will make router-link The point in the label is rendered here, that is, replace router-view label --> <router-view/> </div> </template> <script> export default { name: 'App', data() { return { userId: 'xiaoming' } } methods: { // Click to listen for events aboutClick() { // Router injects a $router attribute into each component, which can jump the page this.$router.push('/about') }, profileClick() { // Page Jump is performed through replace, and the page jumped by this method cannot be returned this.$router.replace('/profile') }, } } </script>
Get the url path of user splicing in the sub component through this$ route. params. userId (userId is the dynamic variable set in the route) to obtain the route object that is active at this time
js files are divided through the lazy loading mechanism of routing, so that users will not have a short blank and unresponsive state when accessing for the first time, and a lazy loading will correspond to a packaged js file
There are three ways to load routes
- Method 1 (combining asynchronous components of vue and code analysis of webpack) is not recommended:
const routes = [ { path: '/', component: Home = resolve => {require.ensure(['../components/Home.vue'], () => {resolve(require('../components/'))} )} } ]
- Method 2 (AMD writing method):
const routes = [ { path: '/', component: Home = resolve => require(['../components/Home.vue'], resolve} } ]
- Mode 3 (ES6) recommended:
const routes = [ { path: '/', component: Home = () => import ('../components/Home.vue') } ] // Better practice const Home = () => import ('../components/Home.vue') const routes = [ { path: '/', component: Home } ]
- Components are further subdivided to configure sub routes
const Home = () => import('../components/Home.vue') const News = () => import('../components/News.vue') const Fun = () => import('../components/Fun.vue') const routes = [ { path: '/', component: Home, // The children attribute is used to determine the information related to the sub component route of the component. The sub route does not need to add '/' children: [ { path: 'news', component: News },{ path: 'fun', component: Fun } ] } ]
- In the parent component, add the router link and router view labels as in configuring the normal route, and set the display position and time of the child component
<template> <div id="app"> <!-- Here is the path where you want to add the parent component --> <router-link :to="'/home/news">Journalism</router-link> <router-view/> </div> </template>
- Jump the interface and transfer parameters in another way
<template> <div id="app"> <router-link :to="{path: '/profile', query: {name: 'xiaoming', age: 18}}">Journalism</router-link> <router-view/> <!-- adopt query To get the currently passed parameter object --> <div>{{$router.query}}</div> </template>
- Setting jump and parameter transfer through ordinary label
<template> <div id="app"> <button @click="aboutClick">about</button> <button @click="profileClick">My 11</button> <router-view/> </div> </template> <script> export default { name: 'App', data() { return { userId: 'xiaoming' } } methods: { // Click to listen for events aboutClick() { // Router injects a $router attribute into each component, which can jump the page this.$router.push('/about') }, profileClick() { // Page Jump is performed through replace, and the page jumped by this method cannot be returned this.$router.push({ path: '/profile', query: { name: 'xiaoming', age: 18 } }) }, } } </script>
Route and route are not the same. Route represents the currently active routing object, and route represents the whole routing object
Extension:
-
Add a property to an object:
const obj = { name: 'xiaoming' } // Through object The defineproperty () method adds properties to the object (this method is reactive) // Parameter 1 is the object to add the attribute, parameter 2 is the added attribute name, and parameter 3 is the attribute value Object.defineProperty(obj, 'age', 18)
-
When the page jumps, the title name of the page in the table
// This method will be called after the build is created. However, this method must be used in each component, so it is not recommended created() { // This method can change the title name of each web page document.title = "user" } // As a better practice, add the following code to the routing configuration file const routes = [ { path: '/', component: Home = () => import ('../components/Home.vue'), // Add element data for each routing object to change the title name when jumping to the page meta: { title: 'home page' } } ] // These methods can also be written directly in each mapping relationship // Front guard router.beforeEach((to, from ,next) => { // From and to, i.e. jump from to // When there are nested routes, the parent route will not find the title attribute. In this case, set the title of the meta in the matched attribute document.titile = to.matched[0].meta.title // Next means the next step. This function must be called. When this function is not called, there will be no page transfer // Parameters can be passed in the next function. When the parameter is false, interrupt the current navigation or pass in a path, that is, jump to the path next() }) // Rear hook router.afterEach((to, from) => { // There is no next parameter in the post hook, that is, this method will not be called until the page is skipped })
Using the keep alive tag to nest the router view tag can not create and destroy frequently (because the components will be created and destroyed frequently during switching), but cache it, which will greatly improve the response time
-
Two properties of keep alive
<!-- include String or regular expression, only matching components will be cached --> <!-- exclude String or regular expression, any matched component will not be cached --> <!-- Not cached here Home and Profile Component, where exclude The value of the property does not exist in each component name Property value, used by multiple components , No space is allowed between the segments --> <keep-alive exclude="Home,Profile"> <route-view/> </keep-alive> <!-- Not only cache here Home and Profile Component, where include The value of the property does not exist in each component name Property value, used by multiple components , No space is allowed between the segments --> <keep-alive include="Home,Profile"> <route-view/> </keep-alive>
-
When the page is skipped, the setting returns to the original page, and the display is the same before the page is skipped
export default { name: 'home', data() { return { // The path variable is used to record the last active path, which can be used when jumping back later path: '/home/news' } }, // This function is called when the page jumps, that is, before the route conversion beforeRouteLeave(to, from , next) { this.path = this.$route.path next() }, // This function is called when the page is active activated() { this.$router.push(this.path) } }
-
activated and deactivated lifecycle functions
export default { name: 'home', // Only when the component is kept alive can it be effective. Otherwise, these two functions will not be called automatically // This function is called when the page is active activated() { console.log('activated') }, deactivated() { console.log('deactivated') } }
Configure the path mapping relationship in the file
- In vue2 version, find webpack base. config. JS file (i.e. webpack configuration file), modify resolve and add the corresponding path mapping relationship
resolve: { alias: { '@': resolve('src') 'assets': resolve('src/ssets'), 'components': resolve('src/components'), 'views': resolve('src/views') } }
- Because the related configuration files are hidden in vue3, you need to create a Vue. Exe in the root directory config. JS file (you need to restart the following items every time you modify the configuration file), write the following information in the file to configure the relevant path mapping relationship
module.exports = { configureWebpack: { resolve: { alias: { 'assets': '@/assets', 'components': '@/components', 'views': '@/views' } } } }
When importing in non import mode (for example, importing resource files, pictures, etc.), you need to add "~" in front of it, for example: ~ assets/img/1.jpg
Promise usage
- Asynchronously requesting network data may lead to callback hell. Using Promise can simplify programming and make the code look clearer. The code only needs to be written in the then function
new Promise((resolve, reject) => { // Use setTimeout to simulate asynchronous operations setTimeout(() => { //Call the resolve function resolve() }, 1000) }).then(() => { // The logical structure of the code is processed here console.log("hello xiaoming") // Returns a Promise object, which will be called later return new Promise((resolve, reject) => { setTimeout(() => { // Parameters can be passed in the resolve function and accepted in then resolve("hello xiaohong") }, 1000) }) // The parameter in then is the parameter passed when the resolve function is called }).then((data) => { console.log(data) return new Promise((resolve, reject) => { setTimeout(() => { // resolve is called when successful, and reject is called when failed reject("err ^ ... ^") } ,1000) }) // The then function is executed only when the resolve function is called, and the catch function is executed when the reject function is called }).then(() => { console.log("hello xiaogang") // The second statement will not be executed }).catch((err) => { console.log(err) }) // The execution result of the program is to output a print statement every second
- Another form of Promise
new Promise((resolve, reject) => { setTimeout(() => { resolve("hello xiaogang") // reject("err ^ ... ^") }, 1000) // In the then function, two parameters can be passed, one is the data return result and the other is the error information, that is, the data information return and error information printing can be completed at the same time in the then function }).then(data => { console.log(data) }, err => { console.log(err) })
- Promise multi-level call, single-level asynchronous abbreviation
new Promise((resolve, reject) => { // Use setTimeout to simulate asynchronous operation, which is only used in this stage of network request setTimeout(() => { resolve("hello xiaoming") }, 1000) }).then((data) => { // The logical structure of the code is processed here console.log(data) // Returns the result after calling the resolve function. There is no asynchronous processing here. You can call the resolve function directly, modify the value of the data each time, and print it in the following calls return Promise.reject(data + "1") // The reject function is called here, that is, the following then will not be executed // You can also use throw directly to throw an exception // throw 'error' }).then((data) => { // This function will not execute console.log(data) return Promise.resolve(data + "2") }).then(data => { // This function will not execute console.log(data) }, err => { // This function will execute console.log(err) }) // The print result is Xiaoming \ n Xiaoming1
- Promise further abbreviation
new Promise((resolve, reject) => { // Use setTimeout to simulate asynchronous operation, which is only used in this stage of network request setTimeout(() => { resolve("hello xiaoming") }, 1000) }).then((data) => { // The logical structure of the code is processed here console.log(data) // Return the result after data processing without calling promise Resolve() function return data + "1" }).then((data) => { console.log(data) return data + "2" }).then(data => { console.log(data) }, err => { console.log(err) })
- Promise.all() method
// Promise. The all method needs to pass in an array, and each array is used to encapsulate different network requests Promise.all([ new Promise((resolve, reject) => { setTimeout(() => { resolve("Xiao Ming") }, 2000) }), new Promise((resolve, reject) => { setTimeout(() => { resolve("Xiao Hong") }, 1000) }) // The data object is an array, which is used to store the results of two asynchronous processing operations ]).then(data => { console.log(data[0]) console.log(data[1]) }) // The result is Xiao Ming \ n Xiao Hong
The fourth stop
Vuex status manager
When multiple components want to use the same state (variable), vuex can be used to store the state in the state manager. In this way, multiple components can be directly taken from the State Manager (equivalent to a storage container of a global variable)
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-WKp5GoUB-1626776658179)(D:\Dahui\DesktopApp \ learning materials \ learning notes \ front end \ JavaScript forgetting knowledge points \ Vue.js\Vue.js learning notes \ img\flow.png)]
Related configuration of Vuex
In the src folder, create a price inquiry folder named store (meaning warehouse, used to store various statuses), and create index JS file
index.js(vue2.x)
// Import Vue to register components in subsequent import Vue from 'vue' // Import Vuex to create the object later import Vuex from 'vuex' // Register the plug-in Vue.use(Vuex) // Create Vuex object const store = new Vuex.Store({ // The state object is used to save the state (variable), and you only need to use this elsewhere$ store. state. Variable name to access the variable state: { }, // The only way to update the store status of vuex is through mutation mutations: { }, actions: { }, // Similar to the calculation attribute in the component, if you want to use it after changing the status each time, you need to implement it here getters: { }, // Used to divide modules modules: { } }) // Export the created store object export default store
In main JS
main.js
import Vue from 'vue' import App from './App' import store from './store/index.js' new Vue({ el: '#app', store, render: h => h(App) })
In vue3 The following methods are used in X
- index.js(vue3.x)
import { createStore } from 'vuex' export default createStore({ // State is used to store the state for sharing state: { count: 100 }, mutations: { // Use this method to modify the count variable. The modified method will automatically pass in a parameter state to access the variables in state decreasement(state) { state.count -- }, increasement(state) { state.count -- } }, actions: { }, modules: { } })
In main JS
- main.js
import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' createApp(App).use(store).use(router).mount('#app')
Modify the state in the State Manager
When modifying a state in the state manager, if you use this$ store. state. When variable name = value, which component has modified the state when it is not known in later debugging. In order to facilitate later maintenance, it should be changed in an official way
- The figure shows how to change in the status manager
- Devtools is a plug-in for debugging vue in the browser. Mutions can only handle synchronous operations. Operations such as asynchronous requests cannot be affected by the Action phase, otherwise devtools cannot track them
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-hRdMiLDQ-1626776658183)(D:\Dahui\DesktopApp \ learning materials \ learning notes \ front end \ JavaScript forgetting knowledge points \ Vue.js\Vue.js learning notes \ img\vuex.png)]
Modify the status by the following methods
- App.vue
<template> <div id="app"> <div>{{$store.state.count}}</div> <div>{{$store.getters.powerCounter}}</div> <div>{{$store.getters.length}}</div> <!-- Pass in parameters here to modify the status with parameters --> <div>{{$store.getters.mergeS('a')}}</div> <button @click="additionCount(5)">+5</button> <button @click="addition">+</button> <button @click="substract">-</button> </div> </template> <script> export default { name: 'App', methods: { addition() { // Call the function in the state manager by submitting, and the parameter is the function to be called this.$store.commit('increment') }, substract() { this.$store.commit('decrement') }, additionCount(count) { // Parameters can be passed in the calls to the changes method by passing in the second parameter this.$store.commit("increasementCount", count) // Special submission method. When parameters are passed in this way, the passed past is actually an object, and parameters need to be used when accessing count this.$store.commit({ type: 'increasementCount', count }) } } } </script>
- index.js (vuex configuration file in store folder)
import { createStore } from 'vuex' export default createStore({ state: { count: 100, obj: { age: 18 } }, // The state is modified by functions in this object mutations: { // When called in the change method, it will automatically access the state object, which is a user-defined state increment(state) { state.count ++ }, decrement(state) { state.count -- }, increasementCount(state, count) { state.count += count }, update(state) { // In 2 In version x, this property will not be added to the responsive system, but in later versions, this feature has been fixed and can be modified responsively state.obj['name'] = "xiaoming" // In vue, you can use vue The set () method adds an attribute to the object, which can be added to the responsive system. Parameter 1 is the object to be modified, parameter 2 is added to the attribute, and parameter 3 is the attribute value Vue.set(state.obj, 'name', 'xiaoming') // Using the delete keyword can delete an attribute in an object, but this method cannot be responsive delete state.obj.age // Instead, use Vue The delete () method can responsively delete an attribute in an object. Parameter 1 is the object to be modified and parameter 2 is the deleted attribute (Vue.2x) Vue.delete(state.obj, age) } }, getters: { // Here, you can directly use the modified data and $store getters. Powercount to access powerCounter(state) { return state.count * state.count }, // This method will pass in a getters by default, which is the getters defined here length(state, getters) { return getters.powerCounter >= 10000 ? 10 : getters.powerCounter }, mergeS(state) { // When this method is called, it returns a function, in which you can pass in a function, and the function can return the modified state through the passed in parameters return function(num) { return state.count + num }, // More concise writing, but it is not recommended because it is not good to understand mergeS(state) { return num => state.count + num } } }, actions: { // Define a method in which a parameter will be passed by default. The parameter is the created store object, and the parameter 2 is the passed in parameter aUpdate(context, payload) { // When modifying the state in the store object, you can only modify the parameters in the store object through changes // When asynchronous operations are executed, execute the methods in changes through actions. Only in this way can devtools dynamically track the state changes in the store object. When executing the methods in actions, use this$ store. dispatch("aUpate") setTimeout(() => { context.commit("increment") }, 1000) }, // A method to remind the outside that it has been successfully modified. Parameter 2 is a function passed during external submission: this$ store. Dispatch ("aupdate", () = > {console. Log ("it has been modified")}) aUpdate(context, payload) { setTimeout(() => { context.commit("increment") // Call this function payload() }, 1000) }, // Another way is to pass parameters in this way as follows: this$ store. Dispatch ("update", {message: 'I am the message', success: () = > {console. Log ("it has been modified")}) aUpdate(context, payload) { setTimeout(() => { context.commit("increment") // Call this function payload.success() }, 1000) }, // Another more elegant way aUpdate(context, payload) { retrun new Promise((resolve, reject) => { setTimeout(() => { context.commit("increment") console.log(payload) resolve("Pass on past information") }, 1000) }) } // When calling this method elsewhere, the code is as follows this .$store.dispath("aUpdate", "Carry past information") .then(res => { console.log(res) }) }, moduleA = { state: { name: "xiaoming" }, mutations: { updateName(state, payload) { state.name = payload } }, actions: { // The context here is the module object updateName(context) { // When you use commit here, the method submitted is the method in the changes in the module context.commit("updateName", 'xiaogang') } }, getters: { update(state) { return state.name + "1" }, // Here getters is the getters update2(state, getters) { return getters.update + "1" }, // Here getters is the getters and rootState is the root store object update3(state, getters, rootState) { // You can access the state of the root store object through rootState return getters.update + rootState.count } }, modules: {} } moduleB = { state: {}, mutations: {}, actions: {}, getters: {}, modules: {} } // Modules can be defined in this object, and state and other attributes can be defined in the module. Unlimited dolls can be set. When in use: this$ store. moduleA. Name, when calling the method in mutations: this$ Store ("updatename", "Xiaohong"), so don't repeat the changes in each module // When using the methods in getters, it is also used directly: this$ store. getters. Update, so the methods defined in getters cannot be repeated modules: { moduleA: moduleA moduleB: moduleB } })
The official recommendation is to extract attributes other than state and modules into external files. You only need to import them in the index. The corresponding modules in modules are extracted into the new modules folder
- extend
When calling some functions in variations, the name of the function that may be called will be written incorrectly, which can be avoided by defining constants
Create the file changes - type. In the store folder JS file
mutations-type.js
export const INCREMENT = 'increment' export const DECREMENT = 'increment'
The method name in the store folder can also be defined in this way
import { createStore } from 'vuex' import {INCREMENT, DECREMENT} from './mutations-type.js' export default createStore({ state: { }, // This method can reduce errors mutations: { [INCREMENT](state) { state.count ++ }, [DECREMENT](state) { state.count -- }, }, getters: { }, actions: { }, modules: { } })
When referencing elsewhere, you only need to write the following code
import {INCREMENT, DECREMENT} from './store/mutations-type.js' // . . . this.$store.commit(INCREMENT) // . . . this.$store.commit(DECREMENT) // . . .
Network requests using Axios
index.js
// Import related modules import axios from 'axios' axios({ // This address can be used for network testing url: 'http://httpbin.org' // By default, it is a get request. You can modify the request method by setting the value of method method: 'get' // The parameters passed in are specified through the params attribute params: { name: xiaoming, age: 18 } // Because axios supports Promise, Promise can be used to receive data }).then(res => { console.log(res) })
axios sends concurrent requests
import axios from 'axios' // This method returns all the requested results, puts the results into an array, and gets results in then. The object is an array axios.all([axios({ // Set base address baseURL: 'http://httpbin.org' url: '/home' }), axios({ url: 'http://httpbin.org' })]).then(results => { console.log(results) }) axios.all([axios({ url: 'http://httpbin.org' }), axios({ url: 'http://httpbin.org' })]).then(axios.spread((res1, res2) => { // Via Axios The spread method can segment the obtained results console.log(res1) console.log(res2) }))
Global configuration of axios
import axios from 'axios' axios.default.baseURL = "http://httpbin.org" // Sets the timeout in milliseconds axios.timeOut = 50000
axios instance
import axios from 'axios' const instance1 = axios.create({ baseURL: 'http://httpbin.org', timeout: 5000 }) const instance2 = axios.create({ baseURL: 'http://baidu.com', timeout: 3000, headers: { } }) instance1({ url: '/home', params: { name: xiaoming } }).then(res => { console.log(res) }) instance2({ url: '/category', params: { name: xiaoming, age: 18 } }).then(res => { console.log(res) })
Modular network request
When designing the network request module, it is best to write the network request to a separate file, so that when the network request framework is not maintained, it is easy to replace other frameworks
Create a separate folder: network, and create request JS file
request.js
import axios from 'axios' // Mode 1: export function request(config, success, failure) { const instance = axios.create({ baseURL: 'http://baidu.com', timeout: 5000 }) instance(config).then(res => { success(res) }).catch(err => { failure(err) }) } // Mode 2: export function request(config) { const instance = axios.create({ baseURL: 'http://baidu.com', timeout: 5000 }) instance(config.baseConfig).then(res => { config.success(res) }).catch(err => { config.failure(err) }) } // Mode 3: export function request(config) { return new Promise((resolve, reject) => { const instance = axios.create({ baseURL: 'http://baidu.com', timeout: 5000 }) instance(config).then(res => { resolve(res) }).catch(err => { reject(err) }) }) } // Mode 4: export function request(config) { const instance = axios.create({ baseURL: 'http://baidu.com', timeout: 5000 }) return instance(config) }
When using this module:
import { request } from './network/request.js' // Corresponding mode I request({ url: '/home' }, res=> { console.log(res) }, err => { console.log(err) }) // Corresponding mode 2 request({ baseConfig: { url: '/home' }, success: function(res) { console.log(res) }, failure: function(err) { console.log(err) } }) // Corresponding modes 3 and 4 request({ url: '/home' }).then(res => { console.log(res) }).catch(err => { console.log(err) })
axios interceptor
import axios from 'axios' export function request(config) { return new Promise((resolve, reject) => { const instance = axios.create({ baseURL: 'http://baidu.com', timeout: 5000 }) // request interceptor instance.interceptors.request.use(config => { // When you need to modify the configuration information, you can use the interceptor to modify it. When the user requests network data, you can add a response animation. When the user logs in, you can jump to the page without a token // This function returns configuration information console.log(config) // When the return configuration information is missing, the address will not be requested successfully, that is, the information is intercepted. But it did not continue down return config }, err => { // This function returns an error message console.log(err) }) // Response interceptor instance.interceptors.response.use(res => { // The parameters passed in by this method are the results returned after the request console.log(res) // After modification, the response information needs to return the data, otherwise the information will not be received elsewhere return res.data }, err => { // This function is called when the request fails console.log(err) }) return instance(config) }) }
nce(config).then(res => {
success(res)
}).catch(err => {
failure(err)
})
}
//Mode 2:
export function request(config) {
const instance = axios.create({
baseURL: 'http://baidu.com',
timeout: 5000
})
instance(config.baseConfig).then(res => { config.success(res) }).catch(err => { config.failure(err) })
}
//Mode 3:
export function request(config) {
return new Promise((resolve, reject) => {
const instance = axios.create({
baseURL: 'http://baidu.com',
timeout: 5000
})
instance(config).then(res => { resolve(res) }).catch(err => { reject(err) }) })
}
//Mode 4:
export function request(config) {
const instance = axios.create({
baseURL: 'http://baidu.com',
timeout: 5000
})
return instance(config)
}
When using this module: ```js import { request } from './network/request.js' // Corresponding mode I request({ url: '/home' }, res=> { console.log(res) }, err => { console.log(err) }) // Corresponding mode 2 request({ baseConfig: { url: '/home' }, success: function(res) { console.log(res) }, failure: function(err) { console.log(err) } }) // Corresponding modes 3 and 4 request({ url: '/home' }).then(res => { console.log(res) }).catch(err => { console.log(err) })
axios interceptor
import axios from 'axios' export function request(config) { return new Promise((resolve, reject) => { const instance = axios.create({ baseURL: 'http://baidu.com', timeout: 5000 }) // request interceptor instance.interceptors.request.use(config => { // When you need to modify the configuration information, you can use the interceptor to modify it. When the user requests network data, you can add a response animation. When the user logs in, you can jump to the page without a token // This function returns configuration information console.log(config) // When the return configuration information is missing, the address will not be requested successfully, that is, the information is intercepted. But it did not continue down return config }, err => { // This function returns an error message console.log(err) }) // Response interceptor instance.interceptors.response.use(res => { // The parameters passed in by this method are the results returned after the request console.log(res) // After modification, the response information needs to return the data, otherwise the information will not be received elsewhere return res.data }, err => { // This function is called when the request fails console.log(err) }) return instance(config) }) }