[项目练手笔记-谷粒商城(SpringCloud Alibaba+vue前后端分离)]day02+day03 nacos,gateway的使用、前端入门学习
结合SpringCloud Alibaba我们最终的技术搭配方案:
SpringCloud Alibaba Nacos:注册中心(服务发现/注册)
SpringCloud Alibaba Nacos:配置中心(动态配置管理)
SpringCloud Ribbon:负载均衡
SpringCloud Feign:声明式HTTP客户端(调用远程服务)
SpringCloud Alibaba Sentinel:服务容错(限流、降级、熔断)
SpringCloud Gateway: API网关(webflux 编程模式)
SpringCloud Sleuth:调用链监控
SpringCloud Alibaba Seata:原Fescar,即分布式事务解决方案
一、SpringCloud Alibaba Nacos的使用
1.在common模块中导入依赖
阿里巴巴统一依赖管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
nacos服务注册于配置中心
<!-- 服务注册/发现-->
<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-config</artifactId>
</dependency>
2.注册微服务
在application.yml中将对应的微服务注册到nacos中
cloud:
nacos:
discovery:
server-addr: localhost:8848
application:
name: gulimall-coupon #注册的名字
3.添加注册发现注解
在主方法上添加@EnableDiscoveryClient
二、OpenFeign的远程调用
1.引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.编写远程调用接口
为了方便起见,建立一个feign包专门用来存放远程调用接口
接口要声明调用哪个接口的哪个请求
//要被调用的controller的方法
@RequestMapping("/member/list")
public R memberFeign() {
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("满100-99");
return R.ok().put("coupons", Arrays.asList(couponEntity));
}
//feign接口,表明要调用的是微服务gulimall-coupon中的/coupon/coupon/member/list路径下的memberFeign方法
@FeignClient(value = "gulimall-coupon")
public interface CouponFeignService {
@RequestMapping("/coupon/coupon/member/list")
public R memberFeign() ;
}
@RestController
@RequestMapping("member/member")
public class MemberController {
@Autowired
private MemberService memberService;
@Resource
private CouponFeignService couponFeignService;
@RequestMapping("/coupons")
public R memberCoupon() {
R coupons = couponFeignService.memberFeign();
MemberEntity memberEntity = new MemberEntity();
memberEntity.setUsername("小三");
return R.ok().put("member",memberEntity).put("coupons",coupons.get("coupons"));
}
3.配置主方法
@EnableFeignClients(basePackages="com.xiaoxiao.gulimall.member.feign")
访问localhost:8000/member/member/coupons,验证远程调用了

三、Nacos作为服务配置中心
nacos作为配置中心都在我以前的学习笔记中有,笔记地址
1.引入依赖
<!-- 配置中心来做配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.创建bootstrap.yml
bootstrap.yml作为全局配置,优先级高于application.yml,可以在其中配置注册配置地址,其余配置从nacos配置中心拉取
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
namespace: 36cbae64-6c6a-443a-87d3-f4ade9651be8 #命名空间
ext-config:
- dataId: datasource.yml
group: dev
refresh: true
- dataId: mybatis.yml
group: dev
refresh: true
- dataId: other.yml
group: dev
refresh: true
group: dev
application:
name: gulimall-coupon
3.自动刷新
只需要在调用的controller上加上@RefreshScope即可
注,不知道为什么nacos总是有一些莫名其妙的问题,比如加了@RefreshScope一直刷新也没有更新配置,如果遇到了,网上也搜不到解决方案,建议重启,可能就好了
四、GateWay作为API网关
1.nacos配置
使用nacos作为配置中心,在nacos配置设置进行命名空间隔离,分组,创建yml
2.配置bootstrap.yml
spring:
application:
name: gulimall-gateway
cloud:
nacos:
config:
server-addr: localhost:8848
namespace: c2a660b0-5796-46f1-9c18-7686e3fb4c83
3.配置application.yml
配置路由规则
spring:
application:
name: gulimall-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: baidu_route
uri: http://www.baidu.com
predicates:
- Query=url,baidu
- id: qq_route
uri: http://www.qq.com
predicates:
- Query=url,qq
server:
port: 88
4.测试
测试输入localhost:88/hello?url=qq,能否跳转到QQ,这里是跳转到了qq的/hello
五、前端开发入门
1.ES6入门
ECMAScript是浏览器脚本语言的规范,而javascript则是规范的具体实现
1.let声明变量
shift+! 快速生成html规范
- 特性1:let较var严格,不能跨域
/*
特性1:
var定义的变量可以跨域
let定义的变量不能跨域,与域要求严格
*/
{
var a = 1;
let b = 2;
}
console.log(a); //输出1
console.log(b); //报错,因为跨域
- 特性2:var能声明多次,let只能声明一次
/*
特性2:
var可以多次定义的同一个变量
let只能同一个变量一次
*/
var m = 1;
var m = 2;
let b = 2;
let b = 3;
console.log(a); //输出2
console.log(b); //报错,因为多次赋值
- 特性3: var会变量提升,let不会变量提升
/*
特性3:
var会变量提升
let不会变量提升
*/
console.log(m); //输出undifined
var m = 1;
let b = 2;
console.log(b); //报错,提示未定义b
2.const声明常量
const定义的变量是常量,无法进行修改,且必须初始化
3.解构表达式
1.数组解构
//1.数组解构
let arr=[1,2,3];
let [x,y,z] = arr;
console.log(x,y,z);
2.对象解构
//2.对象解构
const person = {
name: "xiaoxiao",
age: 21,
language: ['java', 'js', 'php']
}
//解构对,将解构的name赋值给bbb
const {name:bbb, age, language} = person;
console.log(bbb, age, language);
4.字符串
1.字符方法
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("llo"));//true
2.字符串模板
let ss = `
<div>
<span>helloword<span>
<div>
`
console.log(ss);
3.${}的使用
${}可以放在字符串中,可以插入变量或者js表达式,函数返回值
let age = 10;
console.log(`我今年${age}岁了`);//我今年10岁了
console.log(`我今年${age+15}岁了`);//我今年25岁了
5.函数优化
1.函数默认值
//函数默认值
function fun1(a,b=1) {
console.log(a+b);
}
fun1(10);//11
fun1(10,10);//20
2.不定参数
不定参数用来表示不确定参数个数,形如…变量名,…加上一个具名参数标识符组成。
具名参数只能放在参数列表的最后,并且有且只有一个不定参数
//不定参数
function fun2(...values) {
console.log(values.length);
}
fun2(1, 2)//2
fun2(1, 2, 3, 4) //4
3.箭头函数
和lamda表达式类似
//箭头函数
var print = obj=>console.log(obj); //函数方法体就是console.log(obj),参数是obj
print("hello");
var sum1 = (a,b)=>a+b;
console.log(sum1(10,20));//30
var sum2 = (a,b)=> {
let c = a+b;
return c+a;
}
console.log(sum2(10,20));//40
箭头函数+解构表达式
const person = {
name: "xiaoxiao",
age: 21,
language: ['java', 'js', 'php']
}
var hello=({name})=>console.log("hello"+name);
hello(person)//helloxiaoxiao
6.对象优化
1.输出对象
const person = {
name: "xiaoxiao",
age: 21,
language: ['java', 'js', 'php']
}
console.log(Object.keys(person));//输出对象的键
console.log(Object.values(person));//输出对象的值
console.log(Object.entries(person));//输出对象的键值对
2.合成对象
const target = {
a:1
}
const source1 = {
b:1
}
const source2 = {
c:1
}
Object.assign(target,source1,source2);
console.log(target);
3.对象函数简写
//3) 、对象的函数属性简写
let person3 = {
name:"xiaoxiao",
//以前:
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("橘子");
4.对象运算符扩展
// 1、拷贝对象(深拷贝)
let p1 = { name: "Aamy", age: 15 }
let someone = {...p1}
console.log(someone) // { nane: "Amy", age: 15 }
// 2、含并对象
let age1 = { age: 15 }
let name1 = { name: " Amy" }
let p2 = { name: "zhangsan" }
p2 = { ...age1, ...name1 }
console.log(p2);
7.map与reduce
//数组中新增了map和reduce方法。
//map():接收一个经数,将原数组中的所有元素用这个团数处理后放入新数组返回。
let arr = ['1', '20', '-5', '3'];
// arr=arr.map(item) => (
//return item * 2
//});
arr = arr.map(item => iten * 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)
8.promise优化异步操作
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) => {
console.log("出现异常", err)
});
如果出现异常:
已拦截跨源请求:同源策略禁止读取位于 file:///D:/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E/%E5%89%8D%E7%AB%AF%E5%9F%BA%E7%A1%80/mock/user.json?callback=jQuery34106058175736353101_1594216378693&_=1594216378694 的远程资源。(原因:CORS 请求不是 http)。
说明没有使用Live server运行,使用的是在浏览器打开

9.模块化
使用export导出要使用的对象,变量,函数,使用import来调用
2.vue入门
1.安装
npm init -y
npm install vue
2.引入vue
<script src="./node_modules/vue/dist/vue.js"></script>
3.基本语法
1.声明式渲染
<div id="test">
<input type="text">
<h1>{{name}},我成功了!</h1>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
//声明式渲染
let vm = new Vue({
el: "#test",
data: {
name: "天才",
num: 10
}
});
2.双向绑定
<div id="test">
<input type="text" v-model="num">
<h1>{{name}},我成功了!有{{num}}正在围观</h1>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
//声明式渲染
let vm = new Vue({
el: "#test",
data: {
name: "天才",
num: 10
}
});
//双向绑定,模型和视图一起变化

3.事件处理
<div id="test">
<input type="text" v-model="num">
<!-- 点击num+1,这个是事件处理 -->
<button v-on:click="num++">围观</button>
<h1>{{name}},我成功了!有{{num}}正在围观</h1>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
//声明式渲染
let vm = new Vue({
el: "#test",
data: {
name: "天才",
num: 10
}
});
//双向绑定,模型和视图一起变化
4.总结
el:绑定数据
data:封装数据
methods:封装方法
1、创建vue实例,关联页面的模板,将自己的数据(data) 渲染到关联的模板,响应式的
2、指令来简化对dom的一些操作。
3、声明方法来做更复杂的操作。methods可以封装方法
安装vue语法插件vue2 snippets
安装chrome插件vue.js devtools
4.基本指令
1.v-text,v-html
注意{{}}插值是给标签体内部绑定值
<div id=test>
{{msg}},加载有延时,未渲染的时候会加载出{{}}
<br>
<span v-html="msg"></span><br>
<span v-text="msg"></span>
</div>
<script src="../node_modules/vue/dist/vue.min.js"></script>
<script>
new Vue({
el: "#test",
data: {
msg: "<h1>helloword</h1>"
}
})
</script>

2.v-bind
给html标签的属性绑定值
<div id=test>
<a v-bind:href="link">百度</a><br>
<span v-bind:class="{active:isActived,'text-danger':isError}"
v-bind:style="{color:color1}">你好</span>
</div>
<script src="../node_modules/vue/dist/vue.min.js"></script>
<script>
new Vue({
el: "#test",
data: {
link: "http://www.baidu.com",
isActived: true,
isError: true,
color1: 'red'
}
})
</script>

3.v-model
<!--表单项,自定义组件-->
<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>

4.v-on
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
<!-- 阻止事件冒泡 -->
<a @click.stop="doSomething"></a>
<!-- 阻止事件默认行为 -->
<a @click.prevent="doSomething"></a>
<!-- 点击一次行为 -->
<a @click.once="doSomething"></a>
<!-- 键盘按键行为 -->
<a @keyup.up="doSomething"></a>
<!-- 组合按键行为 -->
<a @click.ctrl="doSomething"></a>
5.模块化开发
1.安装webpack
全局安装webpack
npm install webpack -g
2.安装vue脚手架
全局安装vue脚手架
npm install -g @vue/cli-init
3.初始化vue项目
vue init webpack appname: vue脚手架使用webpack模块初始化一个appname项目
4.运行
cd appname
npm run dev