VUE学习笔记详细

x33g5p2x  于2022-07-20 转载在 其他  
字(61.4k)|赞(0)|评价(0)|浏览(453)

VUE学习笔记

本文章以vue3来记录的,但并非记录vue3所有变化!

1、ES6语法

1.1、let变量声明

  • let用于声明变量
  • 有局部作用域
  • let声明的变量不会提升(只能先定义后使用)

1.2、const变量声明

  • const用于声明常量
  • const声明的常量也不会提升(只能先定义后使用)
  • const声明对象时,该对象不可以更换,但是对象里的内容可以更改

1.3、箭头函数

function myfunction(x){
	return x*x
}
console.log(myfunction(3))

const myFunc =(x)=>{return x * x}
console.log(myFunc(3))

const myFunc1 =x=>x*x
console.log(myFunc(3))
  • 理解为一般函数去掉function关键字再在参数和函数语句块中间加上=>
  • 如果只有一个参数,可以去掉括号(注意没有参数时也要加上()占位)
  • 如果只有一条返回语句,可以再去掉return和{ }
  • 箭头函数在返回对象时必须在对象外层多加一个()
  • this 与普通函数的this不同, 普通函数谁调用这个函数,this就是指向谁 箭头函数没有自己的this,它的this继承于父级, 也就是箭头函数的this指向箭头函数所处对象

1.4、数组新增的高级方法

  • filter()
// 接受一个函数,函数有一个参数,此参数代表循环这个数组时的每个元素
let myArray=[1,2,3,4,5,6,7,8,9];

let array1 = myArray.filter(function(n){
	return n>5;
})
console.log(array1) // 6,7,8,9
  • map()
// 接受一个函数,同样的也有一个参数,相当于对数组元素每个都应用这个函数的规则
let array2 = array1.map(function(n){
    return 2*n;
})
console.log(array1)
  • reduce()
// 接受两个参数,
// 第一个参数为函数,函数有两个参数(s,n),第一个参数代表起始值,第二个参数代表循环数组的每个元素
// 第二个参数指定第一个函数参数的第一个参数的起始值s
// s指上一次的返回值
// n每次代表这次循环的数组的值
let sum = 0;
sum = array2.reduce(function(s,n){
    return s+n;
},0)

console.log(sum)

1.5、字符串新增方法

  • String.startswith(string) 判断String是否以string开头 返回true或false
  • String.endswith(string) 判断String是否以string结尾

1.6、模板字符串

let name = 'zhangsan';
let age = 10;

// 下面两个都得到: zhangsan is 10 years old
let normalStr = name+ ' is ' + age + ' years old';
let templateStr = `${name} is ${age} years old`

1.7、解构

  • 数组
let arr = [1,2,3];

// 如果要把这个数组的三个值分别给三个变量:
{
    let a = arr[0];
    let b = arr[1];
    let c = arr[2];
}

// 新增简单方法:
{
    let [a, b, c] = [1, 2 ,3];
}
// 或写成:
{
    let [a, b, c] = arr;
}
  • 对象
let person = {
    name:'zhangsan',
    age:10,
    gender:'male'
}
{
    let {name, age, gender} = person;
    console.log(name, age, gender)
    // 输出 zhangsan 10 male
}
// 别名
{
    let {name:Name, age:Age, gender:Gender} = person;
    console.log(Name, Age, Gender)
    // 输出 zhangsan 10 male
}
  • 复合赋值
let arr = [{name:'zhangsan', age:10}, [1,2,3], 'hello', 9 ];
{
    let [a,b,c,d] = arr;
    console.log(a);
    console.log(b,c,d);
}
  • 分解赋值
let arr = [{name:'zhangsan', age:10}, [1,2,3], 'hello', 9 ];
{
    let[{name,age},[a,b,c],d,e] = arr;
    console.log(name,age);  // zhangsan 10
    console.log(a,b,c);     // 1 2 3 
    console.log(d,e);       // hello 9

}

1.8、三点拓展运算符

let array1 = [1,2,3];
let array2 = [7,8,9];
let myArray = [...array1, 4, 5, 6, ...array2] ;
console.log(myArray)    // 1, 2, 3, 4, 5, 6, 7, 8, 9
function myFunction(a, b, c) {
    console.log(a,b,c);     
    return a+b+c;
}
let arr = [1,2,3];
console.log(myFunction(...arr));    
// 1 2 3 
// 6
function myFunction(...arr) {    for(let i = 0; i <arr.length; i++)    {        console.log(arr[i]);    }    console.log(arr);}myFunction(3,12,45,123);// 3// 12// 45// 123// 3 12 45 123// 由此可见,猜测正确
1
function myFunction(a,b, ...arr){
    console.log(arr);
}
myFunction(1,2,3,4,5,6,7);  // 3 4 5 6 7
// 1 2 被赋值给了a, b, 剩下的生成了数组arr

1.9、模块化编程

1.9.1、module的引入

编写html文件时,通常会引入许多js文件,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./1.js"></script>
    <script src="./2.js"></script>
</head>
<body>
    
</body>
</html>

当这些js文件中有重复命名时,便会报错 如1.js和2.js都定义一个变量name

// 1.js
let name = 'zhangsan';
// 2.js
let name = 'lisi';

那么在最开始那样引入三个js文件会导致变量名冲突,报错如下: Uncaught SyntaxError: Identifier 'name' has already been declared 因为这样引入js会导致浏览器不知道解析那个name变量

可以给script标签的type属性赋值为module来解决这个问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./1.js" type='module'></script>
    <script src="./2.js" type='module'></script>
    <script src="./3.js" type='module'></script> 
</head>
<body>
    
</body>
</html>
1.9.2、访问不同js文件下相同的变量
// 1.js

let name = 'zhangsan';
function add(a, b){return a+b}

export {name, add};  // 注意这里是json的简化写法,相当于 export {name:name};
// 3.js

import {name, add} from './1.js';   
// 注意这里使用了解构赋值,相当于:
// let {name, add} = {name:name, add:add} (这个对象来自./1.js文件的export)

// 接下来我们便可以直接使用name与add
console.log(name);  // zhangsan
console.log(add(3, 9)); // 1
1.9.3、解决引入后的命名冲突

当从其他文件引入变量后,也可能出现命名重复

// 3.js
import {name} from './1.js';
import {name} from './2.js';

可以采用取别名的方法来解决这个问题

// 3.js
import {name as name1} from './1.js';
import {name as name2} from './2.js';
// 接下来使用name1或者name2即可

同样的你也可以在1.js或者2.js暴露属性时取别名

// 1.js

let name = 'zhangsan';

export {name as name1};
// 2.js

let name = 'lisi';

export {name as name2};
// 3.js
import {name1} from './1.js';
import {name2} from './2.js';

console.log(name1, name2);  // zhangsan lisi
1.9.4、定义属性时暴露
// 1.js
export let name = 'zhangsan';
1.9.5、缺少名字的暴露属性

每个js文件只能定义这样的一个export default,

如果出现两个及以上, 那么会报错Uncaught SyntaxError: Identifier '.default' has already been declared

// 1.js
export default function(a){
    console.log(a)
}

接收时名字不需要{}

// 3.js
import printa from './1.js'
// 这里的printa是自己定义的
1.9.6、接收暴露的所有属性
export * as name from 'url';   // 创建一个对象接收暴露的所有属性
// name.attr;

1.10、Promise

是异步编程的一种解决方案

从语法上说,Promise 是一个对象,从它可以获取异步操作的消息

以前的回调

setTimeout(()=>{
    console.log(111)
    setTimeout(()=>{
        console.log(222)
        setTimeout(()=>{
            console.log(333)
        },1000)
    },1000)
},1000)

es6的回调

new Promise((resolve, reject) => {
    console.log(111)
    resolve(222)
    // reject(333)
}).then(res => {
    console.log(res)
    return 444
}).catch(err => {
    console.log(err)
}).then(res => {
    console.log(res)
    return new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve(555)
        },1000)
    })
}).then(res => {
    console.log(res)
})

2、nodejs

node.js

2.1、npm

npm会跟随nodejs一起安装

  • npm -v:查看版本
  • npm install :安装模块
  • npm install -g:全局安装模块
  • npm uninstall :卸载模块

2.2、Package.json

  • name:包名

  • version:包的版本号

  • “5.0.3”表指定版本号

  • “~5.0.3”表安装5.0.x的最新版本

  • “^5.0.3”表安装5.x.x的最新版本

  • description:包的描述

  • homepage:包的官网url

  • author:作者

  • contributors:包的其他贡献者

  • dependencies:依赖包列表

  • repository:包代码存放位置

  • main:程序入口文件

  • keywords:关键词

3、webpack

npm install webpack -g

3.1、快速入门

  • 创建文件夹
  • npm init -y
  • npm i -D webpack webpack-cli
  • webpack.config.js
const path = require('path')

module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    }
}
  • index.js
console.log('Interesting!')
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript" src="../dist/bundle.js" charset="utf-8"></script>
</body>
</html>
  • package.json
{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.60.0",
    "webpack-cli": "^4.9.1"
  }
}
  • 编译
npm run dev

3.2、多入口和多出口

const path = require('path')

module.exports = {
    // 单chuank
    // entry: ["./src/index1.js",./src/index2.js]
    
    // 多chuank,key为chuank名
    entry: {
        entry1: path.resolve(__dirname, './src/index1.js'),
        entry2: path.resolve(__dirname, './src/index2.js')
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: '[name].js',
    }
}

3.3、webpack打包html

npm i html-webpack-plugin -D

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        })
    ]
}

webpack.config.js——多个html

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "index.html",
            chunks: ["index","common"],
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        }),
        new htmlWebpackPlugin({
            template: "./src/cart.html",
            filename: "cart.html",
            chunks: ["cart","common"],
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        })
    ]
}

3.4、webpack打包css

  • css-loader:处理@import和url
  • style-loader:把样式插到Dom中
npm i css-loader style-loader -D

index.js

require('./index.css')
console.log('Interesting!')

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        })
    ]
}

3.5、webpack打包less

npm install less less-loader -D

less.less

h1{
  &:hover{
    color: blue;
  }
}

index.js

require('./index.css')
require('./less.less')
console.log('Interesting!')

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader']
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        })
    ]
}

3.6、webpack打包sass

npm install sass-loader node-sass -D

sass.scss

p{
  text-indent: 2em;
}

index.js

require('./index.css')
require('./less.less')
require('./sass.scss')
console.log('Interesting!')

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader']
            },
            {
                test: /\.scss$/,
                use: ['style-loader','css-loader','sass-loader']
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        })
    ]
}

3.7、提取css为单独的文件

npm i mini-css-extract-plugin -D

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
let miniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [miniCssExtractPlugin.loader,'css-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader']
            },
            {
                test: /\.scss$/,
                use: ['style-loader','css-loader','sass-loader']
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        }),
        new miniCssExtractPlugin()
    ]
}

3.8、css兼容性处理

npm i postcss-loader postcss-preset-env -D

index.css

h1{
    color: aqua;
    transform:rotate(-30deg);
}

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
let miniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [miniCssExtractPlugin.loader,'css-loader','postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader']
            },
            {
                test: /\.scss$/,
                use: ['style-loader','css-loader','sass-loader']
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        }),
        new miniCssExtractPlugin()
    ]
}

postcss.config.js

module.exports = {
    plugins: [
        require('postcss-preset-env')()
    ]
}

package.json

"browserslist": [
  ">0.8%",
  "last 2 version"
]

3.9、css压缩

npm i optimize-css-assets-webpack-plugin -D

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
const miniCssExtractPlugin = require("mini-css-extract-plugin");
const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [miniCssExtractPlugin.loader,'css-loader','postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader']
            },
            {
                test: /\.scss$/,
                use: ['style-loader','css-loader','sass-loader']
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        }),
        new miniCssExtractPlugin(),
        new optimizeCssAssetsWebpackPlugin()
    ]
}

3.10、图片、字体资源打包

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
const miniCssExtractPlugin = require("mini-css-extract-plugin");
const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [miniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /\.scss$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(png|jpg|gif)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 8192
                    }
                },
                generator: {
                    filename: 'images/[hash][ext][query]'
                }
            },
            {
                test:/\.(eot|svg|ttf|woff|woff2)/,
                type: 'asset',
                generator: {
                    filename: 'fonts/[hash][ext][query]'
                }
            },
            // 如果html里引入了图片资源要使用html-withimg-loader插件处理
            {
                test: /\.html$/,
                use: [
                    'html-withimg-loader'
                ],
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "demo.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        }),
        new miniCssExtractPlugin(),
        new optimizeCssAssetsWebpackPlugin()
    ]
}

3.11、热部署devServer

npm i webpack-dev-server -D

webpack.config.js

const path = require('path')
const htmlWebpackPlugin = require("html-webpack-plugin")
const miniCssExtractPlugin = require("mini-css-extract-plugin");
const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
    entry: {
        entry1: path.resolve(__dirname, './src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [miniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /\.scss$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(png|jpg|gif)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 8192
                    }
                },
                generator: {
                    filename: 'images/[hash][ext][query]'
                }
            },
            {
                test:/\.(eot|svg|ttf|woff|woff2)/,
                type: 'asset',
                generator: {
                    filename: 'fonts/[hash][ext][query]'
                }
            },
            {
                test: /\.html$/,
                use: [
                    'html-withimg-loader'
                ],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "eslint-loader",
                options: {
                    fix: true
                }
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            template: "./src/index.html",
            filename: "index.html",
            minify: {
                // 移除空格换行
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        }),
        new miniCssExtractPlugin(),
        new optimizeCssAssetsWebpackPlugin()
    ],
    devServer: {
        open: true,
        port: 8090
    },
    mode: 'development',
    target: "web"
}

package.json

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "test": "echo \"Error: no test specified\" && exit 1",
	"start": "webpack-dev-server --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.60.0",
    "webpack-cli": "^4.9.1"
  }
}
npm start

更改下文件,查看浏览器效果

4、axios

npm i -S axios
npm i -D webpack webpack-cli

4.1、快速入门

@RestController
@CrossOrigin
public class HelloController {
    @RequestMapping("/")
    public String hello(){
        return "hello,vue server!";
    }
    @RequestMapping("/name")
    public String hello(@RequestParam String name){
        return "hello,"+name;
    }
}
import axios from "axios";

console.log("hello,world!")

axios.get("http://localhost:8099/").then(res=>{
    console.log(res);
})
axios.get("http://localhost:8099/name?name=frost").then(res=>{
    console.log(res);
})

4.2、处理并发请求

import axios from "axios";

console.log("hello,world!")

axios.all([
    axios.get("http://localhost:8099/"),
    axios.get("http://localhost:8099/name?name=frost")
]).then(res=>{
    console.log(res);
})

4.3、全局配置

import axios from "axios";

console.log("hello,world!")

axios.defaults.baseURL = "http://localhost:8099/"
axios.defaults.timeout = 5000

axios.get("name?name=frost").then(res=>{
    console.log(res);
})

4.5、实例封装

import axios from "axios";

console.log("hello,world!")

const localhost1=axios.create({
    baseURL: "http://localhost:8099/"
})
const localhost2=axios.create({
    baseURL: "http://localhost:8199/"
})
localhost1.get("name?name=frost").then(res=>{
    console.log(res);
})

4.6、拦截器

import axios from "axios";

console.log("hello,world!")

const localhost1=axios.create({
    baseURL: "http://localhost:8099/"
})
const localhost2=axios.create({
    baseURL: "http://localhost:8199/"
})
localhost1.interceptors.request.use(config=>{
    console.log("请求拦截成功,给请求加点料");
    return config
},error => {
    console.log(error);
})
localhost1.interceptors.response.use(config=>{
    console.log("响应拦截成功,给响应加点料");
    return config
},error => {
    console.log(error);
})
localhost1.get("name?name=frost").then(res=>{
    console.log(res);
})

5、VUE

5.1、vue脚手架

全局安装vue脚手架

npm install -g @vue/cli

创建项目

vue create 项目名
PS D:\ITEM> vue create vue

Vue CLI v4.5.15
? Please pick a preset: (Use arrow keys)
> standard ([Vue 3] babel, router, vuex, eslint)
  Default ([Vue 2] babel, eslint)
  Default (Vue 3) ([Vue 3] babel, eslint)
  Manually select features

自定义项目配置

PS D:\ITEM> vue create vue

Vue CLI v4.5.15
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, CSS Pre-processors, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass)
? Pick a linter / formatter config: Airbnb
? Pick additional lint features: Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? Yes
? Save preset as: wenley-project

�  Preset wenley-project saved in C:\Users\xumeng03\.vuerc

5.2、vue.config.js

与webpack配置不一样,精简了许多

详细配置清单

5.3、插值

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{ msg }}</p>
    <!--不解析内部内容-->
    <p v-pre>{{ msg }}</p>
    <!--只显示初始化的值,不跟随data变化-->
    <p v-once>{{ msg }}</p>
    <!--不解析html标签,只作为字符串显示-->
    <p v-text="msg"></p>
    <!--解析html标签-->
    <p v-html="msg"></p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: '<strong>hello world!</strong>',
    };
  },
};
</script>

<template>
  <div class="about">
    <h1 :title="msg">This is an about page</h1>
    <!--<h1 v-bind:title="msg">This is an about page</h1>-->
    <p style="color:red">This is an about page</p>
    <p :style="{'font-size':'12px'}">This is an about page</p>
    <p :style="style">This is an about page</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: 'This is an about page',
      style: {
        'font-size': '12px',
      },
    };
  },
};
</script>

几乎所有的html属性都可以使用v-bind绑定

5.4、计算属性

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{ title }} - {{ slogan }}</p>
    <p>{{ title + '-' + slogan }}</p>
    <p>{{ TheTitle }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'This is an about page',
      slogan: '标语',
    };
  },
  computed: {
    // 只要依赖值未变化,则不会重新计算
    TheTitle: {
      get() {
        return `${this.title}#${this.slogan}`;
      },
    },
  },
};
</script>

5.5、事件

<template>
  <div class="about">
    <h1 @click="click">This is an about page</h1>
    <!--<h1 v-on:click="click">This is an about page</h1>-->
    <h1 @click="click1($event)">This is an about page</h1>
    <!--<h1 v-on:click="click1($event)">This is an about page</h1>-->
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'This is an about page',
    };
  },
  methods: {
    click() {
      console.log(111);
    },
    click1(e) {
      console.log(e);
      console.log(111);
    },
  },
};
</script>

事件修饰符

  • stop:阻止事件冒泡
  • prevent:阻止默认事件的发生
  • capture:捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行,然后再按自然顺序执行触发的事件
  • self:将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响
  • once:设置事件只能触发一次

5.6、条件分支

  • v-if:为false不渲染
  • v-show:为false仅仅使用css隐藏
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p v-if="true">v-if=true</p>
    <p v-if="false">v-if=false</p>
    <p v-else>v-if=false</p>
    <p v-show="true">v-show=true</p>
    <p v-show="false">v-show=false</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'This is an about page',
    };
  },
};
</script>

5.7、循环

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <ul>
      <li v-for="item in list" :key="item">{{ item }}</li>
    </ul>
    <ul>
      <li v-for="(item,index) in list" :key="index">{{ index+' '+item }}</li>
    </ul>
    <ul>
      <li v-for="(value,key) in book" :key="key">{{ key+' '+value }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: ['java', 'c#', 'c', 'nasm', 'vue'],
      book: {
        name: 'java web',
        price: 128,
        date: '2021-12-31',
      },
    };
  },
};
</script>

5.8、v-model

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <input type="text" v-model="name">
    <br>
    <input type="number" v-model.number="age">
    <br>
    <input type="text" v-model.trim="name">
    <br>
    <input type="text" v-model.lazy="name">
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'wenley',
      age: 5,
    };
  },
};
</script>

修饰符

  • number 限制用户输入的只能是数字(不是将用户输入的字符串转换成number!会将input里的值用parseFloat()转化!)
  • trim 限制用户不能输入空格
  • lazy:改变input框中的内容并不会使得数据马上发生变化,此时当输入框失去焦点后触发change事件

5.9、监视

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <input type="text" v-model="people.name"/>
    {{ watchName }}
    <input type="text" v-model="name"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      watchName: 'wenley',
      name: 'wenley',
      people: {
        name: 'wenley',
      },
    };
  },
  watch: {
    name(newvalue, oldvalue) {
      console.log(oldvalue);
      console.log(newvalue);
      this.watchName = newvalue;
    },
    'people.name': {
      handler(newvalue, oldvalue) {
        console.log(oldvalue);
        console.log(newvalue);
        this.watchName = newvalue;
      },
      deep: true,
    },
  },
};
</script>

5.10、组件

home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <!-- 组件使用 -->
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
// 组件引入
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';

export default {
  name: 'Home',
  // 组件注册
  components: {
    HelloWorld,
  },
};
</script>

helloworld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

5.10.1、组件通信-父传子

home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <!-- 组件使用 -->
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
// 组件引入
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';

export default {
  name: 'Home',
  // 组件注册
  components: {
    HelloWorld,
  },
};
</script>

helloworld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

props默认值(缺省值)

props: {
  demoString: {
    type: String,
	//缺省值
    default: '',
    //是否必传
    required:true
  },
  demoNumber: {
    type: Number,
    default: 0
  },
  demoBoolean: {
    type: Boolean,
    default: true
  },
  demoArray: {
    type: Array,
    default: []
  },
  demoObject: {
    type: Object,
    default: {}
  },
  demoFunction: {
    type: Function,
    default: function () { }
  }
}
5.10.2、组件通信-子传父

helloworld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>{{ msg1 }}</h2>
    <input type="text" v-model="num" @input="()=>this.$emit('numChange',num)">
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
             target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
             target="_blank" rel="noopener">router</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
             target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
             target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank"
             rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank"
             rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
    msg1: {
      default: ['a', 'b'],
    },
  },
  data() {
    return {
      num: 0,
    };
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
  margin: 40px 0 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld @numChange="numChange" msg="Welcome to Your Vue.js App"/>
  </div>
  <div>
    111-
    {{ res }}
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';

export default {
  name: 'Home',
  components: {
    HelloWorld,
  },
  data() {
    return {
      res: 0,
    };
  },
  methods: {
    numChange(num) {
      console.log(num);
      // eslint-disable-next-line radix
      this.res += parseInt(num);
    },
  },
};
</script>

5.10.3、父子组件相互访问

helloworld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>{{ msg1 }}</h2>
    <h3>{{ num }}</h3>
    <!--<input type="text" v-model="num" @input="()=>this.$emit('numChange',num)">-->
    <input type="button" value="res++" @click="()=>this.$parent.res++">
    <input type="button" value="res++" @click="()=>this.$parent.numChange(1)">
    <br>
    <input type="button" value="log" @click="()=>this.$root.log()">
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
             target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
             target="_blank" rel="noopener">router</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
             target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
             target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank"
             rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank"
             rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
    msg1: {
      default: ['a', 'b'],
    },
  },
  data() {
    return {
      num: 0,
    };
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
  margin: 40px 0 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld ref="helloworld" @numChange="numChange" msg="Welcome to Your Vue.js App"/>
  </div>
  <div>
    111-
    {{ res }}
  </div>
  <input type="button" value="num++" @click="()=>this.$refs.helloworld.num++">
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';

export default {
  name: 'Home',
  components: {
    HelloWorld,
  },
  data() {
    return {
      res: 0,
    };
  },
  methods: {
    numChange(num) {
      console.log(num);
      // eslint-disable-next-line radix
      this.res += parseInt(num);
    },
  },
};
</script>

5.10.4、插槽

TheSlot.vue

<template>
  <div>
    <h3>This is slot test</h3>
    <slot>
      <span>这个插槽好像是空的?</span>
    </slot>
  </div>
</template>

<script>
export default {
  name: 'TheSlot',
};
</script>

<style scoped>

</style>

About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <TheSlot>
      <input type="text">
    </TheSlot>
    <TheSlot>
      <input type="button" value="button">
    </TheSlot>
    <TheSlot>
      <a href="https://www.baidu.com/">百度</a>
    </TheSlot>
    <TheSlot></TheSlot>
  </div>
</template>

<script>
// eslint-disable-next-line import/extensions
import TheSlot from './TheSlot';

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    TheSlot,
  },
};
</script>

具名插槽

TheSlot.vue

<template>
  <div>
    <h3>This is slot test</h3>
    <slot name="slot1">
      <span>slot1好像是空的?</span>
    </slot>
    <br>
    <slot name="slot2">
      <span>slot2好像是空的?</span>
    </slot>
    <br>
    <slot>
      <span>slot3好像是空的?</span>
    </slot>
  </div>
</template>

<script>
export default {
  name: 'TheSlot',
};
</script>

<style scoped>

</style>

About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <TheSlot>
      <template v-slot:slot1>
        <input type="text">
      </template>
      <template v-slot:slot2>
        <input type="button" value="button">
      </template>
    </TheSlot>
    <TheSlot>
      <template v-slot:slot1>
        <input type="text">
      </template>
    </TheSlot>
    <TheSlot>
      <a href="https://www.baidu.com/">百度</a>
	  <!--<template v-slot:default>-->
      <!--  <input type="text">-->
      <!--</template>-->
    </TheSlot>
  </div>
</template>

<script>
// eslint-disable-next-line import/extensions
import TheSlot from './TheSlot';

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    TheSlot,
  },
};
</script>

插槽数据

TheSlot.vue

<template>
  <div>
    <h3>This is slot test</h3>
    <slot name="slot1">
      <span>slot1好像是空的?</span>
    </slot>
    <br>
    <slot name="slot2">
      <span>slot2好像是空的?</span>
    </slot>
    <br>
    <slot :user="user">
      <span>slot3好像是空的?</span>
    </slot>
  </div>
</template>

<script>
export default {
  name: 'TheSlot',
  data() {
    return {
      user: {
        name: 'slot',
      },
    };
  },
};
</script>

<style scoped>

</style>

About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <TheSlot>
      <template v-slot:slot1>
        <input type="text">
      </template>
      <template v-slot:slot2>
        <input type="button" value="button">
      </template>
      <template v-slot:default="children">
        <span>{{children.user.name}}</span>
      </template>
    </TheSlot>
  </div>
</template>

<script>
// eslint-disable-next-line import/extensions
import TheSlot from './TheSlot';

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    TheSlot,
  },
  data() {
    return {
      user: {
        name: 'about',
      },
    };
  },
};
</script>

5.11、生命周期

官方描述:https://v3.cn.vuejs.org/api/options-lifecycle-hooks.html#beforecreate

  • beforeCreate:
  • created:
  • beforeMount:
  • mounted:
  • beforeUpdate:
  • updated:
  • beforeUnmount:
  • unmounted:
  • activated:keep-alive组件激活时触发
  • deaactivated:keep-alive组件停用时触发

延迟处理

缓存标签

TheSlot.vue

<template>
  <div>
    <h3>This is slot test</h3>
    <p>{{ num }}</p>
    <slot name="slot1">
      <span>slot1好像是空的?</span>
    </slot>
    <br>
    <slot name="slot2">
      <span>slot2好像是空的?</span>
    </slot>
    <br>
    <slot :user="user">
      <span>slot3好像是空的?</span>
    </slot>
  </div>
</template>

<script>
export default {
  name: 'TheSlot',
  data() {
    return {
      user: {
        name: 'slot',
      },
      num: 0,
    };
  },
};
</script>

<style scoped>

</style>

About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <input type="button" value="num++" @click="()=>this.$refs.slot1.num++">
    <input type="button" value="slot" @click="()=>this.isShow=!this.isShow">
    <!--<TheSlot v-if="isShow" ref="slot1">-->
    <!--  <template v-slot:slot1>-->
    <!--    <input type="text">-->
    <!--  </template>-->
    <!--  <template v-slot:slot2>-->
    <!--    <input type="button" value="button">-->
    <!--  </template>-->
    <!--  <template v-slot:default="children">-->
    <!--    <span>{{children.user.name}}</span>-->
    <!--  </template>-->
    <!--</TheSlot>-->
    <keep-alive>
      <TheSlot v-if="isShow" ref="slot1">
        <template v-slot:slot1>
          <input type="text">
        </template>
        <template v-slot:slot2>
          <input type="button" value="button">
        </template>
        <template v-slot:default="children">
          <span>{{children.user.name}}</span>
        </template>
      </TheSlot>
    </keep-alive>
  </div>
</template>

<script>
// eslint-disable-next-line import/extensions
import TheSlot from './TheSlot';

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    TheSlot,
  },
  data() {
    return {
      user: {
        name: 'about',
      },
      isShow: true,
    };
  },
};
</script>

延迟处理

About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <input type="button" value="slot" @click="log">
    <input v-if="isShow" type="text" ref="input">
  </div>
</template>

<script>
// eslint-disable-next-line import/extensions
import TheSlot from './TheSlot';

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    TheSlot,
  },
  data() {
    return {
      user: {
        name: 'about',
      },
      isShow: true,
      text: 'this is a text',
    };
  },
  methods: {
    log() {
      this.isShow = !this.isShow;
      if (this.isShow) {
        this.$refs.input.focus();
      }
    },
  },
};
</script>

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <input type="button" value="slot" @click="log">
    <input v-if="isShow" type="text" ref="input">
  </div>
</template>

<script>
// eslint-disable-next-line import/extensions
import TheSlot from './TheSlot';

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    TheSlot,
  },
  data() {
    return {
      user: {
        name: 'about',
      },
      isShow: true,
      text: 'this is a text',
    };
  },
  methods: {
    log() {
      this.isShow = !this.isShow;
      // if (this.isShow) {
      //   this.$nextTick(() => {
      //     this.$refs.input.focus();
      //   });
      // }
    },
  },
};
</script>

5.12、axios

npm i -S axios
npm i -S qs
5.12.1、axios二次封装
import axios from 'axios';
import qs from 'qs';

const network = axios.create({
  baseURL: 'http://localhost:8099/',
  timeout: 5000,
});
network.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 请求拦截
network.interceptors.request.use((request) => {
  console.log('请求拦截成功,给请求加点料');

  // token添加

  if (request.method === 'get' && request.params) {
    // eslint-disable-next-line no-param-reassign
    request.url = `${request.url}?${qs.stringify(request.params)}`;
    // eslint-disable-next-line no-param-reassign
    delete request.params;
  }

  return request;
}, (error) => {
  console.log(error);
});

// 响应拦截
network.interceptors.response.use((response) => {
  console.log('响应拦截成功,给响应加点料');
  return response;
}, (error) => {
  if (error) {
    // eslint-disable-next-line default-case
    switch (error.status) {
      case 400:
        // 错误请求
        console.log('错误请求');
        break;
      case 401:
        // 权限验证失败,跳转登录页
        console.log('权限验证失败,跳转登录页');
        break;
      case 403:
        //  请求被拒绝
        console.log('拒绝请求');
        break;
      case 404:
        // 页面找不到
        console.log('页面找不到');
        break;
      case 405:
        // 请求方法不被支持
        console.log('请求方法不被支持');
        break;
      case 500:
        // 服务器遇到错误
        console.log('服务器遇到错误');
        break;
      case 502:
        // 网关错误
        console.log('网关错误');
        break;
      case 503:
        // 服务不可用
        console.log('服务不可用');
        break;
    }
  } else {
    // eslint-disable-next-line no-lonely-if
    if (!window.navigator.onLine) {
      // 断网处理
      console.log('断网处理');
    } else {
      console.log('服务器崩溃');
    }
  }
});

export default {
  // 导出post请求
  post(url, data) {
    return network.post(url, data);
  },
  // 导出get请求
  get(url, data) {
    return network.get(url, { params: data });
  },
};
5.12.2、注入vue实例
import { createApp } from 'vue';
import App from './App.vue';
import network from './network/request';
import router from './router';
import store from './store';

const app = createApp(App);
// Vue.prototype.$http = network;
app.config.globalProperties.$http = network;
app.use(store)
  .use(router)
  .mount('#app');
5.12.3、使用
this.$http.post('post', {
      str: 'wenley',
      str1: '111',
    })
    .then((res) => {
    	console.log(res);
	});

5.13、router

$router代表全局路由

$route代表当前页路由

5.13.1、快速入门

router/index.js

import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

App.vue

<template>
  <div id="nav">
    <!--router-link与router-view成对出现-->
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about">About</router-link>
  </div>
  <router-view/>
</template>

<script>

export default {
};
</script>

5.13.2、懒加载

直接加载会打成一个chunk,懒加载打成多个chunk

vue3取消了router-link的tag标签

replace
<router-link to="/about" tag="span" event="dblclick">About Us</router-link>
with
<router-link to="/about" custom v-slot="{ navigate }">
  <span @click="navigate" @keypress.enter="navigate" role="link">About Us</span>
</router-link>
5.13.4、r o u t e r . g o ( ) 与 router.go()与router.go()与router.back()

go(-1): 原页面表单中的内容会丢失

  • this.$router.go(-1):后退+刷新
  • this.$router.go(0):刷新
  • this.$router.go(1) :前进

back(): 原页表表单中的内容会保留

  • this.$router.back():后退
  • this.$router.back(0) 刷新
  • this.$router.back(1):前进
5.13.5、$router的使用
<template>
  <div id="nav">
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about">About</router-link>
    |
    <router-link to="/about1" custom v-slot="{navigate}">
      <button @click="navigate">About1</button>
    </router-link>
    |
    <button @click="about2">About2</button>
    |
    <button @click="$router.go(-1)">Back</button>
    <!--<button @click="$router.back()">Back</button>-->
  </div>
  <router-view/>
</template>

<script>

export default {
  methods: {
    about2() {
      this.$router.push('/about2');
    },
  },
};
</script>

5.13.6、命名视图

视图未命名

<template>
  <div id="nav">
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about">About</router-link>
    |
    <router-link to="/about1" custom v-slot="{navigate}">
      <button @click="navigate">About1</button>
    </router-link>
    |
    <button @click="about2">About2</button>
  </div>
  <router-view/>
  <router-view/>
  <router-view/>
</template>

<script>

export default {
  methods: {
    about2() {
      this.$router.push('/about2');
    },
  },
};
</script>

视图命名

<template>
  <div id="nav">
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about">About</router-link>
    |
    <router-link to="/about1" custom v-slot="{navigate}">
      <button @click="navigate">About1</button>
    </router-link>
    |
    <button @click="about2">About2</button>
  </div>
  <router-view/>
  <router-view name="About1" />
  <router-view name="About2" />
</template>

<script>

export default {
  methods: {
    about2() {
      this.$router.push('/about2');
    },
  },
};
1234567891011121314151617181920212223242526
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
// eslint-disable-next-line import/extensions
import About1 from '@/views/About1';
// eslint-disable-next-line import/extensions
import About2 from '@/views/About2';

const routes = [
  {
    path: '/',
    name: 'Home',
    components: {
      default: Home,
      About1,
      About2,
    },
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
  },
  {
    path: '/about1',
    name: 'About1',
    component: () => import('../views/About1.vue'),
  },
  {
    path: '/about2',
    name: 'About2',
    component: () => import('../views/About2.vue'),
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

5.13.7、路由嵌套
<template>
  <div id="nav">
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about">About</router-link>
    |
    <router-link to="/about/a1" custom v-slot="{navigate}">
      <button @click="navigate">About1</button>
    </router-link>
    |
    <button @click="about2">About2</button>
  </div>
  <router-view/>
</template>

<script>

export default {
  name: 'App',
  methods: {
    about2() {
      this.$router.push('/about/a2');
    },
  },
};
</script>
<template>
  <div class="about">
    <router-link to="/about/a1" custom v-slot="{navigate}">
      <button @click="navigate">About1</button>
    </router-link>
    |
    <button @click="about2">About2</button>
    <h1>This is an about page</h1>
    <router-view/>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {
    about2() {
      this.$router.push('/about/a2');
    },
  },
};
</script>
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
// eslint-disable-next-line import/extensions
import About1 from '@/views/About1';
// eslint-disable-next-line import/extensions
import About2 from '@/views/About2';
// eslint-disable-next-line import/extensions
import About from '@/views/About';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    // name: 'About',
    component: About,
    children: [
      {
        path: 'a1',
        component: About1,
      },
      {
        path: 'a2',
        component: About2,
      },
    ],
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

5.13.8、动态路由

params参数传递

<template>
  <div id="nav">
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about/2">About</router-link>
    |
    <button @click="click">About</button>
  </div>
  <router-view/>
</template>

<script>

export default {
  name: 'App',
  methods: {
    click() {
      this.$router.push('/about/3');
    },
  },
};
</script>
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{$route.path}}</p>
    <p>{{$route.params.id}}</p>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
};
</script>
// eslint-disable-next-line import/extensions
import About from '@/views/About';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about/:id',
    name: 'About',
    component: About,
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

query参数传递

<template>
  <div id="nav">
    <router-link to="/">Home</router-link>
    |
    <router-link to="/about?name=wenley&age=1">About</router-link>
    |
    <button @click="click">About</button>
  </div>
  <router-view/>
</template>

<script>

export default {
  name: 'App',
  methods: {
    click() {
      this.$router.push({
        path: '/about',
        query: {
          name: 'wenley',
          age: 2,
        },
      });
    },
  },
};
</script>
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <p>{{$route.path}}</p>
    <p>{{$route.query.name}}</p>
    <p>{{$route.query.age}}</p>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
};
</script>
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
// eslint-disable-next-line import/extensions
import About1 from '@/views/About1';
// eslint-disable-next-line import/extensions
import About2 from '@/views/About2';
// eslint-disable-next-line import/extensions
import About from '@/views/About';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

5.13.9、重定向
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
// eslint-disable-next-line import/extensions
import About from '@/views/About';
// eslint-disable-next-line import/extensions
import About1 from '@/views/About1';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    // redirect: '/about1',
    // redirect: { name: 'About1' },
    redirect: {
      path: '/about',
      query: {
        name: 'wenley',
        age: 4,
      },
    },
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
  {
    path: '/about1',
    name: 'About1',
    component: About1,
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

5.13.10、别名
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
// eslint-disable-next-line import/extensions
import About from '@/views/About';
// eslint-disable-next-line import/extensions
import About1 from '@/views/About1';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    // alias: '/home',
    alias: ['/home', '/h'],
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
  {
    path: '/about1',
    name: 'About1',
    component: About1,
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

5.13.11、导航守卫

待补

5.14、Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

5.14.1、快速入门
import { createStore } from 'vuex';

export default createStore({
  state: {
    num: 0,
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  },
});
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.state.num++">
      {{ $store.state.num }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

5.14.2、mutations的使用

mutations基本使用

import { createStore } from 'vuex';

export default createStore({
  state: {
    num: 0,
    num1: 0,
  },
  mutations: {
    add(state) {
      // eslint-disable-next-line no-plusplus
      state.num1 += 2;
    },
  },
  actions: {},
  modules: {},
});
12345678910111213141516
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.state.num++">
      {{ $store.state.num }}
    </div>
    <div @click="()=>this.$store.commit('add')">
      {{ $store.state.num1 }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

mutations传参(单参数)

import { createStore } from 'vuex';

export default createStore({
  state: {
    num: 0,
    num1: 0,
    num2: 0,
  },
  mutations: {
    add(state) {
      // eslint-disable-next-line no-plusplus
      state.num1 += 2;
    },
    add1(state, count) {
      // eslint-disable-next-line no-plusplus
      state.num2 += count;
    },
  },
  actions: {},
  modules: {},
});
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.state.num++">
      {{ $store.state.num }}
    </div>
    <div @click="()=>this.$store.commit('add')">
      {{ $store.state.num1 }}
    </div>
    <div @click="()=>this.$store.commit('add1',Math.random())">
      {{ $store.state.num2 }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

mutations传参(多参数)

import { createStore } from 'vuex';

export default createStore({
  state: {
    num: 0,
    num1: 0,
    num2: 0,
    num3: 0,
  },
  mutations: {
    add(state) {
      // eslint-disable-next-line no-plusplus
      state.num1 += 2;
    },
    add1(state, step) {
      // eslint-disable-next-line no-plusplus
      state.num2 += step;
    },
    // add2(state, step, count) {
    //   // eslint-disable-next-line no-plusplus
    //   state.num3 += step * count;
    // },
    add2(state, object) {
      // eslint-disable-next-line no-plusplus
      state.num3 += object.step * object.count;
    },
  },
  actions: {},
  modules: {},
});
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.state.num++">
      {{ $store.state.num }}
    </div>
    <div @click="()=>this.$store.commit('add')">
      {{ $store.state.num1 }}
    </div>
    <!--单参数-->
    <div @click="()=>this.$store.commit('add1',Math.random())">
      {{ $store.state.num2 }}
    </div>
    <!--多参数-->
    <!--<div @click="()=>this.$store.commit('add2',2,2)">-->
    <!--  {{ $store.state.num3 }}-->
    <!--</div>-->
    <div @click="()=>this.$store.commit('add2',{step: 2,count: 2})">
      {{ $store.state.num3 }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

5.14.3、devTools

devTools

5.14.4、getters
import { createStore } from 'vuex';

export default createStore({
  state: {
    num: 0,
  },
  mutations: {
    add(state, step) {
      state.num += step;
    },
  },
  getters: {
    num2(state) {
      return state.num * state.num;
    },
  },
  actions: {},
  modules: {},
});
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.commit('add',2)">
      {{ $store.state.num }}
    </div>
    <div>
      {{ $store.getters.num2 }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

5.14.5、actions
import { createStore } from 'vuex';

export default createStore({
  state: {
    num: 0,
  },
  mutations: {
    add(state, step) {
      state.num += step;
    },
  },
  getters: {
    num2(state) {
      return state.num * state.num;
    },
  },
  actions: {
    api(content) {
      setTimeout(() => {
        // eslint-disable-next-line no-param-reassign
        // content.state.num += 5;
        content.commit('add', 5);
      }, 5000);
    },
  },
  modules: {},
});
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.commit('add',2)">
      {{ $store.state.num }}
    </div>
    <div>
      {{ $store.getters.num2 }}
    </div>
    <div @click="()=>this.$store.dispatch('api')">
      点击请求API
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

5.14.6、modules
import { createStore } from 'vuex';

const moduleA = {
  state: () => ({ num: 1 }),
  mutations: {},
  actions: {},
  getters: {},
};

const moduleB = {
  state: () => ({ num: 2 }),
  mutations: {},
  actions: {},
  getters: {},
};

export default createStore({
  modules: {
    a: moduleA,
    b: moduleB,
  },
});
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <div @click="()=>this.$store.commit('add',2)">
      {{ $store.state.a.num }}
    </div>
    <div>
      {{ $store.state.b.num }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'About',
  data() {
    return {};
  },
  methods: {},
};
</script>

相关文章

目录