Vue2.0
Declarative programming, imperative programming responsive: data change, interface automatic changeCopy the code
.stopPrevents the child's listener from triggering the parent.preventPrevents default events from happening,form-input
input-text,@keyupsimilar@click
@keyup.enter="Function name"Listen for clicks (in this case enter) on a particular keycap @click.once="Function name"Only trigger a / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / v - if ="Variable name"Controls whether or not the label should be rendered. True, false correspond to V-else, V-else. With v-if and V-else, make a switch to enter the user name and user mailbox interface div-> two V-if /else span, -> label for="xx"And input the id ="xx"Placeholder you'll see that the input field remains in the placeholder, not empty /* label for="xxx"Click on the text to select input Type = with id XXX"radio" name="sex/age..."*/ Why? (VUE - bottom layer) VUE puts what we are going to display into memory, creates a VDOM (virtual DOM) in memory, and when rendering dom, for performance reasons, reuses existing elements as much as possible rather than creating new ones. So we still use the original label and input, but compare rendering, and empty everything except the user input. Solution: Add a key to the corresponding input and make sure the key is different. Won't reuse / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - the if and v/v - show can choose whether to display the page elements But false, The v-if disappears completely and does not exist in the DOM -- creating and removing v-shows just add adisplay:none;
Copy the code
Insert a new element in the middle of the array let's say we have4Li, A, B, C, and D. At this point, we're going to insert E in the middle of BC and we're going to assume that in vDOM right now0-A 1-B 2-C 3-d (vue low-level) is A, B, C, and D in the DOM.0-A 1-B 2-E 3-C 4In -d vDOM, after E is inserted,3The number position is changed to the original2Number C, create4In dom, according to the Diff algorithm, A, B, C, AND D change to A, B, E, C, and D in A similar order to the previous row (also change from top to bottom C to E, D to C, and finally insert D). The efficiency is very low at this time, we need to set the key to make A unique identification for each node. If multiple Li keys are the same, an error is reportedeg: <li v-for="item in array" :key="item">{{item}}</li>An array insert With a key, as shown in the image above With Keys, has a one-to-one feel.0For A,1B and so on. The E to be inserted will be inserted into the appropriate position after the original array is paired up, rather than having the data change one by one/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /Push -- add unshift -- add header (add can pass multiple values) pop-- delete shift-- delete variable parameters in headerfunction sum(. num) { clg(num); } splice(start position, number of deleted, element used for replacement) delete/insert/replace splice(1) to delete1And all subsequent vue.set (this.array,0.'xxx'The first parameter is an array object, the second parameter is index, and the third parameter is the modified valuethis.array[index]='xxx', will change the value, but not reactive, the page remains the same/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
Copy the code
filter/map/reduce
Filter/Map/Reduce Filters: The callback function in filter has one requirement: it must return a Boolean valueconst nums = [10.20.123.450.45]
let newNums = nums.filter(function(n){
return n<100; }) returnstrue, the function automatically adds "n of this callback" (the array element that meets the condition) to the new array/* The new array is automatically created and we are responsible for receiving it */
false: Filters out the n map function: mapping operationconst nums = [10.20.123.450.45]
let newNums = nums.map(function(n){
return n*2; }) will treat the returned value as the new value of the original position in the array. Reduce function: sums up all the contents of the array/*(this function definition uses ts) has function overload function, can write two functions, the same name does not overwrite, the number of arguments to make the function difference */
const nums = [10.20.123.450.45]
let total = nums.reduce(function(preValue,n){
return preValue+ n
},0Two arguments, each of which is a function, and the second parameter is the initialization value. Parameter one takes a function that has two arguments preValue for the previous timereturn, n is the value of each array traversal, and the first preValue is the initial value of reduce parameter 2./* The first preValue==0, n==10. The second preValue==0+10==10, n==20. The third preValue==20+10==30, and so on. Return preValue+n returns the sum of all the numbers in the array. * /Synthesis: functional programmingconst nums = [10.20.123.450.45]
let total = nums.filter(function(n){
return n<100
}).map(function(n){
return n*2
}).reduce(function(preVaule,n){
return preValue + n
},0Arrow functionlet total =nums.filter(n= >n<100).map(n= >n*2).reduce((pre,n) = >pre+n); The default value of reduce parameter 2 is0the/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /Programming Paradigm -- Imperative/Declarative Programming Programming Paradigm -- Object-oriented programming (First Citizen: objects)/Functional programming (First Citizen: Functions)/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /@input (input) {@click (input) {@input (input) {@click (click) {1.V-bind binds a value attribute2.The V-ON directive binds the current element to the input event <input type="text" v-model="message"> is equivalent to <input type="text" v-bind:value="message" v-on:input="message=$event.target.value">
/////////////////////////////////////////////////////////////////////////
<input type="number"/* Only numbers plus */ can be enteredv-model="age">
<h2>{{age}}--{{typeof age}}</h2>Vue age:0 --> start with 0 and number The number that you put in and the string that you're going to say is bidirectional binding, the value that's being passed in real time, is being passed as a string and in order for it to be number, V -model.number="age"; v-model.number="age"; v-model.number="age"; But data processing when the trim can be used to remove the blank space * / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /Copy the code
componentization
Component: a closed space where I can have my own data and have my own methods
Component -- abbr. CPN ES6 supplement,'This can contain a newline' 而' 'As well as""To use a component, you have to make sure that it's registered in scope, either globally or in the parent component's components or else you'll get an error, Unknown Custom Element < tag >/ / example:
const cpnC1=Vue.extend({
template:`<div><span>nothing1</span></div>`,})const cpnC2=Vue.extend({
template:`<div><span>nothing1</span></div>`.components: {cpn1:cpnC1
}
})
const app = new Vue({
el:'#app'.components: {cpn2:cpnC2
}
})
<div id="app">
<cpn2></cpn2> // Component 2 is called directly
<cpn1></cpn1> CpnC1 is registered within the cpnC2 component and is scoped to the component cpnC2
</div>
// The solution
// Components can be registered multiple times, and again in the Vue instance components
Copy the code
Component code is separated from HTML1. script type="text/x-template"
2.Put a template tag around it and notice that you need to add an ID to both script and template tags and then in your js code, template:'#id'
////////////////////////////////////////////////////////////////////////////The component does not have access to Vue instance data data internally, so the component has a data property internally, but it cannot be an object type, it should befunctionAnd returns an object containing data <template id="theid">
<div> h2.p.{{title}} </div>
</template>
Vue.component('cpn', {template:'#theid'.data(){
return {
title:'abc'}}}) component objects also have methods and declared periodic functions, much like a Vue instance, to which the prototype of the component points////////////////////////////////////////////////////////////////////////////Why does data have to be a function in a Vue component? Each time a function is executed, a new variable is created in stack space/ / case
function abc(){
return { name:'whe'.age:18}}let obj1= abc() letObj2 = ABC () Obj1 and obj2 are two different object tests: obj1.name="mmmm" console.log(obj2.name) you make a module whose functions are timers, a count div, and a add and subtract button that you refer to2Submodule, so in both modules, count is two different variables. Conclusion: using a function to return a new object each time, can avoid - multiple component instances to share variables to artificially share variables, canconst obj={ count:0} Vue.com ponentdata(){ returnObj}, so we're sharing the count of obj////////////////////////////////////////////////////////////////////////////HTML is case insensitive. And JS differentiates. So in general, JS case variables in HTML will change the uppercase to lowercase and will be preceded by a dash. So don't use camelCase and PascalCase for event names, because even if you do use this name, it will be automatically converted to all lowercase in DOM templates, such as <input type="text" v-on:keyup.F2=113> is automatically converted to <input type="text" v-on:keyup.f2=113> and: Vue v-bind/on etc. Does not support the hump named - "father and son communication components, don't use hump variable naming, default value will be shown Unless, that is, the case oneself do a conversion, eg: the child component data in CPN textMyMessage in CPN labels when converted to write HTML: text - my - the message////////////////////////////////////////////////////////////////////////////When defining child component templates, reference data <template><h2>{{cmessage}}</h2>
<h2>{{aamessage}}</h2></template> will report an error. You need to put a div <template> around both data references.<div>
<h2>{{cmessage}}</h2>
<h2>{{aamessage}}</h2>
</div>
</template>
///////////////////////////////////////////////////////////////////////////////////The v-bind component doesn't use a hump name, Why does the template Script Style tag in the.vue file compile into a component object that doesn't have a template? It renders the component object into a render function that resolves the name of the hump during rendering. HTML that works is written in lower case///////////////////////////////////////////////////////////////////////////////////Parent passes to children: props -- write in the props constructor, usually in object form, and pass to the parent in the CPN tag corresponding to the assignment parent: Events -- Child $emit() triggers events, parent components V-ON, @ listen on child component eventsdata: {num1:1
},
components: {// Subcomponent -- syntactic sugar
cpn: {props: {number1:Number // Define variable names and types}}},}) in the template tag: If you want input V-model bidirectional binding data, do not bind to number1. You can still do this, but you will get an error. Because number1 itself is taken from the parent component, you can't change both the parent component data and the input data// Instead, use a data or computed property based on the prop's valueSo, in a child component, use data or computed to compute the entire new variableeg: in the component abovecpn: {props: {number1:Number
},
data(){
return {
dnumber1: this.number1,}}} then input text V-model ="dnumber1"If you want to change the num1 value of the parent component, then: Instead of selecting the V-model, or, instead, the @ and V-on template tags: <input :value="dnumber1" @input="num1Input"> // Listen for the event num1Input
// Go to the child component to define num1InputSubcomponent: methods:{num1Input(event){
this.dnumber1 = event.target.value; // This only changes dnumber1
this.$emit('num1change'.this.dnumber1) // Each input emits data to the parent component}} then: div id="app", CPN tag, < CPN :number1="num1" @num1change="parent_num1change"/> Parent component:methods: {parents_num1change(value){ // Where value is the dnumber1 transmitted by the child component
this.num1= parseInt(value) // A string is passed}}ParseInt (string) parseInt(string)And then after the input value, it's going to change dnumber1, it's going to change num1, it's going to change num2, number2, dnumber2, it's going to change num2 and it's num1100And finally add to the methods of sub-components:this.dnumber2 = this.denumber1*100;
this.$emit('num2change'.this.dnumber2); In components, with the data and the template, props, the methods, the computed at the same level of the role and watch: monitoring the change of the variable - note: if the child components, return can also monitor the data in an objecteg:
data(){
return {
dnumber1:this.number1; }},watch: {dnumber1(newValue){
this.dnumber1 = newValue*10;
this.$emit('num1change',newValue);
// This. Denumber2 =0;
}
// If you change a variable above, you can also listen below
dnumber2(newValue){
// Runs when dnumber2 changes}}// In addition to newValue, there can be a second argument, oldValue
Copy the code
How parent and child components are accessed
// The parent accesses the child$children or $refs// The child accesses the parentFor example, in a Vue instance, there is a child component CPN, and a child component methods that defines a method showMessageshowMessage(){
console.log('showMessage'); } The parent component methods defines a method called btnClick// triggered by a button click in div #app
btnClick(){
console.log(this.$children);
// Return an array containing VueComponent - component objects
this.$children[0].showMessage(); // The console prints showMessage, referring to the child component method
}
// If CPN tags are referenced multiple times in HTML (even if they are the same), the returned array will be multiple VueComponent objects
// If you add a component in front of it, the index changes completely. $children $childrenThe usual $refs for development starts with an empty object in the component tag: < CPN ref="aa"></ CPN >this.$refs.aa references the VueComponent object////////////////////////////////////////////////////////////////$parent is rarely used because it makes components less reusable. $root accesses the root component, the highest level component, Vue instance, but data is usually null.Copy the code
Advanced componentization
/ / slotsIn the template tag, the slot tag can be used to indicate that the reserved slot is followed by`div #app`In the CPN tag, you can add several tags, such as P, div, button, etc. These tags will be rendered in the slot tag position. If the slot tag has other tags, it means that the CPN tag has no other tags// Named slot
<template id="cpn">
<div>
<slot name="left"><span>On the left</span></slot>
<slot name="right"><span>On the right</span></slot>
</div>
</template>
<div id="app">
<cpn><span slot="left">Replace the words</span></cpn>// If no slot attribute is added, the span of the two slots will be changed to "replace text".</div>
// Add scope
`template`Tags within the CPN subcomponent scope`div #app`Boolean variable isHow Official rule: Everything in the parent component template is compiled in the parent scope; Everything in the subcomponent template is compiled in the subscope////////////////////////////////////////////////////////////////////////Scope slot -- Purpose:The parent component replaces the label of the slot, but the content is provided by the child componentThe parent is not satisfied with the data presented by the child and needs to display it in a different way, so it needs to fetch data from the child. Eg: The child's data contains an array, and I want to display the contents <templat ID ="cpn">
<div>
<slot> ul <li v-for="item in array" >{{item}} </li> /ul </slot>
</div></template> In div #app < CPN >< CPN >< CPN >< CPN >< CPN >< CPN > If you want to get the data array of the subcomponent in the second CPN, v-for will not work. <templat ID =" CPN "> <div> // Add an attribute (dat) to the slot tag, equal to the desired array array <slot: DAT ="array"> ul <li V -for="item in array" >{{item}} </li> /ul </slot> </div> </template> < CPN > <template slot-scope="slot"> // <span v-for="item in slot.dat">{{item}} - </span> <span>{{slot.dat.join(' - ')}}</span> </template> </cpn>Copy the code
Webpack
ES6 modular supplement
// Start with some modular ES6 stuffAdd type= to the script tag"module"You can make.js files so modular that other files cannot be accessed directlyexportExport,importThe import/ / method
export{variable name1The variable name2.. }import{variable name1The variable name2} from "./ filene.js";
/ / method 2:
export var num1=1000;
import {num1} from "./ filene.js";
// Export by default
const address = 'guanzhou'
export default address // There can be only one export defaultWhen importing:import add from "./ filene.js" // Add is someone else's renaming of addressIf you have too many variables, you can justimport * as info from './ filenames.js'
// The export of other modules will be stored in the info object (named by the object itself), which will be referenced by properties
Copy the code
Introduction to the
// Webpack is a static module bundler for modern javascript application
Webpack is a static module packaging tool for modern JavaScript applications ----- front-end modular packaging toolCompared with Grunt /gulp and Webpack, grunt/ GulP focuses on Task and puts more emphasis on the automation of front-end processes. Modularization is not the core of grunt/ GulP. Webpack puts more emphasis on modularization development and management, while file compression and consolidation, pre-processing and other functions. It comes with a feature folder named SRC source - developed stuff dist (Distribution) - packaged stuff to distribute/////////////////////////////////////////////////////////////////////////
Copy the code
JavaScript
To deal with
You have multiple`.js`File-componentization, they have direct dependencies on each other (calling other component methods/variables) that you don't need to pass through again`script`One by one, you can do it directly`webpack`Packaged in`dist`Folder and when packaging, you only need to specify individual, inter-component dependencies (other components used)`webpack`It'll take care of a piece of packaging and bring it straight to the`dist`The generated file can beeg: Open to file directory,`webpack ./src/main.js ./dist/bundle.js`
// Pack the main.js component into the dist folder named bundle.js
////////////////////////////////////////////////////////////////////////////Now if YOU want to create a file with a webpack to implement the packing function above,`webpack.config.js`Name temporarily fixed code:const path = require('path')
module.exports = {
entry:'./src/main.js'.output: {
path: path.resolve(__dirname,'dist'), // path is a function that concatenates two paths, __dirname (global variable, the path to save the current file) dist (put in 'dist')
filename: 'bundle.js'},} the path-- dynamic path, need to be in this file, terminal input:`npm init` Package. json is generated. In this file, license attributes are required only for open source
`npm install` / / generated package - lock. Json
/////////////////////////////////////////////////////////////////////////But if I want to just pass'NPM run name'To run it? Install the local webpack:` NPM install [email protected] `-- Webpack is used to package files and send them to the server. Webpack is useless after packaging.` NPM install [email protected] - save - dev `
// "devDependencies": {"webpack": '^3.6.0'}
// devDependencies: Develop dependenciesAs long as it is in the terminal inside the command webpack, using the global webpack so need in`package.json` / 'node_modules' library rootIn the`scripts`To configure the script, add webpack and custom name (similar to setting shortcuts) and pass'NPM run custom name'To package, so that the local will be used first`webpack`Version (script in package.json will find the corresponding command location in a certain order when executing, first, find the corresponding command in the local node_modules/bin path, if there is no global)/////////////////////////////////////////////////////////////////////////
Copy the code
CSS
andless
To deal with
Directly to the CSS file in main.jsrequireNPM run install --save-dev CSS-loader/ / "CSS - loader", "^ 2.0.2", "style - loader" : "^ 0.23.1", "webpack" : "^ 3.6.0"
const path = require('path')
module.exports = {
entry:'./src/main.js'.output: {
path: path.resolve(__dirname,'dist'),
filename: 'bundle.js'
},
module: {
rules: [{test: /\.css$/,
use: [ 'style-loader'.'css-loader' ] // Read from right to left when multiple Loaders are used}}}]// css-loader only loads CSS files, not parses them
// CSS-loader is responsible for adding styles to the DOM
// npm install style-loader --save-dev 或者 npm install --save-dev style-loader
// Add an @ and a version number to the end of the component to change the version information
/////////////////////////////////////////////////////////////////////////If you want to pack`.less`NPM install --save-dev less-loader@4.1. 0Less pay attention to the last`less`It's a package that NPM uses to really workmodule: {
rules: [{test: /\.css$/,
use: [ 'style-loader'.'css-loader'] {},test:/\.less$/,
use:[{
loader:"style-loader"}, {loader:"css-loader"}, {loader:"less-loader"}}}]]// The second test can also be written as an array, but if written as an object, details can be added later
// Remember the sequence of the three loaders
Copy the code
Image resource processing
// NPM run serve failed to import image from file through URL in CSS.Install NPM install --save-dev url-loader webpack.config.jsmodule--rules array {test: /\.(png|jpg|gif|jpeg)$/,
use:[{
loader:"url-loader".options: {// options remember to add s
limit: 16000}}}]// After packaging, the image size smaller than limit will be converted to base64 format,
// Request a string of base64 from the server and place it in the URL
// If the size of the image is 10K, it should be 10240 or larger. If the size of the image is larger than limit, use the file-loader module to load the imageFile-loader NPM install --save-dev file-loader// After running, we will repackage the image in Dist (and rename it to 32-bit hash to prevent duplication). In the future, we will use the image in Dist instead of the one in the folder when we code
// The next question is, how do we use the image path in DIST for THE URL in HTMLIn the webpack.config.js file,module.exports = {
entry:'./src/main.js'.output: {
path: path.resolve(__dirname,'dist'),
filename: 'bundle.js'.publicPath:'dist/' // Add publicPath here. In the future, urls will always be preceded by dist path
},
module: {
rules: [{text:' '.use:[] },
{ text:' '.use: [{loader:""}, {loader:""}, {loader:""}}}]]// Finally, because index. HTML is also distributed in dist, publicPath is not needed, remember to delete
In the end, all images are stored in the dist file. If you put them in the img/name file, you can know the name of the image. ----> img/name.hash:8.ext (:8 means cut eight bits, ext: extension)Solution: webpack.config.js configuration codemodule--rules array {test: /\.(png|jpg|gif|jpeg)$/,
use:[{
loader:"url-loader".options: {// options remember to add s
limit: 16000.name:"img/[name].[hash:8].[ext]"}}}]Copy the code
Turn ES6 ES5
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
// Babel-loader is similar to "less" when less is installedWebpack.config.js configuration code {test:/\.js$/.// exclude
// Local environment install Webpack generated folder. Js files do not need to convert
exclude: /(node_modules|bower_components)/,
use:{
loader:'babel-loader'.options: {//presets:['@babel/preset-env']
presets: ['es2015']}}}Copy the code
Configure the Vue
NPM install vue --save instead of loading vue.js as a file// no -dev because it is also dependent at runtime, not just at development time
// export default Vue in node_modulesWhen you want to use it later, you pass it in your.js fileimport Vue from 'vue'Here,'vue'There is no path because it goes directly to node_modules// But add #app to div to display {{message}}, that simple Amway,
// The run-time only version is still incorrectly used after NPM run serveTemplates are not allowed in runtime-only code, because compiler can be used to compile template solutions: Declare configuration code using the Run-time Compiler version webpack.config.jsmodule.exports ={
entry:'./src/main.js'.output: {},module{},
resolve: {/ / alias: alias
Git c: git c: git c: git c:
alias: {'vue$':'vue/dist/vue.esm.js'
Imp ort Vue from 'Vue' imp ort Vue from 'Vue
// go to node_modules and find vue, dist, vue. Esm.js
// Vue. Esm.js contains compiler
// The default is to use vue.runtime.js in the same path}}},Copy the code
supplement
SPA (Simple Page Web Application) Single page Web Application --> Multiple pages via VUe-Router// If we want to display data in data, we have to change the HTML code, but we don't want to change the HTML too often
// So: we need to use el and template
// Define the template attribute in Vue. The HTML tag in template will be replaced by the div mounted by el
// But we are further apartThere is only one div id= in HTML'app'In the main.js fileimport Vue from 'vue'
const App={
template:`
<div @click="btnClick">{{message}}</div>
`.data(){
return {
message:'!!!!!! ',}},methods: {btnClick(){
console.log('1'); }}}new Vue({
el:"#app".template:'<App/>'.components:{
App
}
})
// create folder vue under SRC, create file app.js under vue
export default{
template:`
<div @click="btnClick">{{message}}</div>
`.data(){
return {
message:'!!!!!! ',}},methods: {btnClick(){
console.log('1'); }}} after the original main.js file, directlyimport App from './vue/app'You can reference the code above// The data, methods, and contents of the component are separated, but the template is not separated.Created in a vue file, the app.vue file moves blocks of data from the app.js file to the app.vue file, which is not used after the app.js file <template><div @click="btnClick" class="title">{{message}}</div>
</template>
<script>
export default {
name:'App'.data(){
return {
message:'!!!!!! ',}},methods: {btnClick(){
console.log('1'); }}}</script>
<style>
.title {
color:green;
}
</style>
/ / the main js
import App from './vue/app.vue'
// Now that a new file has been introduced -- the vue file -- we need to install the configurationNPM install vue-loader vue-template-compiler --save-dev NPM run serve error after installation, because vue-loader14.For later versions, you need to install the plugin here for webpack.config.js13Then NPM install// The component calls the component, adding it to the script tag in a component's.vue file
importThe name of the label used by the componentfrom './ component name '(./ generally under the same document)// Then register the components in export default, remember components, with s and s
// Remember the component name/filename, uppercase the first letter
// Test the.vue file
export defaultThe name in the template file can be omitted, and the reference to the component tag in the template file can be either//eg:
Copy the code
The plugin – plug-in
// Plug-in: extends an existing schema
loader: converter/loader, mainly used to convert certain types of modulesplugin: extender, extension to WebPack itself - package optimization, file compression// First: add the copyright PluginWebpack. Config. Js fileconst webpack = require('webpack')
module.exports = {
..
plugins: [new webpack.BannerPlugin('xxxxxx')} repackage and add XXXX information to the bundle.js header in dist folder// Package the HTML PluginAutomatically generate index.html files - You can specify the template to automatically insert the packaged.js files into the body with the script tag// NPM install html-webpack-plugin --save-devThen webpack. Config. Jsconst HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:'./src/main.js'.output: {},plugins: [new webpack.BannerPlugin('Final copyright belongs to Kuoc'),
new HtmlWebpackPlugin({
template:'index.html'})],... }// npm run serve
// Uglify - uglify- uglify- uglify- uglify- uglify
// NPM install [email protected] --save-devThen webpack. Config. Jsconst UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry:'./src/main.js'.output: {},plugins: [new webpack.BannerPlugin('Final copyright belongs to Kuoc'),
new HtmlWebpackPlugin({
template:'index.html'
}),
new UglifyjsWebpackPlugin()
],
...
}
// npm run serve
Copy the code
Setting up a local Server
NPM run serve does not need to generate distribution file dist(placed on disk) every time you change the code will automatically refresh ---- update the code in memory// npm install --save-dev [email protected]Then webpack. Config. Jsmodule.exports = {
entry:'./src/main.js'.output: {},plugins: [new webpack.BannerPlugin('Final copyright belongs to Kuoc'),
new HtmlWebpackPlugin({
template:'index.html'
}),
new UglifyjsWebpackPlugin()
],
devServer: {contentBase:'./dist'.inline: true // Whether to listen in real time
//port Indicates the port number. The default value is 8080}... }// Webpack-dev-server will give an error because this is equivalent to a global command line lookup, but the plug-in is installed locallySo: Law 1:// .\node_modules\.bin\webpack-dev-serverMethod 2: Package. json file,script object with properties,"dev":"webpack-dev-server --open"Then NPM run dev// add --open to automatically open web pagesFinally, Ctrl + C, Y pushes out the current operation, but the server is still set up. DevServer is required at development time, but not at release time, so we can make a separationCopy the code
Webpack configuration separation
There are some plugins that you need during development, but don't need after release. The dev.config.js public part of prod.config.js at development time blocks the corresponding code into a file, For example, JS Uglifyjs is set up in prod.config. JS local server and devServer is set up in dev.config.js// This is a splice
// npm install [email protected] --save-devDev. Config. Js file// Development-time dependencies
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig,{
devServer: {contentBase:'./dist'.inline:true // Whether to listen in real time
//port Indicates the port number. The default value is 8080}}) prod.config.js file// Dependencies at release time
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig,{
plugins: [new UglifyjsWebpackPlugin()
]
})
// the webpack.config.js file can be removed and placed in package.jsonIn scripts, modify serve and add dev"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"."serve": "webpack --config ./config/prod.config.js"./ / release
"dev": "webpack-dev-server --open --config ./config/dev.config.js" / / development
},
// Then NPM run serve, pack the dist folder under the config folder,
// Instead of under the entire project folderSolution: base.config.js filemodule.exports = {
entry:'./src/main.js'.output: {
path: path.resolve(__dirname,'.. /dist'), Dist = dist; dist = dist; / Skip to the directory one level above, not new
filename: 'bundle.js'.publicPath:'dist/'},... }Copy the code
Vue CLI
Scaffolding --CLI-- command-line-interface Relies on Node and WebpackNPM install -g@vue /cli
// vue --version View the versionThe scaffold2.X template pull// npm install -g @vue/cli-init(My-project - name of the project- choose your own)// CLI-- 2.x initializing project: vue init webpack my-project
// CLI-- 3.x initialize project: vue create my-project
Copy the code
Vue CLI2
ESLint ES limits, i.e. js code that fails if it is non-standard -- such as function sun () {} and not ending with a semicolon; There are also functions to be used in the config folder index.jsFile, useEslint: false; Disable e2E -> EndtoEnd to end test build and Config are project configuration, plug-in configuration of the latter, variable definition of the former, and file merge in static files (static resources, images and data of the file are copied to dist file unchanged), package.jsonIn the file, "dev":"webpack-dev-server --inline --progress --config build/webpack.dev.conf.js"."start": "npm run dev"They are the same"lint": "eslint --ext .js,.vue src"To limit"build": "node build/build.js"Package project // supplement: node (c++ development, Google open source: // NodeTest.js can be used to run javascript code. // Nodetest.js can be used to run JAVASCRIPT code. The package-lock.json file is a mapping between node_modules and package.json. -- Version of loader in package.json ^4.0.1Means greater than or equal to4.0.1Version. But we don't know which version is installed on node_modules so we need package-lock.json fileCopy the code
runtimecompiler / runtimeonly
// The difference is in the main.js filePublic sectorimport Vue from 'vue'
import App from './App'
Vue.config.productionTip = falseThe difference between partruntimecompiler:
new Vue({
el:"#app".template: '<App/>'.components: {App}}) runtimeOnly:new Vue({
el:'#app'.render: h= >h(App)
Render: function(h){return h(App)} */}) interpretation of the difference: first look at the Vue program running process diagramCopy the code
// template---> AST---> render ---> Virtual dom ---> Dom(UI)Runtimeonly directly: Compared with run-time compiler, runtimeonly has higher performance and less code, and the template tag of runtimeonly file is not parsed into AST, so who handles it?// the.vue file is parsed into an object that contains no template information,
// All templates are converted into render functions by vue-template-compilerTherefore, we do not need template to be converted to AST and then runtimeonly directly through the render function via compilerCopy the code
npm run build/dev
Vue CLI3
Different versions
// Vue2.5.21 -> vue2. x -> flow-type type detection (facebook)
// Vue3.x -> TypeScript(microsoft)
// VuE-cli2 is built based on WebPack3
// VuE-CLI3 is built based on WebPack4
Vue-CLI3 -- 0The build and Config directories in the root directory provide vue UI commands that provide visual configuration removalstaticFolder, added the public folder, and moved index.html to publicstatic] - [ˈ st æ ^ t ɪ k)Copy the code
The creation process
Vue create testvuecli3(project name) Please pick a preset:// Preset: Preset [preset]
// Manually [ˈmæ l əli]After player moves: multiple choice - press space to select Enter to submit// vcs --> version control system (git/svn) Git add. Commit git commit -m'comments'Commit to local repository Git push to remote repositoryCopy the code
Project running
npm run build // Finally package the distribution
npm run serve // Run at development time
Copy the code
Vue Router
Front-end/back-end rendering
1. Back end (server) rendering early browser development:htmlCSS has no JS, use JSP (Java Server Page)/PHP, write a web page to the browser, let the browser show no Ajax, the web page has been rendered by JAP technology on the server (html+ CSS + Java, Java dynamically reads data from the database and puts it on the page) The server is the final web page, when sent to the browser, onlyhtmlAnd CSSCopy the code
2.Front end separation stage - Front end rendering -jquery development mode requests data through AjaxCopy the code
3.SPAPage SPA: Simple Page Web Application -- Rich single-page applications are stored in multiple sets on static resource servers in the stage of front-end separationhtml+ CSS +js, and the corresponding URL but only one index on the static resource server.htmlIt does not mean that there is only one site, such as a site that has three pages, but only one in the static resource serverhtmlYou have to rely on the front-end routing technology to separate the code from the page. You click the button and the front-end routing generates the URL. Instead of asking the server for resources, you extract the page code from the entire code by using the judgment of the JS code.Copy the code
The relationship between URLS and components in front-end routing (a page is a large component)
Hash of URL and history of H5
URL: scheme:// host:port/path? Query #fragment How to change the URL but not refresh the page? (F12-network, view resource request to know whether to refresh) method1. location.hash = 'foo'Behind,'foo'Optional method2. history.pushState({},'','foo'), the console returns undefined, and modifs the URL, which can return /back()3. history.replaceState({},'','foo'), cannot return history.go(-1) is equivalent to a history.back(), go(-2), equal to two, can also be a positive history.go(1) is equivalent to a history.forward() method123The three interfaces are equivalent to the forward and backward href of the browser interface: Hyper Reference hyperlinksCopy the code
History. pushState pushes and unpushes history
// redirect
// parameters --paramsThree JS files after packaging// all code for app development -- business code
// Vendor indicates the third-party VUE
// Manifest does the underlying support for packaged code (import,export....)Import and export// commonjs const {a,b,c} = require('./xxx.js')
Import {a,b,c} from './ XXX '$route and $router $route -- whichever component is active gets the $Router -- the object created in app.vueeg:
computed: {
userId(){
return this.$route.params.useId
}
}
Copy the code
Lazy loading
const routes = [
{
path:'/home'.component:() = >import('.. /components/Home')}, {path:'/about'.component:() = >import('.. /components/About')},];// For better management, choose the following way
const Home = () = >import('.. /components/Home')
const About = () = >import('.. /components/About')
const HomeNews = () = >import('.. /components/HomeNews')
const routes = [
{
path:'/home'.component: Home,
children:[
{
path:'news' // do not add/before news
component:HomeNews
},
]
},
{
path:'/about'.component:About
},
];
Copy the code
Profile // Archive ---- my pageIn the index.js file in the Router folder,1.//////////////////////
import VueRouter from 'vue-router'
import Vue from 'vue'
import User from './User.vue' / / routing
//////////////////
2.
Vue.use(VueRouter)
//////////////////
3.
const routes = [
{
path:' '.redirect:'/home'
},
{
path:'/user/:userId'.component:User
}
]
const router = new VueRouter({ VueRouter contains methods like push, replace, and back
routes,
mode:'history'.linkActiveClass:'active'
})
//////////////////
4.
export default router
//////////////////Use (VueRouter), VueRouter. Install, install the plugin. In node_modules, find SRC, util, install. (as well as globally registered RouterViews and RouterLinks)// Vue.prototype.$router = return this._routerRoot._rooter;
// All components inherit from the Vue class prototype!! So that all components have the $router attribute
// defineProperty(obj, attribute name, attribute value) defines attributesThe _router is the router we mounted in the project main.jsimport Vue from 'vue'
import App from 'app'
import router from 'router'
Vue.config.productionTip=false
new Vue({
el:'#app',
router,
render: h= >h(App)
})
////////////////////////////////////////////
而 this.$route represents the active route we configured (newMappings in router objects created by VueRouter)Copy the code
Navigation guard
/ / definition:To listen for the route jump process, perform operations in the listener function/ / introduction:When we click on the navigation bar on the home page, news, information, hopedocument.title can be changed by using the lifecycle function in the component:created(){ document.title='xxx'} However, it is inefficient to change one by one, because every time you click the jump, it is actually the jump of the route. Therefore, we consider whether we can monitor the jump of the route and operate in the jump process/ / methods:Add meta {to the routing object of the Routes arraypath:'/home'.component:Home,
meta: {// meta: metadata -- data that describes data
title:'home'
},
children:[
{
path:'xxx'. }}]// Hook /guard -- Hook: callback
AfterEach (hook) after a jump -- no need to actively call next
router.afterEach((to,from) = >{
})
router.beforeEach((to,from,next) = > {
document.title = to.meta.title
next() // The next hook must be called as soon as possible}) but there is a problem, if it involves route nesting, such as home internal news information also has route jump, then the home title displayundefinedPrint to, you can see that the title of home is not present, improve: router.beforeeach ((to,from,next) = > {
document.title = to.matched[0].meta.title // Then there are no problems
next()
})
// Both of the above are global guard and route exclusive guard, component inside guardA front hook that determines whether the user is logged in. If so, execute next or next(false)
Copy the code
Save route Status
/ / introduction:Home class has Profile, sublevel (nested routine by havenewAnd message) Home by defaultnewThe user clicks Message at Home, then goes to Profile, and when they come back Home, it's changed tonewEach jump to a route is an old destruction and a new creation, which can be done through the lifecycle function:destoryed(){} detection// After destoryed is destroyedRouter-view is also a component. If the router-view is directly wrapped in keep-alive, all view components matched by the path will be cached// Solution<keep-alive> directly in app.vue<route-view/></keep-alive> Keep-alive ensures that the component will not be destroyed in the home.vue component, there isnewAnd message, corresponding to the news and information on the home pagedata(){
return {
message:'hello'.path:'/home/news'}}activated(){
this.$router.push(this.path);
}
beforeRouteLeave(to,from,next){
this.path = this.$route.path
next()
}
/ * why can't use activated and deactivated deactivated () {. This path = this. $route. The path; } $route points to an active route, that is, the deactivated callback is called when the route is activated. $route points to an active route that is activated when the route is activated. This.$route is already user. BeforeRouteLeave indicates that the callback activated and deactivated functions are valid only if the router-view uses a keep-alive package */
// import ':The router-view is wrapped with keep-alive, which means that the keep-alive buffer is not destroyed for all the routing components. In other words, the creation callback of the lifecycle function of each route is only once. But what if a single route is artificially set multiple times? <keep-alive exclude=Component name (the name attribute in export Default in the.vue file)>....</keep-alive>
// exclude and include.
Copy the code
TabBar case
First of all, TabBar.vueto1This component implements a dynamic internal slot layout (flex) style in TabBarItem.vueSlot V-if V-else in the file there is no problem that slot here will eventually be applied.vue<slot :class= <slot :class= <slot :class= <slot :class= <slot :class="{active: isActive}" name="item-text"></slot> is replaced directly by the slot content in app. vue without a dynamic class solution: <div :class="{active: isActive}">
<slot name="item-text"></slot> </div> To be on the safe side, all slots that have V-if /else, dynamic classes, etc., will be wrapped around a div, and the related operations will be added to the divCopy the code
In this case, SVG images will be used. If you do not pay attention to the file path during the extraction process, it is very easy to make mistakes, and it is difficult to change, so you can choose to alias the file, in the project file build webpack.base.conf.jsResolve :{The '@':resolve('src'Import TabBar from import TabBar from import TabBar from import TabBar from import TabBar from import TabBar from'@/components/tabbar/TabBar'For convenience,eg: CLI2
alias: {
'@': resolve('src'),
'assets':resolve('src/assets'SRC = @src'@/assets'---CLI3
'components': resolve('src/components'),
'views': resolve('src/views'} after this configuration, re-npm run dev note: the alias method can only be used directly on import from, if used on img SRC. Need: SRC ="~assets/img/tabbar/home.svg", preceded by the symbol ~Copy the code
Promise
PromiseIs a feature of Es6 and a solution to asynchronous programming// What is synchronization? When we write code, we execute it line by line, it's a kind of synchronization.
// In the same way, if we make a network request, then we cannot respond to the user's action and must wait until the requested resource/response is receivedCan respond to user operations.// Therefore, we need to process network requests asynchronously, i.e. make network requests while responding to user operations.After that, the response to the user operation continues, and the network request-data request is successful, and the data is called back out through the function passed inCopy the code
The callback hell
But if the network request is complex, callback hell can occurCopy the code
// executor executes.exeVue-day8, class code// sync Synchronization
// async asynchronization
// This is a big pity
// Pending
Copy the code
Promise.all
Introduce, if you have two asynchronous requests, use Ajax to receive them, but you don't know which one comes first, and you can only do something if both requests come first. Don't have toPromiseWith.all, you can define only two Boolean variables that are received in the handler function handleResult()true&&true
/ / case
new Promise, the parameter is a functionPromise.all() is an array containing iterable (traversable) objectsPromise.all([
new Promise((resolve,reject) = > {
$ajax({
url:'url1'.success: function(data) {
resolve(data)
}
})
}),
new Promise((resolve,reject) = > {
$ajax({
url:'url2'.success: function(data) {
resolve(data)
}
})
})
]).then(results= > { // The results of both requests are stored in the Results array
// Execute when both data are received
results[0]******
results[1] * * * * * *})Copy the code
Vuex
Vuex component state management (staff) that is, between multiple components, their state (now understood as: variables, state variables are commonly used to store) hope that can be Shared according to the component tree, bottom to top, interlayer is too much, the request of trouble Can create an object, as an intermediary state of centralized management - vuex is responsive// Responsiveness is key. When a variable in an object changes, the component to which that variable is applied is refreshed accordinglyIf it is not reactive, then there are other implementation methods, such as:const ShareObj = {
name:'why'} vue.prototype. ShareObj = ShareObj then Vue instance components and components registered in them can passthis. ShareObj. Name to access// But there is no response, you change the name, the corresponding component variable does not change accordinglyManaged states: Token certificates, user information, login status, geolocation items, shopping cart, etcCopy the code
The most basic use
// npm install vuex --saveSimilar to router, firstimport Vue from 'vue'
import Vuex from 'vuex'Then vue.use (Vuex) to prevent main.js from getting too big, put it in another folder and create a folder, not named Vuex, but Store/ / store warehouseCreate index.js in the Store folderimport Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// Create an object, which is a little different here
const store = new Vuex.Store({
state: {
// Save the state
counter:1000 // Other. Vue component template tag can be referenced by $store.state.counter (reactive)
},
mutations: {
/ / method
increment(state){ // State defaults directly to the state object above, without adding this
state.counter++
},
decrement(state){
state.counter--
}
},
actions: {},getters: {},modules: {}})// Export the store object
export default store
// Finally mount it in main.js
import store from './store'
new Vue({
el:'#app',
store, Prototype.$store = store global property, similar to router
methods: {
// <button @click="addition">++</button>
// <button @click="subtraction">--</button>
addition() {
this.$store.commit('increment')},subtraction() {
this.$store.commit('decrement')}},// If the function takes count
subtraction(count){
this.$store.commit('decrement',count)
}
// mutation
decrement(state,count){
state.counter -= count
}
< button@click =" Decrement (5)" >-5
})
Copy the code
Devtools can keep track of the State each time because it is in the order shown above, so if <div>{{$store.state.counter}} < /div>
<button @click="$store.state.counter++"> =" Vue Components "=" Vue Components" =" Vue Components "=" Vue Components" =" Vue Components "=" Vue Components" Mutations must be passed, otherwise you will not be able to show the change of state in devTools when debugging, but you are allowed to skip Action and directly change the function of Vue Components to Mutation Action: After modification, if you have an asynchronous operation, you must go to the Action first (Devtools can only track synchronous operations). For asynchronous operations, you usually send network requests, so connect to the Backend API.backend: back-end, frontend: frontend)Copy the code
Core concepts
getters
State single State tree: English name Sing Source of Truth---- single data Source Getters: calculation properties similar to a single component (when a certain data needs to be displayed on the page after a series of changes) State: {counter:1000}
getters: {
powerCounter(state){return state.counter * state.counter}, // You don't need to write the corresponding methods in each component, just $store.getters.powerCounterCan} <h2>{{$store.getters.powerCounter}} added:1Functions in.getters can also call functions in getters, for example: powerCounter2(state,getters){return getters.powerCounter.length} The second argument to all functions, no matter what the name is, is getters2If you want someone else to pass data in the template tag, and there are no new arguments in the getters to hold the data, return a function. moreAgeStu(state){ return age => { return state.students.filter(s => s.age>age)
}
}
<h2>{{$store.getters.moreAgeStu(8)}} < /h2>
Copy the code
mutations
Mutation: When updating the Vuex store status, we may want to carry some additional parameters (the Payload of the Mutation). In app.vue, methods (first method) are introducedaddCount(count){
this.$store.commit('incrementCount'$store $store $store $store $store $store $store $store.commit({
type:'incrementCount', count,})} If count is a number5In the first case, the Number is passed5But on the second, count exists anyway as an attribute of a parameter, payload, an object, as follows :{incrementCount(state,payload) {state.counter += paypay. count}.jsPut the function eg: export const INCREMENT = inside the file'increment'Import {INCREMENT} from index.js in the store folderfromMutations: {[INCREMENT](state){counter. counter++},.vueImport {INCREMENT}from'./store/mutations-types' If you add setTimeout(()=>{state to the mutations function updateInfo.info.name='xxxx'
},1000The state data will change, but when you're debugging, because you're doing it asynchronously, not synchronously even though you're showing modified data on the page, the debugger is showing unmodified values so you need actionsCopy the code
actions
Action actions: {internal functions also have default parameters, getters and mutations have default state, and actions have default parameters context ----, We can temporarily think of context as a store object (const store=new Vuex).Store({... Mutations: {})} now solve that asynchronous problemupdateInfo(state) {
state.info.name = "xxx"
}
},
actions: {
For_UpdateInfo(context) {
setTimeout(() => {
context.commit('updateInfo')},1000)
}
},
App.vueIn the methods: {updateInfo() {
this.$store.dispatch('For_UpdateInfo'}} Actions you can use in App. Vue for this.$store.dispatch('For_UpdateInfo'.'aaa'If the For_UpdateInfo function returns a Promise object, eg: in store index.js:For_UpdateInfo(context,payload) {
return new Promise((resolve,reject) => {
setTimeout(() => {
context.commit('updateInfo');
console.log(payload); // aaa
resolve(111)},1000Return new Promise((resolve,reject) => {.....resolve(111)... }) returns to App.vueIn the enclosing $store.dispatch('For_UpdateInfo', 'aaa') and replace the original code then you can as well in App.vueFile: this.$store.dispatch(' For_UpdateInfo ', 'aaa').then( res => {
console.log(res); // 111}) and the worse way is in App.vueIn the file, updateInfo(){this.$store.dispatch('For_UpdateInfo',{the second argument is passed to an object message:'aaaa',
success: () => {
console.log('xxxx')}}}Copy the code
modules
Module When a store becomes bloated, it can be divided into Module modules, each Module has its own state, mutations, actions... eg: const moduleA = { state: {.... }, mutations:{... },... } const store = new Vuex.Store({ state: {.... }, modules: {a: moduleA,}}) but essentially,aMutations are defined in template: {{$store.state.a}} modules, which is available on App.vueMethods in modules can have a third parameter, rootState, which accesses the largest, non-modules state, parameter of the actions: method in modules, context is not the largest store, Context.com, MIT will only submit its own mutationsCopy the code
Responsive complement
To be responsive, your variables must be declared in state before they can be added to a responsive system, not dynamically (added to state but not reactive).// non-responsive
this.letter[0] ='aaa'
delete state.info.age
/ / response type
this.letter.splice(0.1.'aaa')
Vue.set(this.letter, 0.'aaa'This method can also be applied to the Vue. Delete (state.info,'age')
Copy the code
Pull away
// First, the syntax is added
const obj = {
name:'xxx'.age:18.height:1.8.address:'china'
}
// Destruct,obj object I only take two attributes
const {name,height} = obj;
// Array destruct
const names = ['why'.'kobe'.'james']
const [name1,name2,name3] = names;
Copy the code
Axios network module encapsulation
Ajax IO System test site: httpbin.org Project server:123.207.32.32:8000Interface: http://123.207.32.32:8000/home/multidata
http://123.207.32.32:8000/home/data? type=sell&page=3
status:200NPM install axios --save main.js import axios from'... '
axios({
url:'http://123.207.32.32:8000/home/multidata'// get method by default:'get'// get/put}).then(res => {// Because a Promise object is returned directly, so.then
console.log(res);
})
axios({
url:'http://123.207.32.32:8000/home/data'Params :{// Parameter concatenation type for get requests:'sell',
page: 3} // equivalent to url:'http://123.207.32.32:8000/home/data? type=sell&page=3'
}).then(res => {
console.log(res); }) also works: axios.get(...). Results: the console.log(res) This res is an Object. The data returned by the server is contained in the data and the other properties are generated by the Axios framework. All can merge multiple network requests.all([axios({
url: 'http://123.207.32.32:8000/home/data'
}),axios({
url:'http://123.207.32.32:8000/home/data'
params: {
type:'sell',
page:5}})]) // axios returns an array and can be used with axios.spreadan.then(axios.spread((res1,res2) => {
console.log(res1);
console.log(res2);
}))
Copy the code
Global configuration
main.js// Remember: default + s axios.defaults.baseURL = '....'
axios.defaults.timeout = 5000// milliseconds, timeout axios.defaults.headers.post['Content-Type'] ='application/x-www-form- urlencoded 'and so onCopy the code
To improve the
When there are too many services, the global configuration is not applicable// Create the corresponding instance of Axios
const instance1 = axios.create({
baseURL: 'http://123.207.32.32:8000'.timeout:5000
})
// Use instance instance1 to set the same baseURL for several outgoing network requests
instance1({
url: '/home/multidata'
}).then(res= > {
console.log(res);
})
instance1({
url:'/home/data'.params: {type:'pop'.page: 1
}
}).then(res= > {
console.log(res);
})
Onst instance2 = axios.create({baseURL:'http://222....... '})Or in every.vue component,import axios from 'axios'And then using the lifecycle hooks,created(){ axios({ulr:'http:..... '}).then(res= >{this.data =res})} get the request data, but it's not good, it's too dependent on third-party frameworks, but any project that uses a third-party framework, absolutely, you have to have the idea of wrapping everything that's involved in the network layer in the SRC file in the network folder and axios says, Network request.js to export multiple instancesexport defaultbutexport function request(){}export function instance(){}...// request.js
import axios from 'axios'
export function request(config) {
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000'
timeout: 5000
})
// Send a real network request
instance(config).then( res= > {
// The results should be passed around, not handled here
}).catch( err= > {
// Here too, try to call back out})}// Call the result back out
///////////////////////////////////////////////////////////
1.
// The parameters success and failure are passed in as functions
export function request(config, success, failure){
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000'
timeout: 5000
})
instance(config).then(res= > {
success(res) // Pass the received data res as an argument to the function success passed in main.js
})
.catch(err= > {
failure(err)
})
}
// main.js
import {request} from './network/request';
request({
url:'/home/multidata'
}, res= > { // This is equivalent to passing success an anonymous function with the argument res
console.log(res);
}, err= > {
console.log(err);
})
///////////////////////////////////////////////////////////
2.
// request.js
export function request(config) {
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000'
timeout: 5000
})
instance(config.baseConfig)
.then( res= > {
config.success(res);
}).catch( err= >{ config.failure(err); })}// main.js
import {request} from './network/request';
request({
baseConfig: {},success: function(res) {},failure: function(err) {}})/////////////////////////////////////////////////////////////////////
// The third option, the final option
// request.js
export function request(config) {
return new Promise((resolve,reject) = > {
const instance = axios.create({
baseURL:'http://123.207.32.32:8000'.timeout: 5000
})
instance(config)
.then(res= > {
resolve(res)
}).catch(err= > {
reject(err)
})
})
}
// Or --> better this one
export function request(config) {
// 1. Create an axios instance
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000'.timeout: 5000
})
// 3. Send a real network request
return instance(config) // Instance (config) itself returns a promise
}
// main.js
import {request} from './network/request';
request({
url:'/home/multidata'
}).then(res= > {
console.log(res);
}).catch(err= > {
console.log(err);
})
Copy the code
intercept
// request.jsThere are four interceptions: request success/failure, response success/failure// Request interception
export function request(config) {
// 1. Create an axios instance
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000'.timeout: 5000
})
// 2. Axios interceptor
// use two parameters, one representing request/response success and the other representing.. failure
axios.interceptors.request.use(); / / global
instance.interceptors.request.use(config= > {
console.log(config);
return config // If there is no return, the data is intercepted, and your main.js operation will report an error
},err= > {
console.log(err);
}); // Only for instance requests
The first parameter of use is config and the second parameter is err
instance.interceptors.response.use(); // Only the instance response is given
// Request interception applies in several cases:
1.Some information in config does not meet the requirements of the server and needs to be modified2.A request icon displayed on the interface each time a network request is sent3.Some network requests, such as login tokens, must carry special information// 3. Send a real network request
return instance(config) // Instance (config) itself returns a promise
}
// Response interception
export function request(config) {
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000'.timeout: 5000
})
instance.interceptors.response.use(res= > {
console.log(res); // Use res.data
return res.data
},err= > {
console.log(err);
});
return instance(config)
}
Copy the code