当前位置:   article > 正文

JAVA菜鸟从零开始----Vue学习篇_vue list

vue list

JAVA菜鸟从零开始----Vue学习篇

B站 博哥视屏
基本创建方式

List<String> list = Arrays.asList("A","B","C","D");
list.stream().foreEach(s->System.out.println(s));
list.forEach(System.out::println);

List<String> list = Arrays.asList(3,4,5,6);
list.stream().filter(s -> s%2 == 0).collect(Collectors.tolist()); //取出所有偶数

List<Person> list = Arrays.aslist(new Person(34,"张三")new Person(56,"李四"));
Set<Person> people = new TreeSet<>((01, o2) -> o1.getId() - o2. getId()); //通过id来进行升序排序
System.out.print1n(peop1e);


List<Integer> list = Arrays.aslist(3, 4, 5, 6); //求和
System . out. println(list. stream(). reduce(, (prev, val) -> prev += val). intValue());

List<String> list = Arrays.asList("A", "B", "C"); // 拼接成 A,B,C 模式
System. out . println(list. stream().reduce(""(prev, val) -> prev += val + ","));


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

一. 开发工具

1.1开发工具

VUE开发环境推荐使用VS code, 然后安装特定的插件即可开发,可用插件如下:

  • Vetur —— 语法高亮、智能感知、Emmet等
  • EsLint—— 语法纠错
  • Auto Close Tag —— 自动闭合HTML/XML标签
  • Auto Rename Tag —— 自动完成另一侧标签的同步修改
  • Path Intellisense —— 自动路劲补全
  • HTML CSS Support —— 让 html 标签上写class 智能提示当前项目所支持的样式
  • Vue 2 Snippets ——vue的语法提示
1.2vue前置学习

var 关键字存在的问题,

1.var声明的变量可以重复声明,

2.var的作用域不明显,循环外面可以取到循环里面的值

1.let和const关键字

let 声明变量 let a = 3

const 声明常量(常量不能重复声明) const a = 56

2.对象的高级定义

<script>
	const age = 10
    const name = '张三'
    const person = {age,name}	//等同于 const person = {age: age,name: name}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5

3.箭头函数(箭头函数中没有this,this取值是代码书写时上下文的值)

<script>				//弹幕,2秒运行一次
  	setInterval(funcation(){
       	console.log("=======")       
  	},2000)
    
    
    const arr = [3456]
    arr.forEach((item,idx) => {
      	console.log(item,idx)
    })
//等同于    
//   const arr = [3,4,5,6]
//   arr.forEach(function(item,idx){
//     	console.log(item,idx)
//   })
  
  	const arr = [314556]
    arr.sort((v1,v2)=>v1 - v2)		//排序
  	console.log(arr)
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

4.解构赋值

<script>
	let person = {age: 10,name: '张三',address: '北京'}
    
  //  let age = person.age
  //  let name = person.name
  //  let address = person.address
    
    let {age,name,address} = person
    console.log(age,name,address)
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5.扩展运算符

<script>
	let arr = [345]
    //concat() 将参数中的数组填充到调用的数组中
    // let arr1 = [6,7].concat(arr)
    // console.log(arr1)
    let arr1 = [67...arr]
    
    let o1 = {name: 'zs',age:1}
    let o2 = {address: '北京'...o1}
    console.log(o2)
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

6.js数组的高级用法

<script>
	let arr = [567,90,20,34,46]
    
    //过滤出所有的偶数
    let arr1 = arr.filter(val => val % 2 === 0)
    
    //找到第一个偶数所在的索引位置
    let arr2 = arr.findIndex(val => val % 2 === 0)
    
    //找到第一个偶数并将其删除
    let arr3 = arr.splice(arr.findIndex(val = > val % 2 === 0),1)
    
    //找到第一个偶数并将其删除,并在该位置插入,100,200
    let arr4 = arr.splice(arr.findIndex(val = > val % 2 === 0),1,100,200)
    
    //找到满足条件的第一个数据
    let arr5 = arr.find(val = > val % 2 === 0)
    
    //map,将一个数组转换成另一个数组
    //将数组的元素平方
    let arr6 = arr.map(val => val * val)
    
    //使数组输出时每个元素之间加上,号
    let arr7 = arr.join(",")
    
    //reduce()函数
    let arr = [1,2,3,4,5]
    //求和
	console.log(arr.reduce((a,b) => a + b))//15
  	//求乘积
	console.log(arr.reduce((a,b) => a * b))//120
   
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

7.模板字符串

<script>
	content.innerHTML = users.map(u =>`<tr><td>${u.id}</td><td>${u.name}</td><td>${u.address}</td></tr>`).join('')
</script>
  • 1
  • 2
  • 3

8.ajax的回调地狱问题

下一次网络请求的结果 需要依赖上一次请求的结果

.then

9.ES6 的模块化

libs/util.js

function add(a,b){ return a + b}
function multiply(a,b){ return a * b}
//表示对外暴露一个方法
export{ add, multiply }				//这里add 等同于 add:add
  • 1
  • 2
  • 3
  • 4
<!-- js模块的时候,type必须是 module-->
<script type="module">
  	<!--util.js是通过 export方式对外暴露的,所以必须通过解构的方式来import-->
	import{ add,multiply} from './libs/util.js'
  	console.log(add(3,4));	//7
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

10.ES6 的 默认 模块化

libs/other.js

function add(a,b){ return a + b}
function multiply(a,b){ return a * b}
//全文只能有一个export default
export default{ add, multiply }				//这里add 等同于 add:add
  • 1
  • 2
  • 3
  • 4
<script type="module">
  	<!--other.js是通过 export default方式对外暴露的,只能通过对象的方式来import-->
	import ot from './libs/util.js'
  	console.log(ot.add(3,4));	//7
</script>
  • 1
  • 2
  • 3
  • 4
  • 5

二. 第一个VUE程序

2.1 引入js
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  • 1
2.2 给dom元素定义id
<div id="app">
   {{msg}}
</div>
  • 1
  • 2
  • 3
2.3 vue代码编写
new Vue({
	 el: "#app",
     data() {
     	return {
            msg: "Hello World"
     	}
	 }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

二. 基本指令

v-text: v-text是用于操作纯文本,它会替代显示对应的数据对象上的值,可以简写为{{}}, 即插值表达式。

v-html: 将内容以html的形式呈现在页面。

v-if: 值如果为true的情况下,显示标签,如果为false会移除标签。

v-else-if: 与v-if配合使用。

v-else: 与v-if配合使用。

v-show: 如果为true,显示信息,如果为false则隐藏标签。

v-for: 循环遍历。语法形式为 v-for=“item in list”

v-bind: 将值绑定到标签的自定义属性上,形式为 v-bind:title=“mytitle”,可以简写为 :属性名

v-model: 双向数据绑定。

v-on:click: 点击事件,可以简写为@click。

如下代码为v-bind的演示:

<head>
    <style>
        .cls{
            color: red;
        }
        .cls1{
            font-size: 30px;
        }
        .cls2{
            line-height: 40px;
        }
    </style>
</head>
<body>
	<div id="app">
        <p v-bind:class="{cls:isCls}">这是一段话</p>
        <p :class="[one, two, {cls:isCls}]">这是一段话</p>
        <p :title="attr">这是一段话</p>
    </div>
</body>
<script>
	new Vue({
        el: "#app",
        data: {
            isCls: true,
            content: 'hello world',
            one: 'cls1',
            two: 'cls2',
            attr: '附加属性'
        } 
	});
</script>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

案例:1. 通过表单添加数据,渲染到列表中。

​ 2. 遍历数组和对象,并能删除和更新。

三. 事件相关

3.1 点击事件修饰符
A. 阻止事件冒泡

​ 一个盒子中嵌套另外一个盒子的时候,在内外层的盒子中都有有对应的事件行为,当点击内层盒子时候,默认情况下会触发外层盒子的事件,这种默认的行为就是事件冒泡。需要去阻止事件的冒泡。使用方法:

@click.stop="方法名"
  • 1
B. 阻止事件的默认行为

​ 对于form表单来说,当点击表单中的button的时候,会默认触发表单的提交;对于a标签,当点击a标签的时候,会触发a标签访问。那么如何去阻止a标签的默认访问行为呢,使用方法是:

@click.prevent="方法名"
  • 1
3.2 按键修饰符
键盘回车绑定
<input @keyup.13="showInfo" v-model="info"><br>
<input @keyup.enter="showInfo" v-model="info"><br>
  • 1
  • 2
new Vue({
	el: '#app',
	data: {
		info: ''
	},
 	methods: {
 		showInfo(){
 			alert(this.info);
 		}
 	}
 })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

四. 监视器(watch)

​ 所谓的监视器就是可以通过watch的方式观察某个属性的变化,然后做出相应的处理。

4.1 案例
    <div id ="app">
        <input type="text" v-model="msg">
        <input type="text" v-model="stu.name">
    </div>

    <script>
     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{
            msg:"",
            stu:{
                name:"",
            }
        },
        methods: {},
        watch: {
            msg(newVal,oldVal){
                console.log(newVal);
                console.log(oldVal);
            },
            "stu.name":{
                handler(newVal,oldVal){ 
                    console.log(oldVal+"--->"+newVal);
                }
            }
        },
     });
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
4.2省市区联动案例
<!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="./lib/vue.js"></script>
    <script src="./lib/city.js"></script>
</head>

<body>
    <div id ="app">
        <select  v-model:id="provinceId">
            <option value="-1">请选择省份</option>
            <option :value="item.id" v-for="(item, index) in provinceAll" :key="index">{{item.name}}</option>
        </select>
        <select v-model:id="cityId">
            <option value="-1">请选择城市</option>
            <option :value="item.id" v-for="(item, index) in cityAll" :key="index">{{item.name}}</option>
        </select>
        <select v-model:id="districtId">
            <option value="-1">请选择区</option>
            <option :value="item.id" v-for="(item, index) in districtAll" :key="index">{{item.name}}</option>
        </select>
    </div>

    <script>
     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{
            provinceAll:province,
            provinceId:-1,
            cityAll:[],
            cityId:-1,
            districtAll:[],
            districtId:-1,
        },
        methods: {},
        watch: {
            provinceId(newVal,oldVal){
                //恢复默认
                this.cityId=-1;
                // 清空数组
                this.cityAll=[];
                //循环通过省份id查询所有符合的城市,放到数组里
                city.forEach(city=> {
                    if(city.upid==newVal){
                        this.cityAll.push(city)
                    }
                });  
            },
            cityId(newVal,oldVal){
                this.districtId=-1;
                this.districtAll=[];
                
                district.forEach(district=>{
                    if(district.upid==newVal){
                        this.districtAll.push(district)
                        console.log(this.districtAll);
                    }
                })
            }
            
        },
        created() {
            console.log(this.provinceAll);
        },
     });
    </script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

五. 过滤器(filter)

​ Vue中使用过滤器(Filters)来渲染数据是一种很有趣的方式,他不能替代Vue中的methodscomputed或者watch,因为过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本。在很多不同的情况下,过滤器都是有用的,比如尽可能保持API响应的干净,并在前端处理数据的格式。在你希望避免重复和连接的情况下,它们也可以有效地封装成可重用代码块背后的所有逻辑。不过,在Vue 2.0中已经没有内置的过滤器了,我们必须要自己来构建它们。过滤器只能用于插值表达式中。

5.1 全局过滤器

​ 全局过滤器是只通过 Vue.filter()的方式来定义的过滤器,用这种方式定义的过滤器可以被所有的Vue实例使用。

<div id="app">
    <p>{{createtime | timeFilter}}</p>				//2.调用过滤器
</div>
<script src="./vue.js"></script>
<script>
	Vue.filter('timeFilter', function(value){			//1.定义全局过滤器
		return moment(val).format(yyyy-MM-dd hh-mm-ss);
	})
	new Vue({
		el: '#app',
		data: {
			createtime:1653374270112
		}
	});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

案例一:将数字转换为美元的形式。

<div id="app">
    <p>{{price | toUSD}}</p>
</div>
<script src="./vue.js"></script>
<script>
	Vue.filter('toUSD', function(value){
		return '$' + value;
	})
	new Vue({
		el: '#app',
		data: {
			price: 345.45
		}
	});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

案例二:串联过滤器,将数字四舍五入成两位有效数字,然后转换为美元表达方式

<div id="app">
    <p>{{price | fix(2) | toUSD}}</p>
</div>
<script src="./vue.js"></script>
<script>
	//方法的第一个参数为数据源,第二个为保留几位小数。
    Vue.filter('fix', (num, limit) => {
    	return num.toFixed(limit);
    });
    //转换为美元表达方式
    Vue.filter('toUSD', function(value){
        return '$' + value;
    })
    new Vue({
        el: '#app',
        data: {
            price: 345.45
        }
    });
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
5.2 局部过滤器

案例三:替换文本

    <div id ="app">
        <p>{{msg|str()}}</p>
    </div>

    <script>
     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{
            msg:"没有未来的未来不是我想要的未来"
        },
        methods: {},
        filters:{
            str(source){
               return source.replace(/未来/g,'世界');
            }
        },
     });
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

练习:定义日期转换的过滤器。

六、axios

github下载地址:https://github.com/axios/axios

axios-get

跨域访问:

跨域访问时浏览器的限制,浏览器不允许不同的域之间相互访问(出于安 全的考虑)

哪些情况会构成跨域

1:域名不同 www.taobao.com => www.jd.com

2:ip不同 11.124.8.12 => 10.15.145.12

3:port不同 127.0.0.1:5566 => 127.0.0.1:8080

4:协议不同 https://127.0.0.1:5566 => http://127.0.0.1:8080

5 : 请求的资源不存在,直接报跨域

跨域问题解决:jsonp解决

让服务端信任客户端,允许客户端跨域访问

@CrossOrigin(origins = {"http://127.0.0.1:5500","http://localhost:5500"})
  • 1
 //发送异步请求,调用后端接口,获取用户列表
            axios.get("http://localhost:8888/user/findAll")
            .then(res=>{ //成功回调
                console.log(res.data);
            })
            .catch(err=> {//失败回调(除了200,其他都是失败)
                console.log(err);
                console.log("????");
            });

            //分页查询
            // axios.get("http://localhost:8888/user/findPage?page=1&size=3")
            // .then(res=>{ //成功回调
            //     console.log(res.data);
            // })
            // .catch(err=> {//失败回调(除了200,其他都是失败)
            //     console.log(err);
            //     console.log("????");
            // });
            axios.get("http://localhost:8888/user/findPage",{params:{page:1,size:3}})
            .then(res=>{ //成功回调
                console.log(res.data);
            })
            .catch(err=> {//失败回调(除了200,其他都是失败)
                console.log(err);
                console.log("????");
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

方式一:通过url传参

<!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="./lib/vue.js"></script>
    <!-- 导入axios库文件 -->
    <script src="./lib/axios.js"></script>
</head>

<body>
    <div id ="app">

    </div>

    <script>
     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{

        },
        methods: {

        },
        created() {
            //发送get请求
            axios.get("http://localhost:8080/goods/findAll?name='jack'").then(
                //请求成功的回调
                function(res){
                      console.log(res.data);  
                }
            ).catch(
                //请求失败的回调(404、500、400、403除了200其他都是失败)
                function(err){
                    console.log("come in !!")
                    console.log(err);  
                }
            )
        },
     });
    </script>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
注意:
1:解决跨域的问题(浏览器为了安 全做的限制,不是服务端的限制,底层可以通过jsonp的原理去解决)
解决办法在controller类上统一价@CrossOrigin

2:axios成功回调的数据必须通过res.data获取

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

方式二:通过parms传参

<!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="./lib/vue.js"></script>
    <!-- 导入axios库文件 -->
    <script src="./lib/axios.js"></script>
</head>

<body>
    <div id ="app">

    </div>

    <script>
     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{

        },
        methods: {

        },
        created() {

            //定义参数
            var paramsObj = {
                name:"jack"
            }

            //发送get请求
            axios.get("http://localhost:8080/goods/findAll",{params:paramsObj}).then(
                //请求成功的回调
                function(res){
                      console.log(res.data);  
                }
            ).catch(
                //请求失败的回调(404、500、400、403除了200其他都是失败)
                function(err){
                    console.log("come in !!")
                    console.log(err);  
                }
            )
        },
     });
    </script>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

axios-post

<!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="./lib/vue.js"></script>
    <script src="./lib/axios.js"></script>
</head>

<body>
    <div id ="app">
       username <input type="text" v-model="user.username">
       address <input type="text" v-model="user.address">
       <input type="submit" value="save" @click="save()">
    </div>

    <script>
     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{
            user:{
                username:"",
                address:""

            }
        },
        methods: {
            save(){
                //发送异步请求(post)
                axios.post("http://localhost:8888/user/save",this.user)
                .then(res=>{
                    console.log(res.data);
                })
                .catch(err=>{

                })
            }
        }
     });
    </script>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

axios-全局配置

axios.defaults.timeout = 10000;   // 超时时间
axios.defaults.baseURL = apiURL;  // baseURL

  • 1
  • 2
  • 3

七、axios-拦截器(interceptors)

请求拦截器

 //设置axios请求拦截器
     axios.interceptors.request.use(function(config){
            console.log(config);
            //统一设置请求头
            config.headers.token = "uuid";

            return config;
     })   
//通过axios请求拦截器全局设置请求头
	axios.interceptors.request.use( config=>{
			config.headers.token = "1234" ;
			return config;
	})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
后台接收请求头的信息
@RequestHeader("token") String token    
  • 1
  • 2

响应拦截器

 //设置响应拦截器
     axios.interceptors.response.use(res=>
        return  res.data;
     })
 //设置响应拦截器
     axios.interceptors.response.use(function(res){
        console.log(res);
        return  res.data;
     })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
<!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="./lib/vue.js"></script>
    <script src="./lib/axios.js"></script>
</head>

<body>
    <div id ="app">

    </div>

    <script>

     axios.defaults.baseURL = "http://localhost:8888";
     axios.defaults.timeout = 3000;   

     //通过axios请求拦截器全局设置请求头
     axios.interceptors.request.use(config=>{
        config.headers.token = "1234";

        console.log(config);

        return config;
     })

     //通过响应拦截器,全局获取后端返回的data
     axios.interceptors.response.use(res=>{

       return  res.data;
     })




     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{

        },
        methods: {},
        created() {
            // axios.get("/user/findAll",{headers:{token:"123"}}).then(res=>{
            //     console.log(res.data);
            // })


            axios.get("/user/findAll").then(res=>{
                console.log(res);
            })

            axios.get("/user/findAll").then(res=>{
                console.log(res);
            })
        },
     });
    </script>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

vue+axios综合练习

需求:分页+条件查询

查询:条件+分页的查询

<!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="./lib/vue.js"></script>
    <script src="./lib/axios.js"></script>
</head>

<body>
    <div id ="app">
        <input type="text" placeholder="请请输入用户名" v-model="stu.uname"> <input type="text" placeholder="请请输入年龄" v-model="stu.uage">
        <input type="submit" value="搜索" @click="search()"><br/><br/>

        <table width="100%" border="1px" cellspacing="0" cellspadding="0">
            <tr>
                <td>名字</td>
                <td>年龄</td>
            </tr>
            <tr v-for="(item, index) in stuList" :key="index">
                <td>{{item.uname}}</td>
                <td>{{item.uage}}</td>
            </tr>
        </table>
        <span @click="page=p;search()" v-for="(p ) in pages" >[{{p}}]   </span>


    </div>

    <script>

     axios.defaults.baseURL = "http://localhost:8080"  ; 

     //定义响应拦截器
     axios.interceptors.response.use(function(res){

        return res.data;
     })  
     
     //定义axios请求拦截器
     axios.interceptors.request.use(function(config){

        config.headers.token = "xx";
        return config;
     })  


     //创建Vue实例,得到 ViewModel
     var vm = new Vue({
        el: '#app',
        data:{
            stu:{

            },
            stuList:[],
            pages:0, // 总页数
            page:1,
            size:1,
        },
        methods: {
            search(){
                axios.post(`/findPage?page=${this.page}&size=${this.size}`,this.stu).then(res=>{
                    console.log(res);  //res是后台返回的数据
                    this.stuList = res.data;

                    this.pages = res.pages
                })
            }
        },
        created() {
            //页面加载,获取第一页数据
            this.search();
        },
     });
    </script>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

使用postman接口测试

八. vue-cli构建项目与打包部署

8.0创建vue项目

nodejs —> NPM —> vue-cli —> Vue的工程化项目

1.安装nodejs (node-v16.14.2-x64.msi)

https://nodejs.org/en/

2.打开控制台查看版本号

node -v

npm -v

3.使用npm构建项目

npm install -g @vue/cli             #安装vue-cli,该步骤需要等一段时间  -g表示全局安装 
vue -V                              #查看vue-cli的版本
vue create my-app                   #创建名为my-app的项目
  • 1
  • 2
  • 3

4.选择版本 Vue 2

>//或者手动配置	勾选 Router,版本2.x          (Vue3 的编程语言为Ts)
  • 1

5.项目结构

  • public: 存放静态文件。

    • favicon.ico
    • index.html
  • src: 源码文件,开发就在此目录下。

    • assets:资产,存放文件,图片,css

    • components:组件

    • router:路由

    • views:视图

    • App.vue:入口组件

    • main.js:入口程序

      import Vue from 'vue'				#导入Vue  App
      import App from './App.vue'
      
      Vue.config.productionTip = false
      
      new Vue({
        render: h => h(App),
      }).$mount('#app')					#把Vue挂载到index.html中ID为app的div
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
  • .gitignore: git的配置文件。

  • babel.config.js: babel的配置文件,在创建项目的时候才用的脚手架为bable,高级语法转低级语法

  • package-lock.json:定义了依赖库的下载位置,保证了在项目迁移部署环境的一致性。

  • package.json: 定义了该项目依赖的类库。

    • dependencies:依赖
    • devDependencies:依赖的作用范围,只在开发时有效
    • eslintConfig:语法检测,书写的代发必须符合eslint规范
    • browserslist:开发的vue项目,满足市面上99%的浏览器兼容

6.启动项目

Ctrl+~							#打开终端
npm run serve					#启动项目(默认端口为8080
  • 1
  • 2
8.3 项目的打包部署

执行命令:

npm run build

  • 1
  • 2

将生成的dist目录下的文件放入到tomcat或者nginx下,启动服务器,即可访问。

九 组件化开发

​ 组件化开发是在ES6中提出的,可以提高页面的复用率,提高开发效率,便于团队协作,是一套模板化的代码,要有<template><script><style>三个标签,分别用来定义布局、脚本和样式。而且<template>下必须有一个根节点。

9.1 编写App.vue和HelloWorld.vue

HelloWorld.vue

<template> 
	<div>  <!-- template的根节点,是必须的 -->
		<h1 class="title">{{msg}}</h1>
	</div>
</template>
<script>
	export default {   <!-- 向外保留成员,表示向外暴露该组件 -->
		data() {
			return {
				msg: 'Hello World'
			}
		} 
	}
</script>
<style>
	.title{
		color: red;
	}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

App.vue

<template>
    <div>
        <p>{{article}}</p>
        <Helloworld></Helloworld> <!-- 在Helloworld.vue中的组件 -->
    </div>
</template>
<script>
/**
 * 引入HelloWorld.vue组件,使用Helloworld变量来接收,接收变量的组件
 * 可以叫任何名字,但是推荐使用和导入组件保持一致。
 */
import Helloworld from './components/HelloWorld.vue'

export default {
	/**
     *  需要在当前组件中来定义引入的组件,接收的形式可以有二种:
     * 
     *  components: {HelloWorld} 最原始的写法为{Helloworld:Helloworld},第一个Helloworld
     *     在当前组件中使用的名字,可以随意更改,第二个Helloworld是上面import引入的时候用来接收的变
     *     量名。如果只写一个表示当前组件中使用的名字和变量名一致。 
     */
    components: {Helloworld},
    data(){   //组件化编程必须使用定义data方法
        return {
            article: '路透社20日援引伊朗法尔斯通讯社消息称'
        };
    }
}
</script>
<style>
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
9.2 定义入口JS文件
import Vue from 'vue'        //引入vue
import App from './App.vue'  //引入自己定义的App.vue,使用变量App来接收

new Vue({
    render: h => h(App),  //将App组件渲染到index.html中。
}).$mount("#app")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

render是Vue中的一个方法,方法的定义形式如下:

// render最原始的,而传入的参数createElement又是一个函数,用来生成dom结构
render: function(createElement){
    
}
// 按照ES6的箭头函数的写法,进行第一次演变
render: createElement => createElement(模板)
// 将上面的createElement变为h,那么就得到最终的形式
render: h => h(App)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

$mount(“#id”)该方法的作用是先实例化Vue对象,接着在挂载到指定Id的节点上,和在**new Vue**的时候使用el指定要渲染的节点的形式是一样的,只是换了种形式而已。

十. vue案例演示

  1. 计算器
  2. tap选项卡
  3. 购物车
  4. 表单操作
  5. 评价功能
  6. 打豆豆

​ 当你能够独立的完成如上案例,表示你已经比较深入的理解VUE了 _

十一. 组件通信

11.1 props

父组件 App.vue

<template>
	<div>
		<h1>Hello World</h1>
		<!-- 前面一个msg标识子组件用于接收的变量名, 引号中的msg是当前组件的值 
			 第一个add是子组件用于接收的变量名,第二个add是当前组件的方法名
		-->
		<child :msg="msg"/> 
	</div>
</template>
<script>
import child from './Child.vue'
export default {
    components: {
        child
    },
	data() {
        return {
            msg: '这个信息来源于父组件'
        };
	}
}
</script>
<style></style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

子组件 Child.vue

<template>
	<div>
		<p>{{msg}}</p>
		<button @click="addItem" />
	</div>
</template>
<script>
export default {
	// 使用props接收父组件传递过来的值
	props: ['msg']
}
</script>
<style></style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
11.2 事件绑定
11.2.1 子组件操作父组件

父组件 App.vue

<template>
  <div>
     <input type="text" v-model="value">
     <hr>
     <Child @dosomething="changeValue"/>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  components: {
    Child
  },
  data() {
    return {
      value: ''
    }
  },
  methods: {
    changeValue(value) {
      this.value = value;
    }
  }
}
</script>
<style>
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

子组件 Child.vue

<template>
    <div>
        <button @click="dosomething">子组件按钮</button>
    </div>
</template>

<script>
export default {
    methods: {
        dosomething() {
        	// 调用父组件绑定的事件 dosomething,然后调用changeValue方法,并传值
            this.$emit('dosomething', '张某人');
        }
    }
}
</script>
<style>
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
11.2.3 父组件取子组件中的值

父组件 App.vue

<template>
  <div>
     <input type="text" v-model="value">&nbsp;&nbsp;
     <button @click="changeValue">取子组件的值</button>
     <hr>
     <Child ref="child"/>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  components: {
    Child
  },
  data() {
    return {
      value: ''
    }
  },
  methods: {
    changeValue() {
      this.value = this.$refs.child.value;
    }
  }
}
</script>
<style>
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

子组件 Child.vue

<template>
    <div>
        <p>我是子组件,我中间定义了一个value='张某人'的数据</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            value: '张某人'
        }
    }
}
</script>
<style>
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
11.4 插槽(slot)

​ 插槽的作用说白了就是一个占位的作用。

父组件 App.vue

<template>
    <List>
    	<!--
    	  可以简写为这种形式
    	  <template #title>
    	-->
        <template v-slot:title>
            <h2>插槽案例</h2>
            <button class="btn btn-danger btn-sm">点击</button>
        </template>
        <!--
    	  可以简写为这种形式
    	  <template #title="props">
    	-->
        <template v-slot:item="props">
            <h3>插槽属性</h3>
            <p>属性值:{{props}}</p>
        </template>
    </List>
</template>

<script>
import List from './components/List.vue'

export default {
    components: {
        List
    }
}
</script>

<style>
    .site-header {
        text-align: center;
    }
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

子组件 Child.vue

<template>
    <div>
        <slot name="title"></slot>
        <slot name="item" v-bind="person"></slot> <!-- 组件属性 -->
    </div>
</template>
<script>
export default {
    data() {
        return {
            person: {age: 10, name: 'zhangsan'}
        }
    }
}
</script>
<style>
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
11.5 路由传参的两种方式
routes:[
  {
    path:'/home/:val',
    component:Home,
    props:true	
  }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
export default{
  props:['val']
}
  • 1
  • 2
  • 3
this.$router.push({
  path:`/user-detail`,
  query:{
  	id:uId,
    name:'张三'
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
mounted(){
  let id = this.$route.query.id
}
  • 1
  • 2
  • 3

十二. 网络请求

​ vue2.X版本中,官方推荐的网络请求的工具是axios。

npm install axios vue-axios --save

  • 1
  • 2
12.1 配置全局请求地址

​ 新建Base.vue文件,文件内容如下:

<script>
const BASE_URL = "http://localhost:8081"
export default {
BASE_URL
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
12.2 main.js配置
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import Base from './Base.vue'

Vue.use(VueAxios, axios);  //顺序有关系
axios.defaults.baseURL = Base.BASE_URL  //配置基本地址

new Vue({
  render: h => h(App),
}).$mount('#app')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
12.3 发送GET请求
this.axios.get('/user'
    /**  可以通过如下方式,添加请求头信息
    ,{
         headers: {
             'token': 'hyfetrrabcpo'
         }
      }
    */
    )
    .then((resp) => {  // 请求成功
      this.users = resp.data;  
    }, (error) => { //请求失败
       window.console.log(error);  //不能直接用console
    })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
12.4 发送POST请求
this.axios.post('/user', {name:'zhangsan', id: 10})  //后台必须要用json接收
	.then((resp) => {
			this.users = resp.data;
	}, (error) => {
			window.console.log(error);  //不能直接用console
	})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
12.5 发送DELELE请求
this.axios.delete('/user/56')
	.then((resp) => {
			this.users = resp.data;
	}, (error) => {
			window.console.log(error);  //不能直接用console
	})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

十三. VueRouter

​ Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

13.1 安装
npm install vue-router@3.5.4 --save

  • 1
  • 2
13.2 配置路由信息

​ 新建一个文件夹叫做router,然后在里面定义一个index.js文件,在该文件中配置路由信息:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'


Vue.use(Router)   //使用插件

export default new Router({
    linkActiveClass: 'active',   //选中状态下默认添加的样式
    routes: [
        {
            path: '/home',
            component: Home
        },
        {
            path: '/about',
            component: About
        },
        {
            path: '/',
            redirect: '/about'   //根路径默认会重定向到/about路径
            
        }
    ]
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
13.3 main.js文件中的配置
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import Base from './Base.vue'
import router from './router'

Vue.use(VueAxios, axios);  //顺序有关系
axios.defaults.baseURL = Base.BASE_URL

new Vue({
  render: h => h(App),
  router
}).$mount('#app')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
13.4 访问与渲染

使用<router-link>标签设置路径,to属性设置路由路径:

<router-link to="/home" class="list-group-item">Home</router-link>
<router-link to="/about" class="list-group-item">About</router-link>
  • 1
  • 2

使用<router-view>标签,将对应的路由组件设置到这个标签当中:

<router-view></router-view>
  • 1
13.5 子路由

​ 在路由的配置中使用children来配置子路由。

children: [
	{
		path: '/home/game',
		component: Games
	}
]


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
13.6 参数的传递

​ 在使用路由的过程中,经常会碰到路由参数的传递,那么传递方式大概有三种。

方式一:

路由配置:
{path:'/user/:id', component:userDetail, props:true}
路由请求:
<router-link :to="'/user/' + user.id">{{user.name}}</router-link>
取值:
在userDetail中使用 props: {id: String} 来接收数据
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

方式三:

路由配置:
{path:'/user', name:'userDetail', component:userDetail}
路由请求:
<router-link :to="{path:'/user', query:{id:user.id}}">{{user.name}}</router-link>
取值:
mounted() {
    this.id = this.$route.query.id;   //用户刷新的时候有用
},    
watch:{ //监听路由的变化
    $route: {
        handler(val) {
            this.id = val.query.id;
        }
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
13.7 编程式路由

方式一:

实现跳转:
this.$router.push({
          path: '/user',
          query: {id:id}
       });
取值:
mounted() {
        this.id = this.$route.query.id;
    },
    
watch:{
    $route: {
    	handler(val) {
    		this.id = val.query.id;
    	}
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

方式二:

实现跳转:
this.$router.push({
          path: '/user',
          query: {id:id}
       });
取值:
props: {
    id: String
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
13.8 路由守卫
13.8.1全局路由守卫
router.beforeEach((to,from,next) =>{
    next();
});

  • 1
  • 2
  • 3
  • 4

十四. vuex

14.1 vuex是什么

​ vuex是对vue项目进行状态管理的js库,对于所有的组件来说,它是一个中央存储,这种模式就保证了只能按照特定的模式来更改状态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwDDC3z2-1663847834589)(image/vuex.png)]

14.2 vuex的五大核心

state

​ 说的直白点就是存储数据的地方。

actions

​ 通过异步的方式更改状态值,但是不能直接更改,需要借助于mutations来更改。

mutations

​ 通过直接同步的方式更改状态。

getters

​ 类似于计算属性,通常是需要通过state来间接计算得到的值。

modules

​ 一个项目中因为模块的原因,存在着各种不同的状态,需要按照模块来划分。

14.3 安装vuex
npm install vuex --save

  • 1
  • 2
14.4 建立store

​ 新建一个文件夹,名字叫store,在文件夹中新建一个文件,文件名叫index.js,文件内容如下:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

//state
const state = {
    todos:[{title:'工作一', complete:true}]
}
// actions
const actions = {
	// 第一个参数必须是context, 第二个参数是需要的业务数据
    addTodo(context, todo){
    	// 通过commit的方式提交个mutations, 真正实现对状态修改的其实是mutations
        context.commit('addTodo', todo)
    }
}
// getter,类似于计算属性,需要根据state来计算出其他想要的属性
const getters = {
    completedTodoNumber: state => {
        return state.todos.reduce((preTotal, current) => preTotal + (current.complete ? 1 : 0), 0)
    }
}
//操作
const mutations = {
    //添加待办事项,第一个参数必须是state, 第二个参数是传递过来的数据
    addTodo(state, todo) {
        state.todos.unshift(todo)
    }
}
// 对外暴露Vuex.Store的对象,在其他任何组件中都可以使用 $store来进行操作
export default new Vuex.Store({
    state,
    mutations,
    actions,
    getters
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
14.5 main.js配置
import Vue from 'vue'
import App from './App.vue'
import store from './store'

new Vue({
    store,   //引入store
    render: h => h(App)
}).$mount("#app");


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
14.6 组件中使用
this.$store.state.todos    //获取状态值
this.$store.commit('addTodo', todo);  //通过mutations中的方法更新状态
this.$store.dispatch('addTodo', todo); //通过actions中的方法异步更新状态
this.$store.getters.completedTodoNumber;  //获取getters中的属性


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
14.7 映射函数调用
import {mapState, mapActions, mapGetters, mapMutations} from 'vuex'

computed: {
    ...mapState(['todos']),  //扩展运算符, 在当前组件中直接使用this的方式调用
    ...mapGetters(['completedTodoNumber'])
},
methods: {
	//引号中的内容为actions中定义的方法名, 可以直接使用this.addTodo来调用。
    ...mapActions(['addTodo']),  
    ...mapMutations(['addTodo'])
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
14.8 Modules

A. 新建一个shopping目录,目录下新建index.js文件,文件内容如下:

const state = {
    todos:[{title:'工作一', complete:true}]
}

const actions = {
    addTodo(context, todo){
        context.commit('addTodo', todo)
    },
    delDone(context) {
        context.commit('delDone')
    },
    delByIndex(context, index) {
        context.commit('delByIndex', index);
    }
}
const getters = {
    completedTodoNumber: state => {
        return state.todos.reduce((preTotal, current) => preTotal + (current.complete ? 1 : 0), 0)
    }
}
//操作
const mutations = {
    //添加待办事项
    addTodo(state, todo) {
        state.todos.unshift(todo)
    },
    delDone(state) {
        state.todos = state.todos.filter(todo => !todo.complete)
    },
    delByIndex(state, index) {
        state.todos.splice(index, 1);
    }
}

export default {
    state,
    actions,
    getters,
    mutations
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

B. 在store下的index.js文件中写入如下内容:

import Vue from 'vue'
import Vuex from 'vuex'
import shopping from 'shopping'

Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
        shopping
    }
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

C. 使用

获取对应模块的state值方式一:
...mapState({todos: state=>state.shopping.todos})
获取对应模块的state值方式二:
todos: function() {
      return this.$store.state.shopping.todos;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

​ 至于getters、actions、mutations都被注册到全局上,和之前的使用方式一样。

附录:

1.spring boot跨域支持

​ A. 在controller或者对应的方法上加上如下代码

@CrossOrigin(origins = {"http://localhost:8080"})

  • 1
  • 2

​ B. 基于过滤器的跨域支持

@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://domain1.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/716058
推荐阅读
相关标签
  

闽ICP备14008679号