赞
踩
VirtualBox+Vagrant安装虚拟机失败。使用VMWare
作用于VMWare一致
下载进行安装(需要开启CPU虚拟化)
进行快速创建虚拟机需要搭配Oracle VM VirtualBox进行使用
下载地址 https://www.vagrantup.com/downloads.html Vagrant 下载
下载完成后,重启系统,打开cmd测试是否安装成功,输入vagrant
,出现指令
https://app.vagrantup.com/boxes/search Vagrant 官方镜像仓库
在镜像官网寻找镜像[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wLp9qlB8-1658967177213)(resource/image/image-20220722154742854.png)]
根据镜像名称进行安装
进入虚拟机要安装的文件夹打开cmd键入vagrant init centos/7
最后一个值为镜像官网的镜像名称
文件夹生成一个Vagrantfile文件后,在cmd窗口键入vagrant up
进行安装镜像,安装完成后VirtualBox会生成镜像系统
安装成功后在cmd中vagrant ssh
进行连接,系统 root 用户的密码是vagrant
修改IP
在本地Vagrantfile文件中
重启vagrant:vagrant reload
允许账号密码登录
vi /etc/ssh/sshd_config
修改 PasswordAuthentication yes/no
重启服务 service sshd restart
虚拟化容器技术。Docker基于镜像,可以秒级启动各种容器。每一种容器都是一个完整的运行 环境,容器之间互相隔离。
删除docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装 Docker-CE
yum install -y yum-utils
设置下载地址
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装Docker
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
启动docker
systemctl start docker
查看docker版本
docker -v
设置docker自启动
systemctl enable docker
配置docker镜像加速(使用阿里云镜像加速器)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://afjpae5l.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
## 查看docker中的容器 docker images ## 查看docker中正在运行的容器 docker ps ## 进入容器 (一个容器相当于一个linux系统) docker exec -it 容器id 或 容器names /bin/bash ## 退出容器 exit; ## 重启容器 docker restart 容器id 或 容器names ## 设置容器自动启动 docker update 容器名 --restart=always
Docker镜像网站 https://hub.docker.com/
## 冒号后面可以跟dockerhub网站中的版本
docker pull mysql:5.7
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
# 参数说明
# -p 3306:3306:将容器的 3306 端口映射到主机的 3306 端口
# --name 设置容器名字
# -v 目录挂载 将冒号后面(容器内部的文件)映射到linux,这样修改容器的文件不需要进入到docker
# -v /mydata/mysql/conf:/etc/mysql:将配置文件夹挂载到主机
# -v /mydata/mysql/log:/var/log/mysql:将日志文件夹挂载到主机
# -v /mydata/mysql/data:/var/lib/mysql/:将配置文件夹挂载到主机
# -e MYSQL_ROOT_PASSWORD=root:初始化 root 用户的密码
# -d 后台运行 mysql:5.7表示使用mysql:5.7启动容器
因为设置了目录挂载,直接设置linux下的文件即可
vi /mydata/mysql/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
注意:解决 MySQL 连接慢的问题
在配置文件中加入如下,并重启 mysql [mysqld] skip-name-resolve 解释: skip-name-resolve:跳过域名解析
docker restart mysql
查看是否修改成功
进入mysql容器中
docker exec -it mysql /bin/bash
cat /etc/mysql/my.cnf
设置root远程访问
docker exec -it mysql mysql -uroot -proot
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
下载容器
docker pull redis
创建实例并启动
# 创建redis挂载目录
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
# 创建实例并启动
docker run -p 6379:6379 --name redis \
-v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
# redis-server /etc/redis/redis.conf 以/etc/redis/redis.conf配置文件启动redis-server
修改redis配置(配置自己找)
https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf
(需要关闭保护模式,并且注释bind)
vi /mydata/redis/conf/redis.conf
# 重启docker容器
docker restart redis
测试redis
docker exec -it redis redis-cli
windows配置阿里云镜像,在maven安装位置修改settings.xml文件
maven安装位置:D:\Software\Java\apache-maven-3.8.5\conf
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
配置maven使用jdk1.8编译项目
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
在idea中配置maven
idea 安装
lombok、mybatisx 插件
Vscode 安装
参考git笔记
在码云创建项目
在IDEA进行Clone 链接
商品服务、仓储服务、订单服务、优惠券服务、用户服务
共同:
先在虚拟机中设置MySQL和redis自启动
docker update redis --restart=always
docker update mysql --restart=always
创建数据库,导入sql
我们使用人人开源管理系统进行快速开发
renren-fast
项目加入到我们的gulimall
父工程renren-fast
中db文件夹的mysql.sql
文件运行到新的数据库gulimall_admin
renren-fast
中pom文件的parent
标签删除,并在父工程添加model
标签。安装node,参考其他笔记
安装依赖
# 在vsCode中打开控制台,
npm install
npm run dev
运行成功,出现登陆界面,使用admin admin进行登陆
首先克隆renren-generator:https://gitee.com/renrenio/renren-generator
克隆完成后,将项目加入gulimall父工程,并将其添加为子工程
修改pom文件
<!-- 添加 --> <properties> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> </properties> <!-- 在dependency下面添加以下 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
更改application.yml文件的mysql地址 将数据库改为 要逆向生成的数据库地址,并修改账号密码
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.219.121:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
修改逆向工程中resource下template中Controller.java.vm文件,将其中的@RequiresPermissions注解(Shrio安全配置)注释,暂时不用。然后运行项目
生成逆向工程文件,将文件中main文件夹替换微服务项目中的文件。
逆向生成的文件中依赖renren-fast中的文件,所以创建maven工程gulimall-common公共资源工程,并添加依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>gulimall</artifactId> <groupId>cn.zcx.gulimall</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>gulimall-common</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.14</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.7.RELEASE</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> </dependencies> </project>
将逆向工程所需要的公共依赖从renren-fast中复制到到common工程中
在所有的微服务模块中引入common
common的pom文件中导入MySQL驱动
<!-- 导入mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
在product中配置yum文件
spring: datasource: username: root password: root url: jdbc:mysql://192.168.219.121:3306/gulimall_pms driver-class-name: com.mysql.jdbc.Driver mybatis-plus: # 映射文件 mapper-locations: classpath*:/mapper/**/*.xml # 主键自增 global-config: db-config: id-type: auto server: port:
其他modeul同理
server:
port: 10000
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--nacos-discovery 注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理 平台。他是使用 java 编写。需要依赖 java 环境 Nacos 文档地址: https://nacos.io/zh-cn/docs/quick-start.html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ddJ2Ps1r-1658967177220)(images/image-20220726091423404.png)]
注意:每一个应用都应该有名字,这样才能注册上去。
@RequestMapping("/member/list")
public R membercoupons() {
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("满100减10");
return R.ok().put("coupons", Arrays.asList(couponEntity));
}
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
@RequestMapping("/coupon/coupon/member/list")
public R membercoupons();
}
@EnableFeignClients(basePackages = "com.yl.gulimall.member.feign") //引入feifn所在的包
@SpringBootApplication
@EnableDiscoveryClient
public class GulimallMemberApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallMemberApplication.class, args);
}
}
localhost:8000/member/member/coupons 调用成功
官方文档:
spring-cloud-alibaba/readme-zh.md at 2.2.x · alibaba/spring-cloud-alibaba · GitHub
<!-- 配置中心来做配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
在 nacos 中创建一个 应用名.properties 配置文件并编写
@RefreshScope //动态获取并刷新配置
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@Value("${coupon.user.name}")
private String name;
@Value("${coupon.user.age}")
private Integer age;
@RequestMapping("/test")
public R test() {
return R.ok().put("name", name).put("age", age);
}
如果配置中心和当前应用的配置文件中配置了相同的项,优先使用配置中心的配置
默认:public(保留空间):默认新增的所有配置都在public空间
1.开发、测试、生产:利用命名空间来做环境隔离
spring.cloud.nacos.config.namespace=0706d5ad-15d3-4755-ac17-259f2c057c33
2.基于微服务进行隔离
#每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
spring.cloud.nacos.config.namespace=00580b5a-a8c0-48b0-a0fc-4f032aa9fbf0
所有的配置的集合
类似于文件名 data ID
默认所有的配置集都属于DEFAULT_GROUP
spring.application.name=gulimall-coupon spring.cloud.nacos.config.server-addr=127.0.0.1:8848 #每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置 spring.cloud.nacos.config.namespace=00580b5a-a8c0-48b0-a0fc-4f032aa9fbf0 spring.cloud.nacos.config.group=dev spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yaml spring.cloud.nacos.config.extension-configs[0].group=dev spring.cloud.nacos.config.extension-configs[0].refresh=true spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yaml spring.cloud.nacos.config.extension-configs[1].group=dev spring.cloud.nacos.config.extension-configs[1].refresh=true spring.cloud.nacos.config.extension-configs[2].data-id=other.yaml spring.cloud.nacos.config.extension-configs[2].group=dev spring.cloud.nacos.config.extension-configs[2].refresh=true
mybatis.ymal
datasource.yaml
other.yaml
满足某些断言(predicates)就路由到指定的地址(uri),使用指定的过滤器(filter)
<dependency>
<groupId>com.yl.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
spring:
cloud:
gateway:
routes:
- id: test_route
uri: http://www.baidu.com
predicates:
- Query=url,baidu
- id: qq_route
uri: http://www.qq.com
predicates:
- Query=url,qq
- 各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路 由匹配。
- 一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
/*
* 1.开启服务注册发蔫(配置nacos的注册中心地址)
* */
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class GulimallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallGatewayApplication.class, args);
}
}
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
#每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
spring.cloud.nacos.config.namespace=27c870b8-3faa-47fe-9fc2-8b48c6d250cd
# 应用名称
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
server.port=88
启动报错:
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
解决方法:在“com.bigdata.gulimall.gulimallgateway.GulimallGatewayApplication”中排除和数据源相关的配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
重新启动
<script> // var 声明的变量往往会越域 // let 声明的变量有严格局部作用域 { var a = 1; let b = 2; } console.log(a); // 1 console.log(b); // ReferenceError: b is not defined // var 可以声明多次 // let 只能声明一次 var m = 1; var m = 2; let n = 3; // let n = 4 console.log(m); // 2 console.log(n); // Identifier 'n' has already been declared // var 会变量提升 // let 不存在变量提升 console.log(x); // undefined var x = 10; console.log(y); //ReferenceError: y is not defined let y = 20; // 1. 声明之后不允许改变 // 2. 一但声明必须初始化,否则会报错 const a = 1; a = 3; //Uncaught TypeError: Assignment to constant variabl </script>
const [x, y, z] = arr;
const { name,age,language } = person;
<!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> </head> <body> <script> // 1.数组解析 let arr = [1, 2, 3]; //以前我们想获取其中的值,只能通过角标。ES6 可以这样: const [x, y, z] = arr; // x,y,z 将与 arr 中的每个位置对应来取值 // 然后打印 console.log(x, y, z); const person = { name: "jack", age: 21, language: ["java", "js", "css"], }; // 2.对象解构 // 解构表达式获取值,将 person 里面每一个属性和左边对应赋值 const { name,age,language } = person; // 等价于下面 // const name = person.name; // const age = person.age; // const language = person.language; // 可以分别打印 console.log(name); console.log(age); console.log(language); //扩展:如果想要将 name 的值赋值给其他变量,可以如下,nn 是新的变量名 // const { name: nn, age, language } = person; // console.log(nn); // console.log(age); // console.log(language); </script> </body> </html>
ES6 为字符串扩展了几个新的 API:
includes()
:返回布尔值,表示是否找到了参数字符串。startsWith()
:返回布尔值,表示参数字符串是否在原字符串的头部。endsWith()
:返回布尔值,表示参数字符串是否在原字符串的尾部。
let str = "hello.vue";
console.log(str.startsWith("hello"));//true
console.log(str.endsWith(".vue"));//true
console.log(str.includes("e"));//true
console.log(str.includes("hello"));//true
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行 字符串,还可以在字符串中加入变量和表达式。
// 1、多行字符串 let ss = ` <div> <span>hello world<span> </div> ` console.log(ss); // 2、字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。 let name = "张三"; let age = 18; let info = `我是${name},今年${age}了`; console.log(info); // 3、字符串中调用函数 function fun() { return "这是一个函数"; } let sss = `O(∩_∩)O 哈哈~,${fun()}`; console.log(sss); // O(∩_∩)O 哈哈~,这是一个函数
function add2(a, b = 1)
//在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
// 判断 b 是否为空,为空就给默认值 1
b = b || 1;
return a + b;
}
// 传一个参数
console.log(add(10));
//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
return a + b;
}
// 传一个参数
console.log(add2(10));
function fun(...values)
不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。 具名参数只能放在参数列表的最后,并且有且只有一个不定参数
function fun(...values) {
console.log(values.length);
}
fun(1, 2); //2
fun(1, 2, 3, 4); //4
一个参数时:var print = (obj) => console.log(obj);
//以前声明一个方法
// var print = function (obj) {
// console.log(obj);
// }
// 可以简写为:
var print = (obj) => console.log(obj);
// 测试调用
print(100);
多个参数:
- 当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
- 代码不止一行,可以用
{}
括起来
// 两个参数的情况: var sum = function (a, b) { return a + b; }; // 简写为: //当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。 var sum2 = (a, b) => a + b; //测试调用 console.log(sum2(10, 10)); //20 // 代码不止一行,可以用`{}`括起来 var sum3 = (a, b) => { c = a + b; return c; }; //测试调用 console.log(sum3(10, 20)); //3
var hello2 = ({ name }) => {
console.log(“hello,” + name);
};
//需求,声明一个对象,hello 方法需要对象的个别属性 //以前的方式: const person = { name: "jack", age: 21, language: ["java", "js", "css"], }; function hello(person) { console.log("hello," + person.name); } //现在的方式 var hello2 = ({ name }) => { console.log("hello," + name); }; //测试 hello2(person);
新增的api
ES6 给 Object 拓展了许多新的方法,如:
- keys(obj):获取对象的所有 key 形成的数组
- values(obj):获取对象的所有 value 形成的数组
- entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:
[[k1,v1],[k2,v2],...]
- assign(dest, …src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层为浅拷贝)
const person = {
name: "jack",
age: 21,
language: ["java", "js", "css"],
};
console.log(Object.keys(person)); //["name", "age", "language"]
console.log(Object.values(person)); //["jack", 21, Array(3)]
console.log(Object.entries(person)); //[Array(2), Array(2), Array(2)]
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
//Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象。
Object.assign(target, source1, source2);
console.log(target); //{a: 1, b: 2, c: 3
声明对象简写
ES6:属性名和属性值变量名一样,可以省略
const age = 23;
const name = "张三";
// 传统
const person1 = { age: age, name: name };
console.log(person1);
// ES6:属性名和属性值变量名一样,可以省略
const person2 = { age, name };
console.log(person2); //{age: 23,
对象的函数属性简写
箭头函数版:拿不到 this (对象.属性)
eat2: (food) => console.log(person3.name + “在吃” + food),
let person3 = { name: "jack", // 以前: eat: function (food) { console.log(this.name + "在吃" + food); }, // 箭头函数版:这里拿不到 this eat2: (food) => console.log(person3.name + "在吃" + food), // 简写版: eat3(food) { console.log(this.name + "在吃" + food); }, }; person3.eat("苹果"); person3.eat2("香蕉"); person3.eat3("桃子");
对象拓展运算符
拓展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象
// 1、拷贝对象(深拷贝)
let person4 = { name1: "Amy", age1: 15 };
let someone = { ...person4 };
console.log(someone); //{name: "Amy", age: 15}
// 2、合并对象
let age1 = { age1: 15 };
let name1= { name1: "Amy" };
let person5 = { ...age1, ...name1 }; //如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值;
console.log(person5); //{name1: 'Amy', age1: 15}
数组中新增了 map 和 reduce 方法
map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回
let arr = ['1', '20', '-5', '3'];
console.log(arr)
arr = arr.map(s => s*2);
console.log(arr)
语法:
arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元 素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
callback (执行数组中每个值的函数,包含四个参数)
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组) initialValue (作为第一次调用 callback)
const arr = [1, 20, -5, 3];
//没有初始值:
let array = arr.reduce((a, b) => {
console.log("上次处理后a:" + a);
console.log("当前处理b:" + b);
return a + b;
});
console.log("最后结果" + array); //19
// 简写
console.log(arr.reduce((a, b) => a + b)); //19
console.log(arr.reduce((a, b) => a * b)); //-300
//指定初始值:
let array1 = arr.reduce((a, b) => {
console.log("上次处理后a:" + a);
console.log("当前处理b:" + b);
return a + b;
}, 2);
console.log("array1:" + array1); //21
// 简写
console.log(arr.reduce((a, b) => a + b, 2)); //21
console.log(arr.reduce((a, b) => a * b, 0)); //-0
const promise = new Promise((resolve, reject) =>{
// 执行异步操作
if (/* 异步操作成功 */) {
resolve(value);// 调用 resolve,代表 Promise 将返回成功的结果
} else {
reject(error);// 调用 reject,代表 Promise 会返回失败结果
}
});
promise.then(function (value) {
// 异步执行成功后的回调
}).catch(function (error) {
// 异步执行失败后的回调
})
<script src="js/jquery-1.10.2.min.js"></script> <script type="text/javascript"> let get = function (url, data) { // 实际开发中会单独放到 common.js 中 return new Promise((resolve, reject) => { $.ajax({ url: url, data: data, success(data) { resolve(data); }, error(error) { reject(error); }, }); }); }; // 使用封装的 get 方法,实现查询分数 get("mock/user.json") .then((data) => { console.log("查询用户:", data); return get(`mock/user_corse_${data.id}.json`); }) .then((data) => { console.log("查询到课程:", data); return get(`mock/corse_score_${data.id}.json`); }) .then((data) => { console.log("查询到分数:", data); }) .catch((error) => { console.log("出现异常了:" + error); }); </script>
模块化就是把代码进行拆分,方便重复利用。类似 java 中的导包:要使用一个包,必须先 导包。而 JS 中没有包的概念,换来的是 模块。
模块功能主要由两个命令构成:
export
和import
。
export
命令用于规定模块的对外接口。
import
命令用于导入其他模块提供的功能。
export
不仅可以导出对象,一切 JS 变量都可以导出。比如:基本类型变量、函数、数组、 对象。
export const util = {
sum(a, b) {
return a + b;
},
};
省略名称
上面的导出代码中,都明确指定了导出的变量名,这样其它人在导入使用时就必须准确写出 变量名,否则就会出错。 因此 js 提供了default
关键字,可以对导出的变量名进行省略
// 无需声明对象的名字
export default {
sum(a, b) {
return a + b;
},
};
这样,当使用者导入时,可以任意起名字
使用export
命令定义了模块的对外接口以后,其他 JS 文件就可以通过import
命令加载这 个模块。
import util from "hello.js";
// 调用 util 中的属性
util.sum(1, 2);
import {name, age} from 'user.js'
onsole.log(name)
//初始化
cnpm install -y
//安装vue
cnpm install vue@2
v-xx:指令
1、创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的
2、指令来简化对dom的一些操作。
3、声明方法来做更复杂的操作。methods里面可以封装方法。
在VUE中el,data和vue的作用:
el:用来绑定数据;
data:用来封装数据;
methods:用来封装方法,并且能够封装多个方法,如何上面封装了cancell和hello方法。
“v-html”不会对于HTML标签进行转义,而是直接在浏览器上显示data所设置的内容;而“ v-text”会对html标签进行转义
{{msg}} :称为差值表达式,它必须要写在Html表达式,可以完成数学运算和方法调用
<!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="./node_modules/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>我是{{name}}</h1> <button @click="num++">点赞</button> <button @click="cancle">取消</button> <h1>点赞次数:{{num}}</h1> <a :href="link">百度</a> <div> 精通的语言:<br> <input type="checkbox" v-model="language" value="Java" /> java<br /> <input type="checkbox" v-model="language" value="PHP" /> PHP<br /> <input type="checkbox" v-model="language" value="Python" /> Python<br /> 选中了 {{language.join(",")}} </div> </div> <script> let vm = new Vue({ el: "#app", data: { name: "大漂亮", num: 0, link: "http://www.baidu.com", language:[] }, methods: { cancle() { this.num = 0; }, }, }); </script> </body> </html>
v-on:click也可以写作@click
事件的冒泡:
<!-- 事件修饰符 -->
<div style="border: 1px solid red;padding: 20px;" v-on:click="hello">
大div
<div style="border: 1px solid blue;padding: 20px;" @click="hello">
小div <br />
<a href="http://www.baidu.com" @click.prevent="hello">去百度</a>
</div>
</div>
上面的这两个嵌套div中,如果点击了内层的div,则外层的div也会被触发;这种问题可以事件修饰符来完成:
<!-- 事件修饰符 -->
<div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello">
大div
<div style="border: 1px solid blue;padding: 20px;" @click.stop="hello">
小div <br />
<a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a>
<!--这里禁止了超链接的点击跳转操作,并且只会触发当前对象的操作-->
</div>
</div>
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。修饰符是由点开头的指令后缀来 表示的。
.stop
:阻止事件冒泡到父元素
.prevent
:阻止默认事件发生
.capture
:使用事件捕获模式
.self
:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
.once
:只执行一次
全部的按键别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
遍历的时候都加上:key来区分不同数据,提高vue渲染效率
<ul> <li v-for="(user,index) in users" :key="user.name" v-if="user.gender == '女'" > <!-- 1、显示user信息:v-for="item in items" --> 当前索引:{{index}} ==> {{user.name}} ==> {{user.gender}} ==>{{user.age}} <br /> <!-- 2、获取数组下标:v-for="(item,index) in items" --> <!-- 3、遍历对象: v-for="value in object" v-for="(value,key) in object" v-for="(value,key,index) in object" --> 对象信息: <span v-for="(v,k,i) in user">{{k}}=={{v}}=={{i}};</span> <!-- 4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率 --> </li> </ul>
<!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="./node_modules/vue/dist/vue.js"></script> </head> <body> <div id="app"> <ul> <li> 西游记:价格{{xyjPrice}},数量: <input type="number" v-model="xyjNum" /> </li> <li> 水浒传:价格{{shzPrice}},数量: <input type="number" v-model="shzNum" /> </li> <li>总价:{{totalPrice}}</li> {{msg}} </ul> </div> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { xyjPrice: 55.55, shzPrice: 66.66, xyjNum: 1, shzNum: 1, msg:"" }, // 计算属性 computed: { totalPrice() { return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum; }, }, // 监听属性 watch: { xyjNum(newVal, oldVal) { if (newVal >= 3) { this.msg = "西游记没有更多库存了"; this.xyjNum = 3; } else { this.msg = ""; } }, }, }); </script> </body> </html>
- | 管道符号:表示使用后面的过滤器处理前面的数据
<!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="./node_modules/vue/dist/vue.js"></script> </head> <body> <div id="app"> <ul> <li v-for="(item, index) in items" :key="index"> id:{{item.id}};姓名:{{item.name}};性别:{{item.gender | sexFilter}} 全局过滤器:{{item.gender | capitalize}} </li> </ul> </div> <script> // 在创建 Vue 实例之前全局定义过滤器 Vue.filter("capitalize", function (val) { if (val == 1) { return "男"; } else { return "女"; } }); let vm = new Vue({ el: "#app", data: { items: [ { id: 1, name: "zs", gender: 1 }, { id: 2, name: "lisi", gender: 0 }, ], }, // 局部过滤器 filters: { sexFilter(val) { if (val == 1) { return "男"; } else { return "女"; } }, }, }); </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <button v-on:click="count++">我被点击了 {{count}} 次</button> 全局组件<counter></counter> <counter></counter> <!-- 使用所定义的组件button-counter --> 局部组件<button-counter></button-counter> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> //1、全局声明注册一个组件 Vue.component("counter", { template: `<button v-on:click="count++">我被点击了 {{count}} 次</button>`, data() { return { count: 1 } } }); //2、局部声明一个组件 const buttonCounter = { template: `<button v-on:click="count++">我被点击了 {{count}} 次~~~</button>`, data() { return { count: 1 } } }; new Vue({ el: "#app", data: { count: 1 }, components: { //声明所定义的局部组件 'button-counter': buttonCounter } }) </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <span id="num">{{num}}</span> <button @click="num++">赞!</button> <h2>{{name}},有{{num}}个人点赞</h2> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> let app = new Vue({ el: "#app", data: { name: "张三", num: 100 }, methods: { show() { return this.name; }, add() { this.num++; } }, beforeCreate() { console.log("=========beforeCreate============="); console.log("数据模型未加载:" + this.name, this.num); console.log("方法未加载:" + this.show()); console.log("html模板未加载:" + document.getElementById("num")); }, created: function () { console.log("=========created============="); console.log("数据模型已加载:" + this.name, this.num); console.log("方法已加载:" + this.show()); console.log("html模板已加载:" + document.getElementById("num")); console.log("html模板未渲染:" + document.getElementById("num").innerText); }, beforeMount() { console.log("=========beforeMount============="); console.log("html模板未渲染:" + document.getElementById("num").innerText); }, mounted() { console.log("=========mounted============="); console.log("html模板已渲染:" + document.getElementById("num").innerText); }, beforeUpdate() { console.log("=========beforeUpdate============="); console.log("数据模型已更新:" + this.num); console.log("html模板未更新:" + document.getElementById("num").innerText); }, updated() { console.log("=========updated============="); console.log("数据模型已更新:" + this.num); console.log("html模板已更新:" + document.getElementById("num").innerText); } }); </script> </body> </html>
1、npm install webpack -g
全局安装 webpack
2、npm install -g @vue/cli-init
全局安装 vue 脚手架
3、初始化 vue 项目; vue init webpack appname
vue 脚手架使用 webpack 模板初始化一个 appname 项目
4、启动 vue 项目; 项目的 package.json 中有 scripts,代表我们能运行的命令
npm start = npm run dev
启动项目
npm run build
将项目打包
vue模板
文件–>首选项–>用户代码片段–>点击新建代码片段–取名 vue.json 确定
{ "生成 vue 模板": { "prefix": "vue", "body": [ "<template>", "<div></div>", "</template>", "", "<script>", "//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)", "//例如:import 《组件名称》 from '《组件路径》';", "", "export default {", "//import 引入的组件需要注入到对象中才能使用", "components: {},", "props: {},", "data() {", "//这里存放数据", "return {", "", "};", "},", "//计算属性 类似于 data 概念", "computed: {},", "//监控 data 中的数据变化", "watch: {},", "//方法集合", "methods: {", "", "},", "//生命周期 - 创建完成(可以访问当前 this 实例)", "created() {", "", "},", "//生命周期 - 挂载完成(可以访问 DOM 元素)", "mounted() {", "", "},", "beforeCreate() {}, //生命周期 - 创建之前", "beforeMount() {}, //生命周期 - 挂载之前", "beforeUpdate() {}, //生命周期 - 更新之前", "updated() {}, //生命周期 - 更新之后", "beforeDestroy() {}, //生命周期 - 销毁之前", "destroyed() {}, //生命周期 - 销毁完成", "activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发", "}", "</script>", "<style lang='scss' scoped>", "//@import url($3); 引入公共 css 类", "$4", "</style>" ], "description": "生成 vue 模板" } }
1、安装 element-ui: npm i element-ui
2、在 main.js 中引入 element-ui 就可以全局使用了。
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
3、将 App.vue 改为 element-ui 中的后台布局
4、添加测试路由、组件,测试跳转逻辑
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。