Vue学习笔记——第二部分

2023-11-11

Vue组件的定义、注册方式和模板使用

组件的定义

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码.

vue组件是把页面(html代码,CSS代码)进行模块化

如下图所示,一个页面分四个部分,每个部分是个vue组件,而页面成了vue组件的容器。

在这里插入图片描述

vue.js中创建组件有三个步骤:定义组件,注册组件以及使用组件

定义组件

  • 方式1:先创建一组件构造器,然后由组件构造器创建组件。如:var myCom = Vue.extend({})

  • 方式2:使用Vue.component()直接创建组件。

定义组件名的方式有两种:

  • 使用 kebab-case:使用 kebab-case (短横线分隔命名) 定义一个组件(kebab发音/kI’ba:b/)

  • 使用 PascalCase:(驼峰式命名) 定义一个组件

当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>。当使用 PascalCase (驼峰式命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。

组件的分类

  • 全局组件

  • 局部组件

    通过选项components定义,但只能在当前Vue实例中使用

引用模版

将组件内容放到<template>中引用。

注意:template组件中,有且只有一个根元素

代码示例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>全局组件和局部组件</title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app1">
			<h1>{{message}}</h1>
			<!-- 使用全局组件 -->
			<global-componet-a></global-componet-a>
		</div>
		<div id="app2">
			<h1>{{message}}</h1>
			<!-- 使用全局组件 -->
			<global-componet-a></global-componet-a>
		</div>
		<div id="app3">
			<h1>{{message}}</h1>
			<!-- 使用全局组件 -->
			<global-componet-a></global-componet-a>
			<!-- 使用局部组件 -->
			<component-a></component-a>
		</div>

	</body>
	<!-- 定义模板 -->
	<template id="my-temlate-1">
		<div><h3>{{info}}</h3><a href='http://www.baidu.com'>百度</a></div>
	</template>
	<script type="text/javascript">
		//全局组件定义和注册 Vue.componet("全局组件名称",{})
		Vue.component("global-componet-a",{
			//定义的数据属性要用函数返回对象(对象中存储数据),因为组件每次使用都是一个独立的对象实例,
			//如果data使用原来的方式还是返回的是对象,不调用函数,那么组件每个实例使用的是同一个data属性对象,使用组件的每个实例,共享data属性数据对象实例,是不可以的
			data:function(){
				return {
					info:"全局组件"
				}
			},
			//使用的是模板,使用模板id或者模板放入html标签
			template:"#my-temlate-1"
		});
	
		var app1 = new Vue({
			el:"#app1",
			data:{
				message:"vue-1调用全局组件"
			}
		});
		
		var app2 = new Vue({
			el:"#app2",
			data:{
				message:"vue-2调用全局组件"
			}
		});
		
		var app3 = new Vue({
			el:"#app3",
			data:{
				message:"vue-3调用全局组件全局组件和局部组件"
			},
			//局部组件定义和注册,使用范围只能在app3挂载的DOM对象中
			components:{
				"component-a":{
					data:function(){
						return {info:"局部组件"}
					},
					//使用的是模板,使用模板id或者模板放入html标签
					template:"#my-temlate-1"
				}
			}
		});
		
	</script>
</html>

组件间数据的通信

父子组件

在一个组件内部定义另一个组件,称为父子组件

子组件只能在父组件内部使用

默认情况下,子组件无法访问父组件中的数据,每个组件实例的作用域是独立的

组件间数据通信

子组件访问父组件的数据(父传子)

  • 在调用子组件时,绑定想要获取的父组件中的数据在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据。

  • 即父组件通过props向下传递数据给子组件。

  • 注:组件中的数据存在方式共有三种:data、props、computed

props传递数据两种形式

  • 数组方式: props:[‘msg’, ‘username’, ‘age’, ‘userObj’]
  • 对象方式:该方式提供了对数据的校验、类型监测、默认值设置操作。

prop命名,可以在在组件中使用postTitle(驼峰名称),在html中是使用短横线命名post-title,如下代码示例

Vue.component('blog-post', {
  // 在 JavaScript 中是 驼峰命名 的
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 短横线 的 -->
<blog-post post-title="hello!"></blog-post>

父组件传子组件的代码实例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 调用根实例message属性值 -->
			<h1>{{message}}</h1>
			<!-- 使用子组件 -->
			<!-- 使用v-bind的简写方法绑定属性 parent-message 值为根实例(父组件)的data属性数据 message-->
			<component-a :parent-message="message"></component-a>
		</div>
	</body>
	<!-- 定义模板 -->
	<template id="my-temlate-1">
		<div>
			<!-- 使用data中的数据 -->
			<h3>子组件内部数据(child-message):{{childMessage}}</h3>
			<!-- 使用props中的数据 -->
			<h3>子组件外部数据(props-parentMessage):{{parentMessage}}</h3>
		</div>
	</template>
	<script type="text/javascript">
		//定义子组件
		var componentA = {
			data:function(){
				return {
					childMessage:"我是子组件的message属性值"
				}
			},
			props:["parentMessage"], //定义props属性对象(数组)
			template:"#my-temlate-1"	//使用模板
		}	
		var app = new Vue({
			el:"#app",
			data:{
				message:"我是(Vue根实例)父组件的message属性值"
			},
			//注册子组件
			components:{
				//格式   "子组件名称":定义的子组件对象
				"component-a":componentA
			}
		});
	</script>
</html>

父组件访问子组件的数据(子传父)

  • 第一步:在子组件中使用 vm.$emit(事件名,数据) 触发一个自定义事件,事件名自定义。
  • 第二步:父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法,用来获取数据。
  • 总结:子组件通过events(事件)给父组件发送消息,实际上就是子组件把自己的数据发送到父组件
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 使用子组件 itemclick为子组件自定义的事件名称,绑定父组件的函数-->
			<component-a @itemclick="parentclick"></component-a>
		</div>
	</body>
	<!-- 定义模板 -->
	<template id="my-temlate-1">
		<div>
			<!-- 使用v-bind简写方式绑定属性value的值 ,使用v-on简写方式绑定click是事件-->
			<input type="button" v-for="item in categories" :value="item.name" @click="btnclick(item)" />
		</div>
	</template>
	<script type="text/javascript">
		//定义组件
		var componentA={
			data:function() {
				return {
					categories:[
						{id:1,name:"家电"},
						{id:2,name:"玩具"},
						{id:3,name:"数码"},
						{id:4,name:"服装"},
					]
				}
			},
			//注册模板
			template:"#my-temlate-1",
			methods:{
				btnclick:function(item){
					//alert(item.id);
					//子组件向父组件发出自定义事件(自定义事件名称,自定义事件参数)
					this.$emit("itemclick",item);
				}
			}
		}
		var app = new Vue({
			el:"#app",
			//注册局部子组件
			components:{"component-a":componentA},
			methods:{
				parentclick:function(item){ //可以获取子组件传过来的参数item
					alert("我是父组件,子组件id="+item.id);
				}
			}
		});
	</script>
</html>

非父子通信

创建一个Vue实例作为中央事件总线,通过它来监听( o n ) 和 触 发 ( on)和触发( on)(emit)事件。适用于组件间全部通信方式。

//实例Vue实例作为中央事件总线
var Event=new Vue();
//发送事件
Event.$emit(事件名,数据);
//监听事件
Event.$on(事件名,data => {});

假设兄弟组件有三个,分别是 A、B、C 组件,C 组件如何获取 A 或者 B 组件的数据

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<!-- 引入vue.js -->
		<script type="text/javascript" src="js/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<my-a></my-a>
			<my-b></my-b>
			<my-c></my-c>
		</div>
	</body>
	<template id="a">
	  <div>
	    <h3>A组件:{{name}}</h3>
	    <button @click="send">将数据发送给C组件</button>
	  </div>
	</template>
	<template id="b">
	  <div>
	    <h3>B组件:{{age}}</h3>
	    <button @click="send">将数组发送给C组件</button>
	  </div>
	</template>
	<template id="c">
	  <div>
	    <h3>C组件:{{name}},{{age}}</h3>
	  </div>
	</template>
	<script type="text/javascript">
	var Event = new Vue();//定义一个空的Vue实例
	var A = {
		template: '#a',
		data() {
		  return {
		    name: 'tom'
		  }
		},
		methods: {
		  send() {
		    Event.$emit('data-a', this.name);
		  }
		}
	}
	var B = {
		template: '#b',
		data() {
		  return {
		    age: 20
		  }
		},
		methods: {
		  send() {
		    Event.$emit('data-b', this.age);
		  }
		}
	}
	var C = {
		template: '#c',
		data() {
		  return {
		    name: '',
		    age: ""
		  }
		},
		mounted() {//在模板编译完成后执行
		 Event.$on('data-a',name => {
		     this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
		 })
		 Event.$on('data-b',age => {
		     this.age = age;
		 })
		}
	}
	var app = new Vue({
		el: '#app',
		components: {
		  'my-a': A,
		  'my-b': B,
		  'my-c': C
		}
	});
	</script>
</html>

总结组件之间的通讯

在这里插入图片描述

单向数据流

props是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来,即子组件中使用的父组件数据发生变化,无法传导给父组件。而且不允许子组件直接修改父组件中的数据,会直接报错,这样更有利于组件间的解耦

解决方式:

  • 方式1:如果子组件想把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据。
  • 方式2:如果子组件想修改数据并且同步更新到父组件
    • 可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间),推荐使用。

过滤器

过滤数据是我们日常开发中必然会用到的。
常见的场景:当我们从后端请求到数据列表时,我们需要对其中符合条件的数据进行筛选、当我们拿到数据,我们希望把英文首字母大写,等等。

过滤器分为两种

  • 单个组件的过滤器,也叫做局部过滤器,
  • vue实例全局的过滤器,它可以被应用在任何地方。

过滤器使用地方两个位置

  • {{ message | filterA }}双括号插值内
  • <h1 v-bind:id="message | filterA">{{ message }}</h1>v-bind绑定的值的地方

过滤器也可以使用多个,会依次执行

例如:{{ message | filterA |filterB }} 这个例子中会把message 的当做参数传入A过滤器进行过滤,A过滤器过滤完的数据返回值会传入B过滤器

全局过滤器:Vue.filter(“过滤器名称”,函数);

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
	</head>
	<body>
		<div id="app1">
			<h1>我是app1:{{message | upperCase}}</h1>
		</div>
		<div id="app2">
			<h1>我是app2: {{message | upperCase}}</h1>
		</div>
	</body>
		
	<script type="text/javascript">
		//定义全局过滤器
		Vue.filter("upperCase",function(value){
			if(!value) return "";
			value = value.toString();
			//字符转换成大写
			return value.toUpperCase();
		});
		var app1 = new Vue({
			el:"#app1",
			data:{
				message:"HelloWord"
			}
		});
		var app2 = new Vue({
			el:"#app2",
			data:{
				message:"hahahaha"
			}
		});
	</script>
</html>

局部过滤器:定义局部的过滤器 定义格式:fliters:{过滤器名称:函数}

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
	</head>
	<body>
		<div id="app3">
			<component-a :msg="message"></component-a>
		</div>
	</body>
    <!-- 定义模板 -->
	<template id="my-temlate-1">
		<h3>我是子组件,使用了局部过滤器{{msg|capitalize}}</h3>
	</template>
	<script type="text/javascript">
		//定义组件
		var componentA = {
			props:["msg"],
			template:"#my-temlate-1",
			//定义局部过滤器,注意是filters
			filters:{
				//过滤器名称:函数
				capitalize:function(value){
					if(!value) return "";
					value = value.toString();
					value = value.charAt(0).toUpperCase()+value.substring(1); //首字母大写
					return value;
				}
			}
		}
		var app3=new Vue({
			el:"#app3",
			data:{
				message:"ddddd"
			},
			components:{
				"component-a":componentA  //注册局部组件
			}
		});
	</script>
</html>

路由

定义

路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击页面上的about 按钮,页面中就要显示about 的内容。

分类

后端路由

例如,分配一个站点,服务器地址是:http://192.168.1.200:8899,在这个网站中提供了三个界面

http://192.168.1.200:8899/index.html          主页
http://192.168.1.200:8899/about/about.html  关于我们页面
http://192.168.1.200:8899/feedback.html       反馈界面

当我们在浏览器输入 http://192.168.1.200:8899/index.html 来访问界面的时候,web 服务器就会接收到这个请求,然后把 index.html 解析出来,并找到相应的 index.html 并展示出来,这就是路由的分发,路由的分发是通过路由功能来完成的

前端路由

1、虽然前端路由和后端路由的实现方式不一样,但是原理都有是相同的,其中一个方式

前端路由的功能都是通过 hash 「散列值」 来实现的,hash 能兼容低版本的浏览器

2、后端路由每次仿问一个页面都要向浏览器发送请求,然后服务端再响应解析,在这个过程中肯定会存在延迟,但是前端路由中仿问一个新的界面的时候只是浏览器的路径改变了,没有和服务端交互「所以不存在延迟」,这个对用户体验来说是大大的提高。如下所示:

http://192.168.1.200:8080/#/index.html
http://192.168.1.200:8080/#/about/about.html
http://192.168.1.200:8080/#/feedback.html

由于 web 服务器不会解析 # 后面的东西「所以通过 hash 能提高性能」,但是客户端的 js 可以拿到 # 后面的东西,有一个方法是 window.location.hash 来读取,使用这个方法来匹配到不同的方法上

3、举个例子

http://www.xxx.com/path/a/b/c.html?key1=Tiger&key2=Chain&key3=abc#/path/d/e.html

我们把这个地址分析一下

http:协议
www.xxx.com:域名
/path/a/b/c.html:路由,即服务器上的资源
?key1=Tiger&key2=Chain&key3=abc:这 Get 请求的参数
#/path/d/e.html:hash 也叫散列值,也叫锚点

上面的 hash 是和浏览器交互的,其它的都是和服务器进行交互

Vue 路由

Vue 中的路由,推荐使用官方支持的 vue-router

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript" src="js/vue-router-3.5.1.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 打印mine变量是构造函数 -->
			<input type="button" value="打印mine变量" @click="method1" />
			<!-- router-link 显示成超链接 -->
			<router-link to="/main">main</router-link>
			<router-link to="/message">message</router-link>
			<router-link to="/mine">mine</router-link>
			<!-- 路由对应的内容在这里显示-->
			<router-view>
				
			</router-view>
			
		</div>
	</body>
	<!-- 定义模板 -->
	<template id="t_main">
		<div style="height: 400px;width: 400px;background-color: green;">
			{{title}}
		</div>
	</template>
	<template id="t_message">
		<div style="height: 400px;width: 400px;background-color: red;">
			{{title}}
		</div>
	</template>
	<template id="t_mine">
		<div style="height: 400px;width: 400px;background-color: yellow;">
			{{title}}
		</div>
	</template>
	<script type="text/javascript">
		//Vue.extend 使用基础 Vue 构造器函数,通过原型继承,(返回)创建一个“子类”(构造器), 这里只是构造函数 但是还没有实例化所以还不是一个组件对象
		//定义组件构造器main
		var main = Vue.extend({
			data:function(){
				return {
					title:"主页"
				}
			},
			template:"#t_main"
		});
		//定义组件构造器message
		var message = Vue.extend({
			data:function(){
				return {
					title:"消息"
				}
			},
			template:"#t_message"
		});
		//定义组件构造器mine
		var mine = Vue.extend({
			data:function(){
				return {
					title:"我的"
				}
			},
			template:"#t_mine"
		});
		//路由routes配置规则对象
		var routes = [
			//path 是url路径  component是路径所对应的组件构造器或者组件对象
			{path:"/",component:main},
			{path:"/main",component:main},
			{path:"/message",component:message},
			{path:"/mine",component:mine}
		]
		//实例化一个VueRouter对象,routes对象赋值给VueRouter实例对象routes属性
		var router = new VueRouter({
			routes //相当于routes:routes 如果属性名和属性值相同,可以只写一个名称 
		});
		
		var app = new Vue({
			el:"#app",
			//VueRouter对象赋值router属性
			router,  //相当于 router:router
			methods:{
				method1:function(){
					/* 打印mine变量 */
					console.log(mine);
				}
			}
		});
	</script>
</html>

嵌套路由

实际应用界面,通常由多层嵌套的组件组合而成,比如,我们 “首页”组件中,还嵌套着 “登录”和 “注册”组件,那么URL对应就是/home/login和/home/register

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript" src="js/vue-router-3.5.1.js"></script>
	</head>
	<body>
		<div id="app">
			<p>
				<router-link to="/home">首页</router-link>
				<router-link to="/news">新闻</router-link>
			</p>
			<router-view></router-view>
		</div>
	</body>
	<!-- 定义模板 -->
	<template id="home">
		<div>
			<h2>{{title}}</h2>
			<!-- //通过query配置路由参数 key为query  参数为JSON对象,请求的结果为  #/home/login?id=1 -->
			<router-link :to="{path:'/home/login',query:{id:1}}">登录</router-link>
			<router-link :to="{name:'register',params:{'name':'zhangsan'}}">注册</router-link>
			<!-- 路由匹配到的组件将渲染在这里 -->
			<router-view></router-view>
		</div>
	</template>
	<template id="news">
		<div><h2>{{title}}</h2></div>
	</template>
	<template id="login">
		<!-- this.$route.query.id 获取url传参数得值 -->
		<div><h3>{{title}},{{this.$route.query.id}}</h3></div>
	</template>
	<template id="register">
		<!-- this.$route.params.name 获取url传参数得值 -->
		<div><h3>{{title}},{{this.$route.params.name}}</h3></div>
	</template>
	<script type="text/javascript">
		//定义组件
		var componentHome = {
			data:function(){
				return{
					title:"首页"
				}
			},
			template:"#home"
		}
		var componentNews = {
			data:function(){
				return{
					title:"新闻"
				}
			},
			template:"#news"
		}
		var componentLogin = {
			data:function(){
				return{
					title:"登录"
				}
			},
			template:"#login"
		}
		var componentRegister = {
			data:function(){
				return{
					title:"注册"
				}
			},
			template:"#register"
		}
		
		//配置路由(嵌套路由,componentHome,有children配置,就是嵌套路由)
		var routes = [
					//redirect 跳转url,如下当访问 / 跳转到 /home 这个路径
					{path:"/",redirect:"/home"},
					{path:"/home",component:componentHome,children:[
							{path:"/home/login",component:componentLogin},  
							//path路径使用:参数名 占位,在router-link配置中使用params:{'参数名':'参数值'} 补位
							{path:"/home/register/:name",component:componentRegister,name:"register"}, 
					]},
					{path:"/news",component:componentNews},
				]
		
		var router = new VueRouter({routes});
	
		var app = new Vue({
			el:"#app",
			router
		});
	</script>
</html>

使用axios进行ajax操作

Axios简介

​ vue本身不支持发送AJAX请求,需要使用vue-resource、axios等插件实现。

​ axios是一个基于Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对vue-resource进行更新和维护。

​ 参考:GitHub上搜索axios,查看API文档 https://github.com/axios/axios

Axios特点

Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。本质上也是对原生XHR(XmlHttpRequest)的封装,只不过它是Promise 的实现版本,符合新的ES规范,有如下特点:

​ 从浏览器中创建 XMLHttpRequests

​ 从 node.js 创建 http 请求

​ 支持 Promise API

​ 拦截请求和响应

​ 转换请求数据和响应数据

​ 取消请求

​ 自动转换 JSON 数据

​ 客户端支持防御 XSRF

Axios基本用法

​ axios({options})

​ axios.get(url,{options});

GET传参方式:

​ 1.通过url传参

​ 2.通过params选项传参

POST传参方式:

​ axios.post(url,data,{options});

默认情况下,axios将JavaScript对象序列化为JSON。要以application / x-www-form-urlencoded格式发送数据,您可以使用以下选项之一。

传参方式:

​ 1.自己拼接为键值对

​ 2.使用transformRequest,在请求发送前将请求数据进行转换

​ 3.如果使用模块化开发,可以使用qs模块进行转换

Vue中axios中箭头函数的this和function(response)函数体中的this的区别

1、在methods下的函数this指向的是当前创建的vue实例,
2、axios与后台交互后回调函数的内部的this指向window而并非指向当前的vue实例,
3、若想拿到后台回传的数据更新data里的数据,不能在回调函数中直接使用this,要用外部函数定义的变量(如:_this)存储的this,也就是当前vue的实例。
4、使用箭头函数之后,箭头函数指向的函数内部的this已经绑定了外部的vue实例了

Axios的get请求代码示例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript" src="js/axios-0.21.1.js"></script>
	</head>
	<body>
		<div id="app">
			<h1>{{message}}</h1>
			<input  type="button" value="axiox请求1(get)" @click="sendAxiosGet1()"/>
			<input  type="button" value="axiox请求2(get)" @click="sendAxiosGet2()"/>
			<input  type="button" value="axiox请求3(get)" @click="sendAxiosGet3()"/>
			<table border="1px" cellspacing="0px">
				<tr>
					<td>编号</td>
					<td>姓名</td>
					<td>年龄</td>
					<td>邮箱</td>
				</tr>
				<hr/>
				<tr v-for="student in students">
					<td>{{student.id}}</td>
					<td>{{student.name}}</td>
					<td>{{student.age}}</td>
					<td>{{student.email}}</td>
				</tr>
			</table>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				message:"axios的ajax请求",
				students:[{id:1,name:"zhansan",age:18,email:"aa@qq.com"}]
			},
			methods:{
				//ajax使用语法:axios({}).then().catch(),then() 表示ajax请求成功后,处理服务器响应数据,  catch() 表示ajax请求异常或者失败,处理异常或者失败情况 
				sendAxiosGet1:function(){
					var _this = this; //这里的this是Vue对象
					axios({
						method:"get", //请求方式 get/post
						url:"http://rap2api.taobao.org/app/mock/238982/students",  //请求的服务器url地址
						params:{}, //请求的数据参数
						reponseType:"json" , //服务器相应数据的类型
						reponseEncoding:"utf-8" //服务器响应数据的编码格式
					}).then(function(response){ //ajax请求成功后,处理服务器响应数据
						console.log(response);
						console.log(response.data);
						//打印this
						console.log(this);  // 这里的this表示window对象,不是我们想要的Vue对象实例
						console.log(_this);	// _this表示Vue对象实例
						_this.students = response.data.students // 服务端返回的数据赋值给属性students,页面就展示了数据 
					}).catch(function(e){
						console.log(e);
						alert(e);
					});
				},
				sendAxiosGet2:function(){
					var _this = this; //这里的this是Vue对象
					axios({
						method:"get",
						url:"http://rap2api.taobao.org/app/mock/238982/students",  //请求的服务器url地址
						params:{p1:"A",p2:"B"}, //请求的数据参数
						reponseType:"json" , //服务器相应数据的类型
						reponseEncoding:"utf-8" //服务器响应数据的编码格式
					}).then((response)=>{ //ajax请求成功后,处理服务器响应数据  ,ES6的语法 箭头函数,可以解决this的指向问题
						console.log(response);
						console.log(response.data);
						//打印this
						console.log(this);  // 这里的this表示的Vue对象实例
						this.students = response.data.students // 服务端返回的数据赋值给属性students,页面就展示了数据 
					}).catch(function(e){
						console.log(e);
						alert(e);
					});
				},
				//axios的get方法  axios.get(url,{}).then().catch();
				sendAxiosGet3:function(){
					axios.get("http://rap2api.taobao.org/app/mock/238982/students",{
						params:{p1:"A",p2:"B"}, //请求的数据参数
						reponseType:"json" , //服务器相应数据的类型
						reponseEncoding:"utf-8" //服务器响应数据的编码格式
					}).then((response)=>{
						this.students = response.data.students // 服务端返回的数据赋值给属性students,页面就展示了数据 
					}).catch((e)=>{
						console.log(e);
						alert(e);
					});
				}
			}
		});
	</script>
</html>

Axios的post请求和传参方式代码示例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript" src="js/axios-0.21.1.js"></script>
		<script type="text/javascript" src="js/qs-6.10.1.js"></script>
	</head>
	<body>
		<div id="app">
			<h1>{{message}}</h1>
			<input  type="button" value="axiox请求4(post)" @click="sendAxiosPost1()"/>
			<input  type="button" value="axiox请求5(post)" @click="sendAxiosPost2()"/>
			<table border="1px" cellspacing="0px">
				<tr>
					<td>编号</td>
					<td>姓名</td>
					<td>年龄</td>
					<td>邮箱</td>
				</tr>
				<hr/>
				<tr v-for="student in students">
					<td>{{student.id}}</td>
					<td>{{student.name}}</td>
					<td>{{student.age}}</td>
					<td>{{student.email}}</td>
				</tr>
			</table>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				message:"axios的ajax请求",
				students:[{id:1,name:"zhansan",age:18,email:"aa@qq.com"}]
			},
			methods:{
				//ajax使用语法:axios({}).then().catch(),then() 表示ajax请求成功后,处理服务器响应数据,  catch() 表示ajax请求异常或者失败,处理异常或者失败情况 
				//axios的post请求
				sendAxiosPost1:function(){
					axios({
						url:"http://192.168.60.254:8080/20210623/student/list",//请求服务器的url
						method:"post",//请求方式
						// `data` 是作为请求主体被发送的数据 data用于post、put、patch请求
						data:{p1:"A",p2:"B"},//默认情况下,axios-post请求请求参数data对象序列化为JSON
						responseType:"json", //服务器响应数据类型
						responseEncoding:"utf-8" //服务器响应数据编码
					}).then((response)=>{
						this.students = response.data.students;
					}).catch((e)=>{
						console.log(e);
						alert(e);
					});
				},
				//axios的post请求
				sendAxiosPost2:function(){
					axios({
						url:"http://192.168.60.254:8080/20210623/student/list",//请求服务器的url
						method:"post",//请求方式
						//headers 设置请求头类型
						//Content-Type的默认类型是application/json
						headers:{"Content-Type":"application/x-www-form-urlencoded"},
						// `data` 是作为请求主体被发送的数据 data用于post、put、patch请求
						// 要以applicaton/x-www-form-urlencoded格式发送数据
						//Qs.stringify方法把json对象序列化成url形式,以&拼接
						data:Qs.stringify({p1:"A",p2:"B"}),
						responseType:"json", //服务器响应数据类型
						responseEncoding:"utf-8" //服务器响应数据编码
					}).then((response)=>{
						this.students = response.data.students;
					}).catch((e)=>{
						console.log(e);
						alert(e);
					});
				},
                //axios.post(url,data,{}).then().catch()  data表示数据
				sendAxiosAjaxPost3: function() {
					//Qs.stringify() 把json对象序列化url格式,用&连接  p1=A&p2=B
					var paramData = Qs.stringify({
						p1: "A",
						p2: "B"
					});
					axios.post("http://192.168.60.254:8080/20210623/student/list", paramData, {
						// post默认是 参数类型json,服务器要支持json数据格式,希望请求参数 form类型  application/x-www-form-urlecoded
						//设置请求头 请求的数据类型为 application/x-www-form-urlecoded
						headers: {
							"Content-Type": "application/x-www-form-urlencoded"
						},
						responseType: "json", //服务端响应的数据类型
						responseEncoding: "UTF-8" //服务端响应数据的编码
					}).then(response => {
						console.log(response);
						this.students = response.data.students;
					}).catch(e => {
						console.log(e);
						alert(e);
					});
				}
			}
		});
	</script>
</html>

后端代码:

@WebServlet(urlPatterns = {"/student/list"})
public class StudentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String p1 = req.getParameter("p1");
        String p2 = req.getParameter("p2");
        System.out.println("p1=" + p1 + ",p2=" + p2);
        //设置响应数据格式和编码
        resp.setContentType("application/json;charset=utf-8");
        //允许跨域请求(后台允许跨域请求)
        resp.setHeader("Access-Control-Allow-Origin", "*");
        //获取数据
        List<Student> students = getStudents();
        Result result = new Result(students);
        //使用Gson把result对象转换json字符串
        Gson gson = new Gson();
        String json = gson.toJson(result);
        //输出json字符串到前端
        resp.getWriter().write(json);
    }

    /**
     * 获取学生数据集合
     *
     * @return
     */
    private List<Student> getStudents() {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1L,"李四",20,"mm@163.com"));
        students.add(new Student(2L,"王五",21,"mm@163.com"));
        students.add(new Student(3L,"赵六",22,"mm@163.com"));
        students.add(new Student(4L,"钱七",23,"mm@163.com"));
        students.add(new Student(5L,"贵八",24,"mm@163.com"));
        return students;
    }
}
public class Result {
    List<Student> students;

    public Result() {
    }

    public Result(List<Student> students) {
        this.students = students;
    }

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
}
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String email;

    public Student() {
    }

    public Student(Long id, String name, Integer age, String email) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

ult(List students) {
this.students = students;
}

public List<Student> getStudents() {
    return students;
}

public void setStudents(List<Student> students) {
    this.students = students;
}

}


```java
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private String email;

    public Student() {
    }

    public Student(Long id, String name, Integer age, String email) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue学习笔记——第二部分 的相关文章

随机推荐

  • Ansible 介绍安装及其使用(基础)

    Ansible 介绍安装及其使用 基础 1 介绍 Ansible 是一个 IT 自动化工具 它能配置系统 部署软件 编排更复杂的 IT 任务 如连续部署或零停机时间滚动更新 Ansible 用 Python 编写 尽管市面上已经有很多可供选
  • uni-app h5公众号 上传多张图片问题

    因uni app的api不支持安卓手机上传多张图片所以要单独引入用到jssdk uni app的底层不是jssdk 第一步 引入jssdk npm i weixin js sdk 文档 https developers weixin qq
  • 【STM32】cubeMX配置HAL库驱动L298N控制直流有刷电机

    目录 1 电机为什么需要驱动板呢 为什么不能用控制器直接控制电机呢 2 H桥电路介绍 3 L298N原理介绍 4 实物接线图 5 CUBEMX配置 6 代码 7 演示视频 L298N是常用来驱动小型直流有刷电机 两个 和步进电机 一个 的电
  • 求开发代码,ESP32 网络收音机、网络对讲机(使用蓝牙耳机输出输入)

    参考链接 ESP32S2小项目 FM 网络时钟 电台 Arduino开发环境 哔哩哔哩 https www eefocus com circuit 1180016 html https www eefocus com circuit 118
  • 基于ASP的反垃圾邮件管理系统的设计与实现

    随着Internet的迅速普及 电子邮件以其快捷 方便 低成本的特点逐渐成为人们进行信息交流的主要媒介之一 但是随之而来的垃圾邮件也越来越泛滥 垃圾邮件占用了有限的存储 计算和网络资源 耗费了用户大量的处理时间 影响和干扰了用户的正常工作
  • Python 数据文件与网络数据序列化存储详解

    1 ETL简介 大部分可用数据都是存放于文本文件中的 这些数据可以是非结构化文本 如一篇推文或文学作品 也可以是比较结构化的数据 其每一行都是一条记录 多个字段之间由特殊字符分隔 如逗号 制表符或管道符号 文本文件有可能会很大 一个数据集可
  • Oracle绑定执行计划

    Oracle绑定执行计划 在Oracle中时长会出现一直运行正常的SQL突然运行的很慢 检查发现执行计划发生了改变 这时候就需要绑定执行计划 在Oracle 10G以后的版本中可以使用SQL profile或SPM 11g以后 来绑定执行计
  • LaTeX公式保姆级教程

    文章目录 希腊字母 上下标 直立与斜体 分式 根式 普通运算符 函数 大型运算符 标注符号 向量 平均值等 箭头 括号与定界符 多行公式 大括号 矩阵 实例仅供参考 希腊字母 pi pi delta
  • Loadrunner11.0安装与简单使用

    Loadrunner下载 https pan baidu com s 1TtBlfp9W7FM8MVjmxa5Irw 提取码 96d0 1 解压loadrunner与破解包 2 打开文件夹运行setup exe 3 点击loadrunner
  • 【华为OD机试真题 Python】英文句子倒序

    前言 本专栏将持续更新华为OD机试题目 并进行详细的分析与解答 包含完整的代码实现 希望可以帮助到正在努力的你 关于OD机试流程 面经 面试指导等 如有任何疑问 欢迎联系我 wechat steven moda email nansun09
  • hive报错:Call from hostname/127.0.1.1 to localhost:9000 failed on connection exception.主节点9000端口拒绝访问.

    1 美图 2 背景 启动hadoop base lcc lcc hadoop 2 7 4 sh sbin start all sh This script is Deprecated Instead use start dfs sh and
  • windows server 2012 r2关于vmtools安装失败以及KB2919355安装

    windows server 2012 r2关于vmtools安装失败以及KB2919355安装 前言 VMware workstation15安装windows server 2012 r2 安装不了vmtools 解决方法 1 安装低版
  • OpenCV中QR二维码的生成与识别(CIS摄像头解析)

    1 QR概述 QR Quick Response 属于二维条码的一种 意思是快速响应的意思 QR码不仅信息容量大 可靠性高 成本低 还可表示汉字及图像等多种文字信息 其保密防伪性强而且使用非常方便 更重要的是QR码这项技术是开源的 在移动支
  • python 注解annotation_Annotation注解(一)- 基础

    这篇博客 主要讲解关于注解的一些基本知识 包括注解的概念 分类 作用 常见注解的定义及其解析方式等 Annotation的概念 1 概念 关于Annotation注解的概念 我们可以看下官方的解释 Annotations a form of
  • 大数据:大规模文件系统及map-reduce

    大数据 大规模文件系统及map reduce 下面是我看 大数据 互联网大规模数据挖掘与分布式处理 一书第二章的总结 1 分布式文件系统 distributed file system 文件多副本存储 计算任务分多个 容错 文件非常大 TB
  • Linux学习之内核Oops详解

    什么是Oops 从语言学的角度说 Oops应该是一个拟声词 当出了点小事故 或者做了比较尴尬的事之后 你可以说 Oops 翻译成中国话就叫做 哎呦 哎呦 对不起 对不起 我真不是故意打碎您的杯子的 看 Oops就是这个意思 在Linux内核
  • 学习笔记 - Hadoop-Hive 介绍

    学习笔记 Hadoop Hive 介绍 1 背景 当前用户数据都是以 亿 为单位进行考量 传统数据库无法满足快速增长的海量数据存储需求 其计算和处理能力也大大不足 数据仓库有分布式存储与处理能力 将各种数据源整合集成到统一的数据中心 防止数
  • 辗转相除法、相减法求两自然数最大公约数和最小公倍数

    l 辗转相除法 算法描述 辗转相除法是求两个正整数的最大公约数的一种算法 有两整数a和b a b得余数c 若c 0 则b即为两数的最大公约数 若c 0 则a b b c 再回去执行 例如求27和15的最大公约数过程为 27 15余1215
  • 【HIT-计算机系统】ICS-Lab2 DataLab

    第1章 实验基本信息 1 1 实验目的 熟练掌握计算机系统的数据表示与数据运算 通过C程序深入理解计算机运算器的底层实现与优化 掌握VS CB GCC等工具的使用技巧与注意事项 1 2 实验环境与工具 1 2 1 硬件环境 x64 CPU
  • Vue学习笔记——第二部分

    Vue组件的定义 注册方式和模板使用 组件的定义 组件 Component 是 Vue js 最强大的功能之一 组件可以扩展 HTML 元素 封装可重用的代码 vue组件是把页面 html代码 CSS代码 进行模块化 如下图所示 一个页面分