谷粒商城环境搭建
1.安装虚拟机virtualbox
virtualbox下载地址:https://mirror.tuna.tsinghua.edu.cn/help/virtualbox/
**步骤:
下载安装即可
2.安装vagrant
简介:vagrant可以根据镜像在virtualbox中快速创建虚拟机
vagrant下载地址:https://www.vagrantup.com/downloads.html
镜像仓库:https://app.vagrantup.com/boxes/search(可查看镜像名字)
中国镜像仓库:http://mirrors.ustc.edu.cn/centos-cloud/centos/6/vagrant/x86_64/images/
vagrant命令:https://www.jianshu.com/p/7e8f61376053
**步骤:
1.下载安装vagrant,cmd中输入vagrant -v查看是否安装成功
2.使用vagrant在virtualBox中安装linux虚拟机:
方式1:
初始化:vagrant init centos/7(根据镜像名字初始化,创建了一个vagrantfile文件)
启动:vagrant up(根据vagrantfile下载镜像,需要在有vagrantfile文件的目录下启动)
连接:vagrant ssh(whoami查看当前登录用户,exit退出连接)
关闭:在virtualbox中关闭虚拟机
再次启动:vagrant up
方式2:(推荐)
访问中科大镜像网下载.box文件:http://mirrors.ustc.edu.cn/centos-cloud/centos
根据box文件初始化centos7:vagrant box add centos7 CentOS-7-x86_64-Vagrant-2004_01.VirtualBox.box
初始化:vagrant init centos7
修改配置:编辑Vagrantfile文件,修改config.vm.box = "centos7"
启动:vagrant up
连接:vagrant ssh(可能出现vagrant@127.0.0.1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic). 错误)
异常解决:https://blog.csdn.net/ai_0922/article/details/106366521(权限问题)
2.1.配置虚拟网络
简介:
1.什么是端口转发:
配置好虚拟机后,默认情况下使用的是端口转发如下图,例如虚拟机中有一个mysql服务,需要在virtualbox中设置端口映射windows本机端口(本机2222映射->虚拟机22),才可以在windows中ssh连接虚拟机(127.0.0.1 2222)
缺点:需要配置很多映射端口
解决:使用虚拟网卡给虚拟机配置一个ip,使本机和虚拟机可以ping通
2.配置虚拟网络:
方法1:登录虚拟机,设置网卡
方法2:修改vagrantfile配置文件(因为虚拟机是根据这个配置文件启动的)
1.查看本机虚拟地址:ipconfig (192.168.56.1)
2.打开配置文件修改地址:config.vm.network "private_network", ip: "192.168.56.10"
3.重启vagrant reload(在virtualBox中重启无效)
4.验证:ip addr,互相ping
端口转发:
本机虚拟地址:
2.2.Xshell连接虚拟机
1.连接:vagrant ssh
2.切换:su root(密码:vagrant)
3.修改允许密码连接
vi /etc/ssh/sshd_config
PasswordAuthentication yes
i(编辑模式)
esc
:wq(保存退出)
reboot
4.xshell连接 192.168.56.10
账号密码:vagrant/vagrant
root/vagrant
5.切换root:su root
2.3.配置网关、DNS
修改网卡相关信息
1.ip addr查看哪个网卡使用了192.168.56.10 ip
查看结果是enth1使用
2.修改配置
cd /etc/sysconfig/network-scripts/
vi ifcfg-eth1
增加以下三行:
GATEWAY=192.168.56.1
DNS1=114.114.114.114
DNS2=8.8.8.8
3.重启网卡
service network restart
2.4.配置yum源加速
1.备份原yum源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
2.使用新yum源
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
3.生成缓存
yum makecache
4.安装
yum -y install wget
yum -y install unzip
3.安装docker
简介:
虚拟化容器技术,docker基于镜像秒级启动各种容器,每一种容器都是一个完整的运行环境(每一个容器可以看做一个完整的linux环境),容器之间相互隔离。
例如windows中的ghost,根据windwos镜像安装系统(镜像中可能包含其他软件,qq、wx)
docker利用各种镜像在linux中安装容器(可以根据一个镜像安装多个容器),例如根据mysql镜像多个mysql容器
docker build
docker pull
docker run
docker安装官方文档:https://docs.docker.com/engine/install/centos/(进入路径->developers->Docs->Guides->Get Docker->Docker for linux->Docker Engine->install->centOS )
镜像仓库:https://hub.docker.com
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-duRmcJug-1686883355978)(/1630247867023.png)]
**步骤:
1.Uninstall old versions(卸载旧版本):
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2.Set up the repository(安装相关依赖):
sudo yum install -y yum-utils
3.设置镜像地址(用于加速下载docker用,并非docker image镜像)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
异常:下载docker的镜像报错fastmirror
解决:
vi /etc/yum/pluginconf.d/fastestmirror.conf(修改 enable=1 为 enable=0)
vi /etc/yum.conf(修改 plugins=1 为 plugins=0)
yum clean all
rm -rf /var/cache/yum
yum makecache
4.安装docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
5、启动docker
设置开机自启:sudo systemctl enable docker
启动:sudo systemctl start docker
6、测试
docker -v
3.1.相关命令
1、查看已启动镜像:docker images
查看已运行容器:docker ps
2、查看所有镜像:docker images -a
3、启动docker:sudo systemctl start docker
4、虚拟机开机启动:sudo systemctl enable docker
5、设置自动启动容器:sudo docker update mysql --restart=always
6、启动已存在的容器或重启容器,例:
1)查看容器的id或name:docker ps -a
2)重启restart id或name【重启就代表启动了】:
docker restart 1b4671904bfa
docker restart mysql
7、终止容器:docker stop redis
8、删除容器:docker rm redis
9、进入容器的运行时环境
进入mysql:docker exec -it mysql /bin/bash
进入redis:docker exec -it redis redis-cli
进入redis:docker exec -it redis /bin/sh
whereis mysql
10、退出容器运行时环境:exit
11、虚拟机开机自动启动mysql:sudo docker update mysql --restart=always
3.2.配置镜像加速器
作用:下载docker image镜像加速
1.登录阿里云:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
2.镜像加速器->centos(依次执行以下命令)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.3.拉取mysql镜像启动容器
简介:https://hub.docker.com 镜像仓库
docker pull mysql: 拉取最新版本镜像
docker pull mysql:5.7 拉取指定版本镜像
navicat12安装:https://cloud.tencent.com/developer/article/1718099
由于找不到MSVCR120.dll,无法继续执行代码.重新安装程序可能会解决此问题:https://blog.csdn.net/burning1996/article/details/100315436
步骤:
1.拉取镜像:
sudu docker pull mysql:5.7
2.查看已拉取的镜像
docker images
3.启动一个容器
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/ib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
参数说明(下面提到的主机指的是虚拟机)
-p 3306:3306:将容器的3306端口映射到主机的3306端口
--name 当前启动的容器 设置名字
-v /mydata/mysql/conf:/etc/mysql:将配置文件夹挂载到主机
-v /mydata/mysql/log:/var/log/mysgl:将日志文件夹挂载到主机
-v /mydata/mysql/data:/var/ib/mysql/:将配置文件夹挂载到主机
-e MYSQL_ROOT_PASSWORD=root: 初始化root用户的密码
-d 后台启动
mysql:5.7: 该容器所使用的镜像
4、远程无法连接mysql【没有修改远程授权】https://blog.csdn.net/scarecrow__/article/details/81556845
解决:进入容器连接mysql修改授权
1)进入mysql容器:docker exec -it mysql /bin/bash
2)连入mysql:mysql -uroot -proot
3)查询:select host,user,plugin,authentication_string from mysql.user;
找到user为root的两列,
%:表示不限制ip的配置
localhost:表示本地连接的配置
plugin数据非mysql_native_password表示要修改密码
执行以下语句:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
5、远程无法连接mysql:修改root用户远程访问权限
“password”填写密码 root
grant all privileges on *.* to root@"%" identified by "password" with grant option;
6、修改mysql字符集
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
7、重启:docker restart mysql
8、虚拟机开机自动启动mysql容器
sudo docker update mysql --restart=always
正确授权配置:
3.4.拉取redis镜像启动容器
简介:
1.redis配置文件:https://raw.githubusercontent.com/redis/redis/6.0/redis.conf
步骤:
1.拉取镜像:docker pull redis
2.坑:使用-v命令挂载时,主机会把redis.conf当做目录创建,所以先将改文件创建好
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
开启redis持久化:
vi /mydata/redis/conf/redis.conf
appendonly yes
3.启动容器
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:该容器redis-server使用/etc/redis/redis.conf配置文件启动
4、自启动:sudo docker update redis --restart=always
docker restart redis
5、终止容器:docker stop redis
删除容器:docker rm redis
6、连接redis:
1)进入容器内部连接:
docker exec -it redis /bin/bash
redis-cli -p 6379
2)使用客户端连接:
docker exec -it redis redis-cli
3)外部windows可视化客户端连接6379端口
3.5.安装nps(内网穿透服务端)
https://ehang-io.github.io/nps
注意:
1.有云服务器且需要用到内网穿透的安装,有很多其他方案代替,例如花生壳
2.服务端需要安装在外网云服务器上
步骤:
1.拉取镜像
docker pull ffdfgdfg/nps
2.下载conf配置文件
https://hub.docker.com/r/ffdfgdfg/nps
3.conf文件夹移动到/mydata/nps
4.启动容器(以host模式启动,自动映射端口)
docker run -d --name nps --net=host \
-v /mydata/nps/conf:/conf ffdfgdfg/nps
5.自启动
sudo docker update nps --restart=always
6.重启
docker restart nps
3.6.安装npc(内网穿透客户端)
https://ehang-io.github.io/nps
注意:客户端需要安装在本地虚拟机环境
docker run -d --name npc --net=host \
-v /mydata/npc/conf:/conf \
ffdfgdfg/npc -server=<ip:port> -vkey=<密钥> -type=tcp
1.docker pull ffdfgdfg/npc
2.下载conf文件夹并解压,或前往项目主页自行下载(升级请忽略)
https://hub.docker.com/r/ffdfgdfg/nps
3.conf文件夹移动到/mydata/npc
4.启动
无配置文件:
docker run -d --name npc --net=host ffdfgdfg/npc
-server=<ip:port> -vkey=<web界面中显示的密钥> <以及一些其他参数>
配置文件:
docker run -d --name npc --net=host \
-v /mydata/npc/conf:/conf ffdfgdfg/npc -config=/conf/npc.conf
5.自启动
sudo docker update npc --restart=always
6.重启
docker restart npc
4.开发环境jdk、maven、idea、vscode
1.版本:
jdk1.8
maven3.5.4
2.配置maven阿里云镜像、并以jdk1.8编译
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>D:\java\apache\repository</localRepository>
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun Maven</name>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<!-- <url>http://maven.oschina.net/content/groups/public</url> -->
</mirror>
</mirrors>
<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>
</settings>
3.idea配置
配置maven + jdk
plugins下载lombok、mybatisx、AI
设置自动导入依赖
setting -> Editor -> general -> Auto Import -> Add + Optimize
4.vscode配置
下载: https://code.visualstudio.com/
安装插件:
Auto Close Tag
Auto Rename Tag
Chinese
ESLint
HTML CSS Support
HTML Snippets
JavaScript(ES6)
Live Server
open in browser
Vetur
5.git配置
步骤:
1.作者信息
用户名:git config --global user.name "WANZENGHUI"
邮箱:git config --global user.email "lemon_wan@aliyun.com"
2.配置ssh登录,不需要账号密码【使用gitee的账户名】
ssh-keygen -t rsa -C "lemon_wan@aliyun.com"【三次回车】
查看秘钥:(复制该秘钥)
cat ~/.ssh/id_rsa.pub【C:\Users\Administrator\.ssh\id_rsa.pub】
3.登录gitee/github -> 设置 -> ssh公钥 -> 将上一步复制内容粘贴在此处
4.测试
ssh -T git@github.com
6.安装nginx
1、调整虚拟机内存3G(free -m查看)
2、创建nginx文件夹
cd /mydata
mkdir nginx
3、随便启动一个nginx实例,只是为了复制出配置
docker run -p 80:80 --name nginx -d nginx:1.10
4、将nginx容器内的配置文件拷贝到当前目录(当前目录在/mydata,此处运行一下命令):
【别忘了后面的点】
docker container cp nginx:/etc/nginx .
5、终止原容器:docker stop nginx
6、删除原容器:docker rm nginx
7、修改当前nginx文件名字为conf:mv nginx conf
8、创建nginx文件夹:mkdir nginx
9、移动conf到nginx文件夹中:mv conf nginx/
10、创建新的nginx容器:
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
--privileged=true \
-d nginx:1.10
11、测试:
在html文件夹下创建index.html=》<h1>test</h1>
然后访问:192.168.56.10
12.自启动
sudo docker update nginx --restart=always
13.mkdir es
在es里面创建fenci.txt文件并且把词汇维护到里面去
项目搭建
坑:
1.idea2018用不了maven3.6,换成3.4
https://blog.csdn.net/weixin_39723544/article/details/101066414
主模块步骤:
1.创建git项目,登录gitee,如下图创建项目
2.打开idea,使用git拉取项目
New -> Project from version Control -> https://gitee.com/lemon_wan/gulimall.git
3.主项目pom文件:【可以先创建子模块,然后复制子模块的pom文件;模块名gulimall】
创建完主项目pom文件后,点击 加号(add maven project导入主模块pom文件)
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall</name>
<description>聚合服务</description>
<packaging>pom</packaging>
<modules>
<module>gulimall-coupon</module>
<module>gulimall-member</module>
<module>gulimall-order</module>
<module>gulimall-product</module>
<module>gulimall-ware</module>
</modules>
</project>
4.在配置忽视.gitignore之前,将所以得git弹出框都点取消
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
**/mvnw
**/mvnw.cmd
**/.mvn
**/target/
.idea
**/.gitignore
HELP.md
5.设置好.gitignore
设置好.gitignore后,将unversioned File加入版本控制 add to VCS
1.创建子项目
1.创建5个Spring Initializr子module,
Group:com.atguigu.gulimall
artifact:gulimall-coupon
gulimall-member
gulimall-order
gulimall-product
gulimall-ware
type:maven
description:
谷粒商城-优惠券服务【表:gulimall_sms】
谷粒商城-会员服务【表:gulimall_ums】
谷粒商城-订单服务【表:gulimall_oms】
谷粒商城-商品服务【表:gulimall_pms】
谷粒商城-仓储服务【表:gulimall_wms】
package:com.atguigu.gulimall.coupon
com.atguigu.gulimall.member
com.atguigu.gulimall.order
com.atguigu.gulimall.product
com.atguigu.gulimall.ware
//选择一个主配置文件pom当作是项目的配置文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall</name>
<description>聚合服务</description>
<packaging>pom</packaging>
<modules>
<module>gulimall-coupon</module>
<module>gulimall-member</module>
<module>gulimall-order</module>
<module>gulimall-product</module>
<module>gulimall-ware</module>
</modules>
</project>
更改.gitgnore
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
----
**/mvnw
**/mvnw.cmd
**/.mvn
**/target
.idea
**/.gitignore
选中需要导入的依赖:
Web:Spring Web
Spring Cloud Routing:OpenFeign
【注:project configuration files can be added:先不点,配置好.gitignore】
2.修改springboot+springcloud的版本,否则可能会报错
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
2.数据库初始化(powerdisigner)
简介:
使用powerdisigner根据数据库设计创建出建表语句
步骤:
database->generate Database->preview:可以预览所有表创建的sql语句,复制运行即可
3.后台管理系统-renren前后端
简介:
使用人人开源作为后台管理系统,git上搜索人人开源 然后克隆项目到本地
git clone https://gitee.com/renrenio/renren-fast-vue.git
git clone https://gitee.com/renrenio/renren-fast.git
3.1.renren-fast(后端)
1.clone到gulimall项目中,并删除.git文件,放在项目的文件夹下面
2.gulimall的pom文件配置该renren-fast模块
<module>renren-fast</module>
3.创建数据库gulimall-admin(基于db.mysql.sql文件)
4.修改配置文件
application-dev.yml
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.10:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root
然后就可以访问:http://localhost:8080/renren-fast/
3.2.renren-fast-vue(前端)
1.下载安装node.js
https://nodejs.org/en/【新版需要python环境】
https://nodejs.org/dist/【所有版本的镜像,可下载老师一致版本10.16.3】
检查:cmd-> node -v
2.管理员身份打开vs-code,并打开文件夹renren-fast-vue
【配置npm(类似maven,for JavaScript)】
在vs-code的控制台依次输入以下命令
2.1.安装python环境
方法一:
手动安装https://www.onlinedown.net/soft/1165640.htm
配置环境变量:D:\Program Files\python2.7
方法二:
npm install --global --production windows-build-tools
配置环境变量:D:\Program Files\python2.7
检查:输入命令python
2.2.以下命令不确定是否全部需要执行
npm config set registry http://registry.npm.taobao.org/
npm install cnpm -g --registry=https://registry.npm.taobao.org
cnpm install -g node-gyp
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
3.初始化项目
cnpm install
4.运行项目
cnpm run dev
异常:
如果cnpm install用不了,用管理员打开power shell,执行【下面前3条是针对cnpm不能使用的情况】
1、set-ExecutionPolicy RemoteSigne + 回车
2、A + 回车
3、删除node_modules文件夹
4、cnpm install
一些其他命令:
cnpm install --save-dev gulp-sass
cnpm install node-sass --save
npm rebuild node-sass
npm uninstall node-sass
解决bug:
https://blog.csdn.net/qq_42886417/article/details/103123659
https://www.cnblogs.com/Wilson6/p/12055389.html
http://quanzhan.applemei.com/webStack/TVRnMk13PT0=
最后是看这个解决的:https://www.jianshu.com/p/2823b2f04b82
4.创建公共模块gulimall-common
1.创建
new module->maven->artifactid:gulimall-common->module name:gulimall-common
2.各子模块引入common
<dependency>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
3.在common中加入公共依赖
<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!--Query用到StringUtils-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--R中用到的-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
4.拷贝renren-fast中下图所示类到common模块中
com.atguigu.common
exception
utils
xss
晚上回来改版本 springboot版本
5.逆向生成工具
步骤:
1.克隆代码到gulimall项目文件夹中
git clone https://gitee.com/renrenio/renren-generator.git
2.配置pom
<module>renren-generator</module>
3.application.yml
# mysql
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.10:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
4.修改generator.properties【重复5遍】
#代码生成器,配置信息
mainPath=com.atguigu
#包名
package=com.atguigu.gulimall
moduleName=product
#作者
author=wanzenghui
#Email
email=lemon_wan@aliyun.com
#表前缀(类名不会包含表前缀)【java bean会去掉表前缀创建bean类】
tablePrefix=pms_
5.修改generator生成模板
注释掉renren-generator -> resources -> template以下语句:【不使用shiro】
// import org.apache.shiro.authz.annotation.RequiresPermissions;
// @RequiresPermissions("${moduleName}:${pathName}:list")
6.运行,访问localhost,选中所有表,点击生成代码
每一个模块都这样修改运行一次
7.下载解压,将main文件整个拷贝到各模块中【重复5遍】
8.非必须:删掉各模块中controller中的shiro注解【如果在generator项目的模板中没有删除的话就需要做这一步骤】
ctrl + shift + R批量修改【使用SpringSecurity】
import org.apache.shiro.authz.annotation.RequiresPermissions;
@RequiresPermissions("product:attrattrgrouprelation:list")
@RequiresPermissions("product:attrattrgrouprelation:info")
@RequiresPermissions("product:attrattrgrouprelation:save")
@RequiresPermissions("product:attrattrgrouprelation:update")
@RequiresPermissions("product:attrattrgrouprelation:delete")
@RequiresPermissions("product:attr:list")
@RequiresPermissions("product:attr:info")
@RequiresPermissions("product:attr:save")
@RequiresPermissions("product:attr:update")
@RequiresPermissions("product:attr:delete")
...
9.删除生成的vue代码
6.整合mybatisplus
版本映射:
步骤:
1、整合mybatis-plus
1)common模块导入依赖
<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
2)代码层面整合,参照文档:https://mp.baomidou.com/guide/config.html
1、配置数据源
1)导入数据库驱动依赖【要跟数据库版本一致,我的是5.7.31】
官方文档,版本对应:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html
在common模块导入依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
2)在product中创建application.yml
spring:
datasource:
username: root
password: root
url: jdbc:mysql://192.168.56.10:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
2、配置mybatis-plus
1)在product模块的Application类上@MapperScan("com.atguigu.gulimall.product.dao")
【如果Dao类上配置了@Repository可以不配】
2)告诉mybatis-plus,sql映射文件xml的位置,
在yml中配置,classpath*表示不止扫描自己的类路径,还扫描依赖的jar包的类路径
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
3)设置主键的类型是自增的,默认是NONE,不是自增
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
6.1.逻辑删除
方案一:全局配置
1)配置相关逻辑删除规则
2)配置相关组件(3.1.2后可省略)
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
-- logic-delete-field: showStatus # 全局逻辑删除的实体字段名【注:这个不要配置,否则整个服务都配置上了】
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
方案二:
/**
* 该值会覆盖全局配置
*/
@TableLogic(value = "1", delval = "0")//value:默认逻辑未删除值;delval:默认逻辑删除值
private Integer showStatus;
7.配置各子模块(端口占用)
1.各子模块端口配置【coupon:7000、member:8000、order:9000、product:10000、ware:11000】
server:
port: 7000
2.启动所有服务(如果出现端口占用以下命令解决)
netstat -ano 查出端口对应的进程ID=》PID,打开控制台关闭
netstat -ano|findstr "13048" 找到对应的进程,在任务管理器里面关闭进程
3.测试接口
localhost:7000/coupon/coupon/list
4.测试持久层
@RunWith(SpringRunner.class)
@SpringBootTest
class GulimallProductApplicationTests {
@Autowired
BrandService brandService;
@Test
void contextLoads() {
BrandEntity entity = new BrandEntity();
entity.setName("华为");
boolean save = brandService.save(entity);
System.out.println("保存成功:" + save);
}
// 查询条件Wrapper,brand_id = 1的,链式编程拼接多个条件
@Test
void queryPage() {
//brandService.queryPage()
List<BrandEntity> list = brandService.list(new QueryWrapper<BrandEntity>().eq("brand_id", 1L));
list.forEach((item)->{
System.out.println(item);
});
}
}
8.日志级别
日志级别使用debug,控制台打印sql语句
logging:
level:
com.atguigu.gulimall: debug
分布式环境搭建
搭配方案
注册中心(服务发现/注册):SpringCloud Alibaba - Nacos【代替Eureka、config】
配置中心(动态配置管理):SpringCloud Alibaba - Nacos
负载均衡:SpringCloud - Ribbon【】
声明式HTTP客户端(调用远程服务):SpringCloud - OpenFeign【代替Feign】
服务容错(限流、降级、熔断):SpringCloud Alibaba - Sentinel【代替Hystrix】
网关:SpringCloud - GateWay【webflux编程模式,代替zuul】
调用链监控:SpringCloud - Sleuth
分布式事务解决方案:SpringCloud Alibaba - Seata【原Fescar】
SpringCloud Alibaba文档:
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies?__cf_chl_tk=ZJXGWmW6mSDwmmgZlkMrWCYcBbmljuMwHRjIAThLN3E-1670480605-0-gaNycGzNDD0
1.spring-cloud-alibaba依赖
在common模块配置依赖:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
对于springboot2.7.6而言
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.Nacos服务注册发现
nacos——demo:
https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md
1.在common模块配置依赖:
<!--服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
//亲自做了的效果需要加版本号才可以
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2.下载服务端
https://github.com/alibaba/nacos/releases/tag/1.3.1
下载完成运行 startup.cmd
3.在各子模块添加nacos服务端ip+port,并配置各模块服务名【不配置名字nacos服务端服务列表不会显示】
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: gulimall-coupon
4.各模块启动类配置注解,作为客户端
@EnableDiscoveryClient
5.查看注册情况【账号/密码:nacos/nacos】
http://127.0.0.1:8848/nacos
3.OpenFeign声明式远程调用
简介:
Feign是一个声明式的HTTP客户端,目的就是让远程调用更加简单
Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息
Feign整合了Ribbon (负载均衡)和Hystrix(服务熔断),可以让我们不再需要显式地使用这两个组件。
流程:
1.启动类加上两个注解【1.添加当前项目到注册中心;2.开启远程调用】
2.@FeignClient定义被调用服务名
3.feign从注册中心拉取服务
4.负载均衡找到真正的ip+port
5.搭配方法上@RequestMapping指定的请求路径访问指定controller
步骤:
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.增加接口测试类
package com.atguigu.gulimall.member.feign;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
}
3.开启远程调用,调用方Application主类上添加注解(spring启动后会扫描此包下的所有@FeignClient修饰的接口)
@EnableFeignClients(basePackages="com.atguigu.gulimall.member.feign")
4.coupon模块增加测试接口
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@RequestMapping("/member/list")
public R membercoupons() {
CouponEntity entity = new CouponEntity();
entity.setCouponName("满100减10");
return R.ok().put("coupons", Arrays.asList(entity));
}
}
5.CouponFeignService增加远程调用方法
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
/**
* 测试openFeign
*/
@RequestMapping("/coupon/coupon/member/list")
public R membercoupons();
}
6.member增加测试请求
@RestController
@RequestMapping("member/member")
public class MemberController {
@Autowired
private MemberService memberService;
@Autowired
private CouponFeignService couponFeignService;
/**
* openFeign测试接口
*/
@RequestMapping("/coupons")
public R test() {
MemberEntity entity = new MemberEntity();
entity.setNickname("张三");
R membercoupons = couponFeignService.membercoupons();
Object coupons = membercoupons.get("coupons");
return R.ok().put("member", entity).put("coupons", coupons);
}
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!出错点应该!!!!!!!!!!!!!!!!!!!!!!!!
SpringCloud Feign在Hoxton.M2 RELEASED版本之后不再使用ribbon而是使用spring-cloud-loadbalancer,所以在不引入spring-cloud-loadbalancer情况下会报错
<!-- 负载均衡-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.0.3</version>
</dependency>
!!!!!!!!!!错误:org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose!!!!!!!!!
原文链接:https://blog.csdn.net/qq_52476654/article/details/125692501
主要原因是还是jar包冲突,nacos依赖的ribbon和springcloud的ribbon存在同个方法的不同实现,不兼容。
排除掉nacos的spring-cloud-starter-netflix-ribbon依赖:
1.<!-- nacos discovery starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflex-ribbon</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflex-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
2.排除调nacos里面的ribbon
Maven: org.springframework.cloud:spring-cloud-netflix-ribbon:2.2.10.RELEASE
Maven: org.springframework.cloud; spring-cloud-starter-netflix-ribbon:2.2.10.RELEASE
原文链接:https://blog.csdn.net/weixin_44592837/article/details/125005325
7.访问测试请求
http://localhost:8000/member/member/coupons
4.Nacos Config配置管理
简介:
demo:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md
不使用配置管理的劣势:集群环境下需要修改配置后打包多份发布
优势:不用重新打包+发布,可以动态刷新配置,由nacos服务端来发布
使用方式
1.引入依赖
<!--服务的配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2.创建一个bootstrap.properties
添加配置项地址
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
3.点击配置导入,给配置中心添加一个(Data Id)gulimall-coupon.properties。默认规则:应用名.properties
4.给应用名.properties 添加任何配置
5.动态获取配置
@RefreshScope 加在控制层里面
@Value 获取到配置文件里面的值
规则:如果当前配置application.properties里面配置了东西优先加载nacos配置中心里面的配置
在日志的这个地方将服务名写进配置:Ignore the empty nacos configuration and get it based on dataId[gulimall-coupon.properties] & group[DEFAULT_GROUP]
注意:
<!--springboot 2.4以上需要加上这个依赖bootstrap才可以生效-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.0</version>
</dependency>
1)命名空间:配置隔离;【默认使用public(保留空间)】默认新增的所有配置都在public空间里面
1.比如说:开发,测试,生产:利用命名空间做,基于环境隔离
2.也可以对于每一个微服务进行命名,创建每一个微服务的命名空间,只加载自己命名空间的所有配置,基于微服务隔离
使用:以模块来区分命名空间【各模块使用自己的命名空间】
注意:在bootstrap.properties;配置使用的命名空间,配置命名空间的唯一id
spring.cloud.nacos.config.namespace=81b480b2-f3b7-4251-849d-e18056e79e0e
2)配置分组:
默认:所有配置属于DEFAULT_GROUP组
在bootstrap.properties里面添加
spring.cloud.nacos.config.group=维护的配置组名(DEFAULT_GROUP)
3)配置ID:类似文件名【默认 服务名.properties】
默认:gulimall-product.properties
4)配置集:指的是一组配置文件共同生效,拆分gulimall-product.properties内的配置放在不同的配置文件中
注意:【属性名相同的配置以gulimall-product.properties为主】
mybatis.yml
datasource.yml
other.yml
spring.application.name=gulimall-product
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=95c36bd7-fd1a-4914-a8d8-7a64fa889258
spring.cloud.nacos.config.group=维护的配置组名(DEFAULT_GROUP)加载默认配置文件的时候进行默认的分组
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml 具体的哪一个配置
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.yml 具体的哪一个配置
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.yml 具体的哪一个配置
spring.cloud.nacos.config.extension-configs[2].group=dev 具体的哪一个分组
spring.cloud.nacos.config.extension-configs[2].refresh=true 配置中心这个配置改掉过后该微服务是否需要刷新配置
控制台会自动展示出那些配置被读取了,gulimall-product.properties这个配置文件是会被自动读取!
【本项目的使用规则】:以每一个微服务来划分 (coupon)命名空间,以dev,test,prod来划分配置分组
同时加载很多个配置
1.微服务的所有配置都可以放在配置中心中。
2.只需要在bootstrap.properties说明加载配置中心中的哪些配置文件即可
@value,@ConfigurationProperties。。。。
以前springboot任何方法从配置文件中获取值都能使用,配置中心优先使用配置中心中的
步骤:
1.在common模块中导入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
访问127.0.0.1:8848/nacos完成以下新增动作
2.新建命名空间:product
3.选中命名空间product,新增配置集并指定分组dev【属性名相同的配置以gulimall-product.properties为主】
Data ID:mybatis.yml
Group:dev
Data ID:datasource.yml
Group:dev
Data ID:spring.yml
Group:dev
4.新增配置文件:/src/main/resources/bootstrap.properties【会比application.properties先被加载】
1.指定Nacos配置中心的server-addr
2.指定当前服务服务名【否则不会在注册中心中显示】
3.指定命名空间【未指定,使用默认public】
4.指定分组【未指定,使用默认DEFAULT_GROUPS Data Id=gulimall-coupon的文件】
5.开启热发布热加载【默认开启】
6.指定配置集【多个yml】
spring.application.name=gulimall-product
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=95c36bd7-fd1a-4914-a8d8-7a64fa889258
spring.cloud.nacos.config.group=dev
#如果这个dev不放开的话,默认的gulimall-coupon不生效【会加载dev分组下的所有配置】
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
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.yml
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=spring.yml
spring.cloud.nacos.config.extension-configs[2].group=dev
spring.cloud.nacos.config.extension-configs[2].refresh=true
5.在需要热加载的配置类上添加注解
@RefreshScope【加入该注解后,使用@Value获取值会以热加载形式加载】
新建配置:
5.Gateway网关
简介:
路由:将访问网关的url转换为正确的ip+port(集群),并且能感知服务的上线和熔断【否则需要在前端来改端口+ip】
过滤
监控
鉴权
限流
日志输出,避免各模块重复代码
springcloud Gateway比zuul(Netflix)更优秀
doc文档,查看GA稳定版
https://docs.spring.io/spring-cloud-gateway/docs/2.2.4.RELEASE/reference/html/
中文文档:https://www.springcloud.cc/spring-cloud-greenwich.html#gateway-starter
gateway网关三个概念:【断言成功后跳转路由指定url】
路由:路由之间通过ID区分 + 一个目的地URI + 断言集合组成 + 过滤器
断言:条件判断,根据请求参数/请求头等进行判断,为true通过【查看官方文档有哪些断言】(经过一些的条件判断你这个请求需要发送或者链接到哪个url或者说是服务)
过滤器:请求之前/响应之后 可以进行过滤,【查看官方文档有哪些过滤器】
各模块之间关系:
每秒处理请求次数:
网关处理过程:
**demo1:**当前请求是否在某时间之后
**demo2:**过滤器,在请求头添加参数 key:X-Request-Foo,value:Bar
步骤:
1.创建Spring Init网关模块,添加网关依赖
com.atguigu.gulimall
gulimall-gateway
com.atguigu.gulimall.gateway
2.将gateway的springboot版本改成一致的版本
将gateway的springcloud版本改成一致的版本
gateway模块添加common依赖
3.maven中添加对common的依赖,并且在主pom里添加网关模块
<module>gulimall-gateway</module>
4.在Application加上注解
@EnableDiscoveryClient
5.配置注册中心的地址application.yml
server:
port: 88
spring:
application:
name: gulimall-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
6.配置中心的地址bootstrap.properties
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
7.启动异常:Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
解决:方法1、移除mybatis相关依赖
<dependency>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
方法2、移除DataSourceAutoConfiguration【加载Application类上】
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
8.实现以下要求:
127.0.0.1:88/hello?url=test1 跳转https://www.cnblogs.com/wu-song/p/7929595.html
server:
port: 88
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: test1_route
uri: https://www.cnblogs.com/wu-song/p/7929595.html
predicates:
- Query=url,test1
前端环境
ES6
简介:
前端语言的规范,每年都会出一个新标准ECMAScript 2018->ES9
ES6:语法新特性【重点】
Node.js:npm包管理工具,相当于maven
Vue:相当于springmvc【重点】
Babel:是一个javascript编译器,自动转换为浏览器兼容的代码
webpack:自动化项目构建工具,gulp也是同类产品
步骤:
1、打开vscode,打开文件夹->新建文件夹->es6
2、新建文件let.html,shift+!回车快速生成HTML文档
3、右键 open with live server【浏览器查看】
let&&const
var在{}之外也起作用
let在{}之外不起作用
var多次声明同一变量不会报错,let多次声明会报错,只能声明一次。
var 会变量提升(打印和定义可以顺序反)。let 不存在变量提升(顺序不能反)
const声明之后不允许改变
<!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>
<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;
// const
// 1. const声明之后不允许改变
// 2. 一但声明必须初始化,否则会报错
const a = 1;
a = 3; //Uncaught TypeError: Assignment to constant variable.
</script>
</body>
</html>
解构表达式
支持let arr = [1,2,3]; let [a,b,c] = arr;这种语法
支持对象解析:const { name: abc, age, language } = person; 冒号代表改名
字符串函数
支持一个字符串为多行
占位符功能 ${}
<!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>
<script>
//数组解构
// let arr = [1,2,3];
// // let a = arr[0];
// // let b = arr[1];
// // let c = arr[2];
// let [a,b,c] = arr;
// console.log(a,b,c)
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
// const name = person.name;
// const age = person.age;
// const language = person.language;
//对象解构
const { name: abc, age, language } = person;
console.log(abc, age, language)
// 字符串扩展
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
//字符串模板
let ss = `<div>
<span>hello world<span>
</div>`;
console.log(ss);
// 字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。
function fun() {
return "这是一个函数"
}
let info = `我是${abc},今年${age + 10}了, 我想说: ${fun()}`;
console.log(info);
</script>
</body>
</html>
函数优化
原来想要函数默认值得这么写b = b || 1; 现在可以直接写了function add2(a, b = 1) {
函数不定参数function fun(...values) {
支持箭头函数(lambda表达式),还支持使用{}结构传入对象的成员
<!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>
<script>
//在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(20));
//不定参数
function fun(...values) {
console.log(values.length)
}
fun(1, 2) //2
fun(1, 2, 3, 4) //4
//箭头函数
//以前声明一个方法
// var print = function (obj) {
// console.log(obj);
// }
var print = obj => console.log(obj);
print("hello");
var sum = function (a, b) {
c = a + b;
return a + c;
}
var sum2 = (a, b) => a + b;
console.log(sum2(11, 12));
var sum3 = (a, b) => {
c = a + b;
return a + c;
}
console.log(sum3(10, 20))
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);
</script>
</body>
</html>
对象优化
可以获取map的键值对等Object.keys()、values、entries
Object.assgn(target,source1,source2) 合并
const person2 = { age, name } //声明对象简写
…代表取出该对象所有属性拷贝到当前对象。let someone = { …p1 }
<!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>
<script>
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 };
//{a:1,b:2,c:3}
Object.assign(target, source1, source2);
console.log(target);//["name", "age", "language"]
// 声明对象简写
const age = 23
const name = "张三"
const person1 = { age: age, name: name }
const person2 = { age, name }//声明对象简写
console.log(person2);
// 对象的函数属性简写
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("橘子");
// 对象拓展运算符
// 拷贝对象(深拷贝)
let p1 = { name: "Amy", age: 15 }
let someone = { ...p1 }
console.log(someone) //{name: "Amy", age: 15}
// 合并对象
let age1 = { age: 15 }
let name1 = { name: "Amy" }
let p2 = {name:"zhangsan"}
p2 = { ...age1, ...name1 }
console.log(p2)
</script>
</body>
</html>
map和reduce
<!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>
<script>
//数组中新增了map和reduce方法。
//map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
let arr = ['1', '20', '-5', '3'];
// arr = arr.map((item)=>{
// return item*2
// });
arr = arr.map(item=> item*2);
console.log(arr);
//reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,
//[2, 40, -10, 6]
//arr.reduce(callback,[initialValue])
/**
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)*/
let result = arr.reduce((a,b)=>{
console.log("上一次处理后:"+a);
console.log("当前正在处理:"+b);
return a + b;
},100);
console.log(result)
</script>
</body>
</html>
promise
以前嵌套ajax的时候很繁琐。
解决方案:
把Ajax封装到Promise中,赋值给let p
在Ajax中成功使用resolve(data),交给then处理,
失败使用reject(err),交给catch处理p.then().catch()
corse_score_10.json 得分
{
"id": 100,
"score": 90
}
user.json 用户
{
"id": 1,
"name": "zhangsan",
"password": "123456"
}
user_corse_1.json 课程
{
"id": 10,
"name": "chinese"
}
<!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>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<script>
//1、查出当前用户信息
//2、按照当前用户的id查出他的课程
//3、按照当前课程id查出分数
// $.ajax({
// url: "mock/user.json",
// success(data) {
// console.log("查询用户:", data);
// $.ajax({
// url: `mock/user_corse_${data.id}.json`,
// success(data) {
// console.log("查询到课程:", data);
// $.ajax({
// url: `mock/corse_score_${data.id}.json`,
// success(data) {
// console.log("查询到分数:", data);
// },
// error(error) {
// console.log("出现异常了:" + error);
// }
// });
// },
// error(error) {
// console.log("出现异常了:" + error);
// }
// });
// },
// error(error) {
// console.log("出现异常了:" + error);
// }
// });
//1、Promise可以封装异步操作
// let p = new Promise((resolve, reject) => { //传入成功解析,失败拒绝
// //1、异步操作
// $.ajax({
// url: "mock/user.json",
// success: function (data) {
// console.log("查询用户成功:", data)
// resolve(data);
// },
// error: function (err) {
// reject(err);
// }
// });
// });
// p.then((obj) => { //成功以后做什么
// return new Promise((resolve, reject) => {
// $.ajax({
// url: `mock/user_corse_${obj.id}.json`,
// success: function (data) {
// console.log("查询用户课程成功:", data)
// resolve(data);
// },
// error: function (err) {
// reject(err)
// }
// });
// })
// }).then((data) => { //成功以后干什么
// console.log("上一步的结果", data)
// $.ajax({
// url: `mock/corse_score_${data.id}.json`,
// success: function (data) {
// console.log("查询课程得分成功:", data)
// },
// error: function (err) {
// }
// });
// })
function get(url, data) { //自己定义一个方法整合一下
return new Promise((resolve, reject) => {
$.ajax({
url: url,
data: data,
success: function (data) {
resolve(data);
},
error: function (err) {
reject(err)
}
})
});
}
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((err)=>{ //失败的话catch
console.log("出现异常",err)
});
</script>
</body>
</html>
模块化
模块化就是把代码进行拆分,方便重复利用。类似于java中的导包,
而JS换了个概念,是导模块。
模块功能主要有两个命令构成 export 和import
export用于规定模块的对外接口
import用于导入其他模块提供的功能
user.js
var name = "jack"
var age = 21
function add(a,b){
return a + b;
}
export {name,age,add}
hello.js
// export const util = {
// sum(a, b) {
// return a + b;
// }
// }
export default {
sum(a, b) {
return a + b;
}
}
// export {util}
//`export`不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象。
main.js
import abc from "./hello.js"
import {name,add} from "./user.js"
abc.sum(1,2);
console.log(name);
add(1,3);
Vue
MVVM思想
MVVM思想
M:model 包括数据和一些基本操作
V:view 视图,页面渲染结果
VM:View-model,模型与视图间的双向操作(无需开发人员干涉)
视图和数据通过VM绑定起来,model里有变化会自动地通过Directives填写到视view中,
视图表单中添加了内容也会自动地通过DOM Listeners保存到模型中。
基础案例
在VSCode中安装vue 2 snippets语法提示插件,在谷歌浏览器中安装vue.js devtools
npm init -y
npm install vue
<!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">
<input type="text" v-model="num">
v-model实现双向绑定
<button v-on:click="num++">点赞</button>
v-on:click绑定事件,实现自增
<button v-on:click="cancel">取消</button>
回到自定义的方法
<h1> {{name}} ,非常帅,有{{num}}个人为他点赞{{hello()}}</h1>
</div>
<!-- 导入依赖 -->
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//1、vue声明式渲染
let vm = new Vue({ //生成vue对象
el: "#app",//绑定元素 div id="app"
data: { //封装数据
name: "张三", // 也可以使用{} //表单中可以取出
num: 1
},
methods:{ //封装方法
cancel(){
this.num -- ;
},
hello(){
return "1"
}
}
});
还可以在html控制台vm.name
//2、双向绑定,模型变化,视图变化。反之亦然。
//3、事件处理
//v-xx:指令
//1、创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的
//2、指令来简化对dom的一些操作。
//3、声明方法来做更复杂的操作。methods里面可以封装方法。
</script>
</body>
</html>
v-text、v-html.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">
{{msg}} {{1+1}} {{hello()}}<br/>
用v-html取内容
<span v-html="msg"></span>
<br/>
原样显示
<span v-text="msg"></span>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
msg:"<h1>Hello</h1>",
link:"http://www.baidu.com"
},
methods:{
hello(){
return "World"
}
}
})
</script>
</body>
</html>
插值表达式
花括号:只能写在标签体内,不能用在标签内。用v-bind解决
{{}}必须有返回值
单向绑定v-bind
<!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>
<!-- 给html标签的属性绑定 -->
<div id="app">
<a v-bind:href="link">gogogo</a>
<!-- class,style {class名:加上?}-->
<span v-bind:class="{active:isActive,'text-danger':hasError}"
:style="{color: color1,fontSize: size}">你好</span>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
link: "http://www.baidu.com",
isActive:true,
hasError:true,
color1:'red',
size:'36px'
}
})
</script>
</body>
</html>
双向绑定v-model
<!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">
精通的语言:
<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>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
language: []
}
})
</script>
</body>
</html>
v-on
<!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">
<!--事件中直接写js片段-->
<button v-on:click="num++">点赞</button>
<!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
<button @click="cancel">取消</button>
<!-- -->
<h1>有{{num}}个赞</h1>
<!-- 事件修饰符 -->
<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>
<!-- 按键修饰符: -->
<input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2" @click.ctrl="num=10"><br />
提示:
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
num: 1
},
methods:{
cancel(){
this.num--;
},
hello(){
alert("点击了")
}
}
})
</script>
</body>
</html>
v-for
<!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">
<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>
<ul>
<li v-for="(num,index) in nums" :key="index"></li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
users: [{ name: '柳岩', gender: '女', age: 21 },
{ name: '张三', gender: '男', age: 18 },
{ name: '范冰冰', gender: '女', age: 24 },
{ name: '刘亦菲', gender: '女', age: 18 },
{ name: '古力娜扎', gender: '女', age: 25 }],
nums: [1,2,3,4,4]
},
})
</script>
</body>
</html>
v-if和v-show
<!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>
<!--
v-if,顾名思义,条件判断。当得到结果为true时,所在的元素才会被渲染。
v-show,当得到结果为true时,所在的元素才会被显示。
-->
<div id="app">
<button v-on:click="show = !show">点我呀</button>
<!-- 1、使用v-if显示 -->
<h1 v-if="show">if=看到我....</h1>
<!-- 2、使用v-show显示 -->
<h1 v-show="show">show=看到我</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
show: true
}
})
</script>
</body>
</html>
v-else和v-else-if
<!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="random=Math.random()">点我呀</button>
<span>{{random}}</span>
<h1 v-if="random>=0.75">
看到我啦?! >= 0.75
</h1>
<h1 v-else-if="random>=0.5">
看到我啦?! >= 0.5
</h1>
<h1 v-else-if="random>=0.2">
看到我啦?! >= 0.2
</h1>
<h1 v-else>
看到我啦?! < 0.2
</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: { random: 1 }
})
</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">
<!-- 某些结果是基于之前数据实时计算出来的,我们可以利用计算属性。来完成 -->
<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 src="../node_modules/vue/dist/vue.js"></script>
<script>
//watch可以让我们监控一个值的变化。从而做出相应的反应。
new Vue({
el: "#app",
data: {
xyjPrice: 99.98,
shzPrice: 98.00,
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 name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 -->
<div id="app">
<ul>
<li v-for="user in userList">
{{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==>
{{user.gender | genderFilter}} ==> {{user.gender | gFilter}}
</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
Vue.filter("gFilter", function (val) {
if (val == 1) {
return "男~~~";
} else {
return "女~~~";
}
})
let vm = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
},
filters: {
filters 定义局部过滤器,只可以在当前vue实例中使用
genderFilter(val) {
if (val == 1) {
return "男";
} else {
return "女";
}
}
}
})
</script>
</body>
</html>
组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相
同的部分。
例如可能会有相同的头部导航。
但是如果每个页面都自开发,这无疑增加了我们开发的成本。所以我们会把页面
的不同分拆分成立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
在vue里,所有的vue实例都是组件
组件其实也是一个vue实例,因此它在定义时也会接收:data、methods、生命周期函等
不同的是组件不会与页面的元素綁定,否则就无法复用了,因此没有el属性。
但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组了
data必须是一个函数,不再是一个对象。
<!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>
<counter></counter>
<counter></counter>
<counter></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>
使用Vue脚手架进行开发
全局安装webpack
1 npm install webpack -g
全局安装vue脚手架
2 npm install -g @vue/cli-init
3 初始化vue项目
vue init webpack appname:vue脚手架使用webpack模板初始化一个appname项目
4 启动vue项目
项目的package.json中有scripts,代表我们能运行的命令
npm start = npm run dev: 启动项目
npm run build:将项目打包
使用element-ui
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
npm i element-ui -S
在 main.js 中写入以下内容:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
1.安装vue
准备工作:
1、安装文档。我们选用npm安装:https://cn.vuejs.org/v2/guide/installation.html#NPM
创建一个vue2文件夹
npm init -y【表示该项目是npm管理】
2、安装最新稳定版
npm install vue
3、创建index.html,引入vue.js
<script src="./node_modules/vue/dist/vue.js"></script>
4、在VS CODE中安装Vue 2 Snippets语法提示 插件
5、在浏览器中安装一个 vue工具包【https://www.jianshu.com/p/79eefcc5418f】
Vue-Devtools.zip 解压,google浏览器 更多工具-》扩展程序-》开发者模式-》加载已解压的扩展程序
作用:检查vue实例的data数据
C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\nhdogjmejiglipccpnnnanhbledajbpd\5.3.4_0,修改"persistent": true,
2.安装webpack模板
1、全局安装webpack【能把项目打包】
npm install webpack -g
细节:cmd右键取消快速编辑模式
2、安装vue脚手架【模块化项目】
npm install -g @vue/cli-init【后面init 失败,选择下面一条语句成功】
解决方法一:cnpm install -g vue-cli
解决方法二:https://blog.csdn.net/zhumizhumi/article/details/89875666
查找vue.cmd,将文件夹添加到环境变量Path中
3、vue脚手架初始化一个叫vue-demo以webpack为模板的应用
vue init webpack vue-demo【https://www.cnblogs.com/yuesebote/p/13750140.html】
3.安装elemnet-ui
https://element.eleme.cn/#/zh-CN/component/installation
1.npm i element-ui -s
ES全文检索
1.安装ES
1、下载镜像文件
docker pull elasticsearch:7.4.2
2、创建目录,作为挂载目录
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
3.允许任何ip访问
命令含义解释:将配置写入elasticsearch.yml文件中
echo "http.host:0.0.0.0">> /mydata/elasticsearch/config/elasticsearch.yml
4.打开9200端口
firewall-cmd --add-port=9200/tcp --permanent
root用户下关闭防火墙:centos6:chkconfig iptables off
centos7:systemctl stop firewalld.service
5.解决BUG,elasticsearch自动关闭
docker logs elasticsearch【查看日志,data文件夹权限不够】
docker logs cb8【查看日志,使用id查看】
修改其他用户权限也是 rwx
解决:chmod -R 777 /mydata/elasticsearch/【-R递归修改任何组任何角色都是rwx】
6.根据镜像启动一个容器
1)容器名字,暴露两个端口。9200:HTTP请求,9300:分布式集群下各节点通信端口
2)单节点运行
3)指定内存,默认占用所有
4)挂载 -v,可以直接在容器外部修改配置,装插件
5)-d使用镜像: elasticsearch:7.4.2
docker run --name elasticsearch -p 9200:9200 -p9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
--privileged=true \
-d elasticsearch:7.4.2
7.自动启动
docker update elasticsearch --restart=always
8.重启
docker restart elasticsearch
http://192.168.245.124:9200/
1.1.指定一个更大内存的es
注:
移除老的容器数据不会遗失,因为挂载了本地目录,当启动新的容器时挂在到相同目录下即可
1.停止已启动的es容器
docker stop elasticsearch
2.删除容器
docker rm elasticsearch
2、创建目录,作为挂载目录
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
3.允许任何ip访问
命令含义解释:将配置写入elasticsearch.yml文件中
echo "http.host: 0.0.0.0">> /mydata/elasticsearch/config/elasticsearch.yml
4.打开9200端口
firewall-cmd --add-port=9200/tcp --permanent
root用户下关闭防火墙:centos6:chkconfig iptables off
centos7:systemctl stop firewalld.service
解决:chmod -R 777 /mydata/elasticsearch/【-R递归修改任何组任何角色都是rwx】
3.启动新容器,分配512M内存
docker run --name elasticsearch -p 9200:9200 -p9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
--privileged=true \
-d elasticsearch:7.4.2
4.自动启动
docker update elasticsearch --restart=always
5.重启
docker restart elasticsearch
2.安装Kibana(可视化检索数据)
1、下载镜像文件
docker pull kibana:7.4.2
2.根据镜像启动一个容器
1)-e elasticsearch.url 表示设置启动参数,主机地址
2)-p 端口映射
3)-d 使用的镜像
docker run --name kibana -e ELASTICSEARCH_URL=http://192.168.245.124:9200 -p 5601:5601 \
-d kibana:7.4.2
【步骤2正确语句写法:以上写法是为了演示步骤4解决异常
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 \
-d kibana:7.4.2】
3.访问192.168.56.10:5601
Kibana server is not ready yet
4.解决异常【docker run语句】
1)docker logs 容器ID
2)docker exec -it kibana /bin/bash
3)vi /usr/share/kibana/config/kibana.yml
修改 elasticsearch.hosts: [ "http://192.168.56.10:9200" ]
5.修改kibana为中文
1)docker exec -it kibana /bin/bash
2)vi /usr/share/kibana/config/kibana.yml
3)增加以下配置:
i18n.locale: "zh-CN"
6.docker update kibana --restart=always
7.docker restart kibana
3.安装ik分词器
1.下载对应版本分词器
选择对应es版本安装:https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v7.6.0
下载7.4.2
不能使用默认 elasticsearch-plugin install xxx.zip
2、具体步骤
1)docker exec -it elasticsearch /bin/bash【可以直接在外部挂载的文件夹下】
cd /mydata/elasticsearch/plugins
2)安装wget
yum install wget
3)wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
4)创建ik文件夹,解压: unzip
5)rm -rf *.zip
6)修改权限 chmod -R 777 ik/
7)检查ik是否装好:docker exec -it elasticsearch /bin/bash
cd /bin
8)重启elasticsearch
ik分词器安装地址: elasticsearch-analysis-ik-7.4.2.zip