vue 知识梳理

回过头,把vue的知识点梳理一遍.?

组件

	<head>
		<meta charset="utf-8">
		<title></title>
	</head>	
	<body>
		<div id="root">
			<table>			
				<tbody>
					<myrow></myrow>
					<myrow></myrow>
					<myrow></myrow>										
				</tbody>
					/* 初学者都容易这样写:
						认为在vue全局申明组件之后,直接在标签内写上申明的组件名即可.
						这里虽然可以成功渲染.但是渲染出来的层级是不对的.
						我们会发现这样一种层级:
							tbody
								myrow
						        myrow
   								myrow
   								tbody
					   很明显,我们希望将myrow显示在tbody内部:									
					   但基于h5语法,在tbody下需要存放的应该是tr,
					   然而我们想要显示的确是自己的myrow组件.
					   于是高潮来了:					
					*/				
				<tbody>
					<tr is="myrow"></tr>
					<tr is="myrow"></tr>
					<tr is="myrow"></tr>
				</tbody>
				/*我们在tbody下写上tr,再在tr上添加vue的is属性,他的意思是,
				  虽然这里是tr标签,但我们真正需要渲染出来的是 "myrow"组件.
				  此时就都解决了
				*/	
				/*
				一定要注意的是: 这个bug是出自于h5,比如 :
					ul 下的标签最希望的li,
					select 下的  最希望是 option等
					所以玩组件,一定要回头看层级,谨记!
				出了bug , 请使用is属性解决
				*/							
			</table>
		</div>
	</body>
	Vue.component("myrow",{
		template:"<tr><td>this is a row</td></tr>"
	})
	
	var vm = new Vue({
		el:"#root"			
	})

ref 与 refs

虽然vue不推荐操作dom,但在某些时候,比如针对"动画"需求的时候,
仅仅操作数据就显得力不从心了,我们在vue中,使用ref 和 refs的组合操作dom

	<div  ref="hello" @click="handleclick()"> hello world</div>
	var vm = new Vue({
			el:"#root",
			methods:{
				handleclick:function(){
					alert(this.$refs.hello.innerHTML);
					//在这里如此操作即可成功操作dom
				}
			}
		})

注意

ref 配合着 refs  写在标签上的时候,获取到的是这个标签的dom元素
而写在组件上的时候,代表的是引用

Demo 写一个累加器

	<div id="root">
		<com ref="one" @change='totaladd()'></com>
		<com ref="two" @change='totaladd()'></com>
		<div>{{total}}</div>		
	</div>
	Vue.component("com",{
		template:"<div @click='handleClick()'> {{num}} </div>",
		data(){
			return {
				num:0
			}
		},
		methods:{
			handleClick(){
				this.num++;
				this.$emit("change");
			}			
		}
	})	
	var vm = new Vue({
		el:"#root",
		data(){
			return{
				total:0
			}
		},
		methods:{
			totaladd(){
				this.total = this.$refs.one.num+this.$refs.two.num
			}
		}
	})
	

父组件与子组件之间的信息传递:

父组件通过 属性(加冒号)的形式向子组件传递信息,子组件使用props接收

	<div id="root">
	
		//如果拿属性传递,那么传递的将是 number类型的1
		// 直接传递,传递的将是字符串类型的 1
		<counter :count="1"></counter>
		<counter :count="2"></counter>
	</div>

注意:

vue中单项数据流 :  多个子组件使用一个父组件的传递的数据,为了防止某个子组件修改数据,导致所有子组件数据紊乱,
所以不可以违背单项数据流,如果想修改某个数据,可以在子组件上定义一个变量,将传递来的数据给该变量赋值,
再去修改该变量即可.
否则报  "warn警告"
	var counter = {
		// 接受传递后  使用props 接收值
		props:["count"],
		//插值表达式 渲染
		template:"<div @click='handelClick()'>{{count}}</div>",
		//为了遵循单项数据流 而定义的对象
		data(count){
			return {
			num :this.count
			}
		},
		methods:{
			handelClick(){
				num++
			}
		}
	}
	var vm = new Vue({
		el:"#root",
		//申明,组件注册
		components:{
			counter:counter
		}
	})

子组件向父组件传值 : 通过事件传值

this.$emit.("事件名称")

$emit 可以接受多个参数,首个参数是事件名,后面的会被作为 参数 传递给监听的函数

	<div @inc="handle"></div>	//被emit监听触发后,会执行 handle函数
	
	this.$emit.("inc",5);	//给div写监听  这个inc是个可随便写的,并不仅拘泥于 inc
	
	handle(step){
		console.log(step);	//5  step 是emit的第二个参数
	}
	//这就代表着

组件数据传递校验


	//html
	<child content="abcdef"></child>
	Vue.component('child',{
			//  props:['content'], 此时content是一个字符串 
			//  如果我们想对传递来的数据进行约束(参数校验) 可以这样写
		// props:{
		// 	content:[String,Number,Object]
		// },
		 	//如果上述 写成<child :content="123"></child>  
			//那么 vue会报一个warn 因为加上冒号 传递来的是一个 number类型
			//如果 <child content="123"></child>   就没有问题 ,因为传递来的是一个字符串了
			//写成 props:{content:[String,Number]}  表示传递来的数据既可以是数字,也可以是字符串
			
		//另一种写法:
		props:{
			content:{
				type:String,		//表示传递来的数据是对象类型
				required:false,		//且 必须传递 不传递会报错
				default:"{a:4}",		//设置默认值,即便有了默认值,不传递的情况下,也会报错
				validator:function(content){	//判断传递过来的数据 长度等具体属性
					return (content.length >2)	//校验失败 则报错
				}
			}
		},				
			template:'<div>{{content}}</div>',
			data(){
				return{
					message:0
				}
			}
		})
		var vm = new Vue({
			el:"#root"
		})

为组件绑定原生事件

在之前我们希望直接让组件触发事件,需要使用$emit.("事件名").
经过两层迂回才可以触发,实际上并不需要这样麻烦,直接在最外层的@click后面添加.native即可
	<mycomponent @click.native="hancleClick()"></mycomponent >

非父子组件之间的数据传递(Bus/总线/发布订阅模式/观察者模式)


	//html
	<div id="root">
		<child  content="Juno"></child>
		<child  content="Mak"></child>
	</div>	
	//js			
	Vue.prototype.bus = new Vue();
		Vue.component("child",{
			//定义一个mycontent  为了遵守单项数据流
			data(){
				return {
					mycontent:this.content
				}
			},
			//数据校验
			props:{
				content:{
					type:String
				}
			},			
			template:"<div @click='handleClick'>{{mycontent}}</div>",
			methods:{
				handleClick:function(){
				//  使用bus向外部触发事件  $emit(change),并传递mycontent
					this.bus.$emit("change",this.mycontent);
				}
			},
			//挂载
			mounted:function(){
				var _this = this;
				// 使用bus进行监听  bus是vue的实列,也有on方法
				this.bus.$on("change",function(msg){
					_this.mycontent = msg
				})
			}
		})
		var vm = new Vue({
			el:"#root"
		})

插槽 slot

	//html
	<div id="root">
			<child>
				<!--1. 我们首先在定义的子组件内部写上想要渲染的数据 -->
				<p>dell</p>
			</child>
		</div>
	//js
	Vue.component("child",{
			//2.然后在template中写上<slot></slot>即可
			// 注意: 插槽支持添加默认值,如果子组件内部没有添加任何内容,那么插槽才会显示默认内容
			//否则不显示默认内容
			template:`<div><slot>我是插槽默认值</slot></div>`
		})
		
		var vm = new Vue({
			el:"#root"
		})

新需求 :如果有两个插槽,如何让他们有顺序地摆放呢?
具名插槽!

    	//html
	<div id="root">
			<child>
				<!--1. 我们首先在具名插槽上规定slot="???" 具体的名字 -->	
				<div slot="headerslot">1</div>
				<div slot="footerslot">2</div>	
				<p>dell</p>
			</child>
		</div>
	//js
	Vue.component("child",{
			//2.然后在slot中写上对应的name即可
			template:`<div><slot name="headerslot">我是插槽默认值</slot>
						<div>content</div>
						<slot name="footerslot">我是插槽默认值</slot></div>`
		})
		
		var vm = new Vue({
			el:"#root"
		})

注意: 无论是插槽还是具名插槽,都可以含有默认值;触发的时机是在组件中未定义的时候. 插槽默认值还支持标签(h5语法都可以:类名\id\内联css)

作用域插槽

slot

动态组件

v-once

	方法只执行一次

axios

axios 已经 取代vue-resource,成为vue全家桶中官方的请求插件。

axios get方法

get方法的请求体 一定需要用params包裹 谨记!

	axios.get("www.123.com/getId",{
		params:{
			userId: "4536",
			Islike: "1",
			count: "15"
		},
		headers: {
			token: "2hu9Xw9d_Dh29doFWs8__82nndn7cq234d8Ete2t75G458D5f44"
		}
	}).then(function(res){
		console.log(res)
	}).catch(function(err){
		console.log(err)
	})

axios post方法

post方法有三个参数:
	第一个参数:“请求的域名" --- str
	第二个参数:"请求体" --- obj
	第三个参数:"请求头" --- obj
	axios.post("www.123.com/getId",{
		userID: "888"
	},{
		headers: {
			token: "Tom"
		}
	}).then(function(res){...}).catch(function(err){...})

http请求

	axios({
		url: "www.123.com/userid",
		methods: "get",
		data: {userID: "001"},
		headers:{token:"2hu9Xw9d_Dh29doFWs8__82nndn7cq234d8Ete2t75G458D5f44"}
	}).then(res=>{}).catch(err=>{})

axios的拦截器

下面的代码优先会打印 request init,
再执行后续操作
	axios.interceptors.request.use(function(config){
		console.log("request init.");
		return config;
	})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值