三阶段week1

125 阅读14分钟

day01 二阶段的JavaScript开发场景: 1、老公司 2、老项目 3、面试笔试 - js是原理 一切的框架的目的都是为了简化JavaScript:准确来说都是为了简化DOM操作

1、vue介绍:

建数据驱动的web应用开发框架,属于前端框架。(vue几乎不会用DOM操作)
	为什么如此受欢迎?
	1.声明式渲染,应对前后端分离开发大趋势
	2.渐进式框架,适应各种业务需求以及各种场景(从小到大都可以省略)
	3.更适合做移动端开发,SPA页面(单页面开发) - 效率更高
	4.快速交付,结合第三方UI框架组件库进行快速开发 - 比如elementUI、VantUI
	5.企业需求,必备技能(vue,react)
	6.中国自己的框架(借鉴了react和angular)

vue是一个属于mvvm架构的框架:什么是mvvm?
	m - model:模型数据
	v  - view:视图
	vm - ViewModel控制器
	我们一般都统称为mv*架构:mvc、mvp、mvvm
开发环境搭建:两种方式
	1、下载引入:vue.js
	2、vue-cli - 脚手架 - 新手不推荐

2、vue开发模板

new Vue({
	el:"#box",//只有在id为box的div里才可以使用vue的语法
	data:{//这里面放的是变量
		变量名: 值,
	},
	methods:{//这里面放的是函数
		函数名(){
			操作
		},		
	}	
})

3、插值表达式:{{变量}} - 再HTML上实现了一个基本的js环境,可以进行js运算、放入变量、三目运算、API操作...

4、vue的指令:再HTML上写着v-xxx的特殊属性

v-html:底层就是innerHTML,做了简化操作,可以渲染标签,其实就是添加了内容
	比如:<elem v-html="变量"></elem>

v-for:底层就是for in循环,做了简化操作,可以遍历数组
	比如:<elem v-for="(v,i) in 数组名">{{v}}</elem> - 会根据数组渲染出多个元素,拥有下标和值
	注意:()写不写都无所谓

v-modal:具有双向数据绑定功能,页面可以控制变量,变量也可以控制页面
	比如:<input v-modal="变量名"> - input的默认值就为此变量,并且input修改内容,变量也会跟着一起变化

v-show:隐藏和显示,传入的是一个布尔值,根据你的布尔值进行显示隐藏,如果为true则显示,如果为false则隐藏,底层:设置display为none/block
v-if:是否渲染页面,传入的是一个布尔值,根据你的布尔值进行显示隐藏,如果为true则显示,如果为false则隐藏,底层:appendChild/remove
	比如:<elem v-show/if="布尔值"></elem>

v-bind:属性名 - 操作动态的属性:简写为:属性名
	<a :class="变量" :href="变量"></a>

v-on:事件名 - 绑定事件,简写为:@事件名="函数名"
	<a @事件名="函数名"></a>

5、vue2的操作样式

1、class操作样式:
	<div :class="obj">文字</div> - 对象口味的语法糖通过下方代码,最终class有aa和bb为true,则带有此class,cc为false说明不需要
	<div :class="arr">文字</div> - 数组口味的语法糖通过下方代码,最终class有aa和cc

		new Vue({
			el:"#box",
			data:{
				obj:{ - 样式class对象口味写法
					aa:true,
					bb:true,
					cc:false, - 注意后续不能用js直接添加dd,不能直接追加新属性和值,vue底层具有拦截机制,想要添加:Vue.set(vm对象.obj,"dd",true);
				},
				arr:["aa","cc"] - 样式class数组口味写法,可以随便的添加和删除,更加的随意简单:vm对象.arr.push("dd");
			},
			methods:{

			}
		})

2、style内联样式操作
	<div :style="obj">文字</div> - 对象口味的语法糖通过下方代码,最终style内联样式,要有的内容需要搭配下面的代码
	<div :style="arr">文字</div> - 数组口味的语法糖通过下方代码,最终style内联样式

		var vm=new Vue({
			el:"#box",
			data:{
				obj:{
					background:"red",
					width:"300px",
					height:"300px",
					border:"1px solid #000",
					borderRadius:"50%",
					overflow:"hidden" - 注意后续不能用js直接添加新样式,不能直接追加新属性和值,vue底层具有拦截机制,想要添加:Vue.set(vm对象.obj,"css属性名","css属性值");
				},
				arr:[
					{background:"red",},
					{width:"300px",},
					{height:"300px",},
					{border:"1px solid #000",},
					{borderRadius:"50%",},
					{overflow:"hidden"}, - 样式class数组口味写法,可以随便的添加和删除,更加的随意简单:vm对象.arr.push({"属性名","属性值"});
				]
			},
			methods:{

			}
		})

6、vue3的操作样式:

1、模板写法就不一样
		Vue.createApp({
			data(){
				return {
					变量名:值,
				}
			},
		}).mount("#box");

2、反而vue3操作样式不用担心vue2的问题,之前的注意点就可以忽视了,对象可以直接用老JS语法添加属性了

7、条件渲染:就是v-if的升级版

		<ul>
			<li v-for="v in datalist">{{v.name}} - 
				<span v-if="v.state===0">未付款</span>
				<span v-else-if="v.state===1">待发货</span>
				<span v-else-if="v.state===2">已发货</span>
				<span v-else>已完成</span>
			</li>
		</ul>
		通过这些代码,我们可以实现根据json数据渲染页面,并且判断状态的不同显示不同的span文字

8、列表渲染:

1、v-for:遍历数组、遍历、甚至是一个数字
	<ul>
			<li v-for="v in 数据名" :key="v.id">{{v}}</li> - 遍历数字基本没有意义,不管是遍历对象还是数组,前面始终是值,后面始终是下标
	</ul> 

2、虚拟DOM:数据->vue变为虚拟DOM:JS对象描述的一个节点,然后在和真实DOM进行比较,考虑要不要替换真实DOM->真实DOM
	新的数据会生成新的虚拟DOM,然后VUE底层会使用diff算法拿着新的虚拟DOM和老的对象,找不同
	找到不同后,会更新出一个补丁,渲染到真实DOM之中,这样的好处就是代价更小(性能)
	为什么说虚拟DOM代家更小呢,因为真实DOM非常复杂,有很多很多的属性,但是虚拟DOM只需要重要的属性就够了
	理想情况:key="v.id",千万不要用下标当做key
	目的:高效复用DOM
	面试题:为什么li要添加key?

3、数组更新检查:
	1、以下方法操作数组,可以检测变动:- 强烈推荐
		push/pop/unshift/shift/splice/sort/reverse

	2、filter/concat/slice/map - 不会修改原数组,会返回一个新数组,我们可以用新数组再去【覆盖】原数组 - 一般般

	3、不能和检测以下变动的数组
		arr[下标]=新值;

		但是vue3不必担心此问题:已解决
       
       

day002

1.事件处理器:

绑定事件指令:@事件名="函数名()";
特殊:1、函数名的(),如果不传参数,其实可以省略
       2、如果调用时,没有加(),我们的函数甚至会自动获得一个形参 - event对象
       3、如果调用时,希望能使用event对象,又想传入自己的实参,那么你必须写为
	@事件名="函数名($event,实参1,实参2,...)"; - 强调:$event名字不能变!

案例:点击一个按钮,使页面上的一个数字+1

2、事件修饰符:

@事件名.stop="函数名()"; - 阻止冒泡
@事件名.self="函数名()"; - 只有点击自己才会触发
@事件名.prevent="函数名()"; - 阻止默认行为
	
甚至按键修饰符:
	@keydown.enter="函数名()" - 只有回车键才会触发
	@keydown.ctrl="函数名()" - 只有回车键才会触发
	除了这两个,还有很多:.esc    .up   .down  .left   .right   .space   .shift   .delete,甚至还可以组合使用,甚至还可以.键码

都是简化event

3、表单控件绑定

1、多选框:想要知道选中没有,现在非常简单
	<input type="checkbox" v-model="变量">
	变量值要求必须是一个布尔值,如果为true则为选中,false则为不选

2、如果多个多选框,希望判断选中否
	<input type="checkbox" v-model="变量" value="值1">
	<input type="checkbox" v-model="变量" value="值2">
	<input type="checkbox" v-model="变量" value="值3">	
	此时的变量需要保存的是一个数组,数组根据传入的value,让对应的多选框勾选成功

3、单选框:判断选中谁
	<input type="radio" v-model="变量" value="值1">男
	<input type="radio" v-model="变量" value="值2">女
	勾选中,此变量会自动保存单选框的value值

切记:1、单选框和多选框不要使用点击事件,否则时机不对(得到点击之前的东西),需要使用change事件
           2、数据驱动页面

4、表单修饰符:
	v-model.lazy="变量" - lazy懒惰,只会在失去焦点时获取到用户输入的内容,提升性能
	v-model.number="变量" - 自动隐式转换为数字的操作
	v-model.trim="变量" - 自动去掉字符串开头结尾的空白字符

4、计算属性

var vm=new Vue({
	el:"",//挂载页面元素
	data:{},//模型数据
	methods:{},//放函数
	computed:{
		函数名(){
			return 结果;//注意此部分叫做计算属性,很像一个函数,但是必须加return返回值,而且在使用时不能加()调用
				   //虽然看上去更加麻烦了,但是js中就应该放入逻辑,HTML上不推荐
				   //但是methods调用几次就会执行几次,但是computed调用多次只要数据不变的情况下只会执行一次
				   //methods可以说是专门为事件准备的,computed不能绑定在事件上,那他用来干什么?
				   //只要以后有跟计算相关的都放到computed里面 - 【重在结果】
		}
	},
})

5、监听属性:

var vm=new Vue({
	el:"",//挂在页面元素
	data:{},//模型数据
	methods:{},//放函数
	computed:{},
	watch:{
		变量名(new,old){//监听,能时刻监听到数据的变化,甚至是异步数据,比如:input不需要再用@input事件了
			
		}
	}
})

方法methods->事件绑定,不可以用return 计算computed->重视结果,解决模板过重的问题,必须要有return,只求结果,不支持异步,只能同步! 监听watch->重视过程,监听一个值的改变,不用返回值,支持异步的


1、fetch:ES6提供的一个新功能,类似于ajax - 是标准方法

 以前原生ajax,是一个设计粗糙的API,配置和调用方式非常繁琐
 而且基于事件的异步模型写起来不友好
 fetch缺点:兼容性不好,我们可以用caniuse.com这个网站看看哪些技术支持哪些浏览器
 
 语法:
	1、fetch - get
		fetch("路径.json").then((res)=>res.json()).then((res)=>{
			res要干什么操作
		})

	2、fetch - post
		fetch("路径.json",{
			method:"POST",
			headers:{
				"Content-Type":"application/x-www-form-urlencoded"
			},
			body:"name=dy&pwd=123123"
		}).then((res)=>res.json()).then((res)=>{
			res要干什么操作
		})
		

2、axios:是一个第三方的请求方式,但是比fetch更简单更好用,而且vue作者也非常推荐

1、记得先引入,后使用
语法:
	1get方式
		axios.get("路径.json","请求消息").then(res=>{
			res.data->拿到数据
		})

	2、post方式:
		axios.post("路径.json","请求消息").then(res=>{
			res.data->拿到数据
		})

day003

组件:组成页面一部分的部件比如:导航条,轮播,侧边栏,底部,抽屉

1.为什么组件化:

vue强烈推荐组件化思想:拓展HTML元素(自定义标签),封装可以【重用】的代码

2.组件的创建/注册方式

1、全局/局部组件
	//全局组件
	Vue.component("全局组件名",{
		template:"<div css/js>内容
				<局部组件名></局部组件名>
			</div>", - html模板
		data(){return {}},
		methods:{},
		...//之前的模板语法都是支持的,但是data必须写为函数式写法,vue3的语法
		components:{//局部组件
			"局部组件名":{
				套娃
			}
		}
	})
	//以前这个new Vue({})我们可以看作是一个根组件
	使用:在HTML直接写双标签,你的组件名就是标签名:<全局组件名></全局组件名>
	注意:1、起名字,如果js写驼峰,html不支持,必须替换写为横线连接符-
	          2html片段,没有代码提示,没有高亮显示,但是不担心 - 以后vue单文件组件解决
	          3css只能写成内联样式 - 以后vue单文件组件解决
	          4template只能包含一个根节点
	          5、组件是一座孤岛,无法直接访问外面的组件的状态和方法 - 需要使用间接的组件通信才可以解决
	          6data必须写为函数时写法,vue3的语法
	          7、所有的组件都放在一起的话,太乱了太丑了 - 以后vue单文件组件解决
	何时使用全局或局部:
		1、如果一个组件只会使用过一次推荐定义为局部
		2、如果一个组件在不同的页面或者各个组件中都会使用到,推荐全局

3、组件通信-父传子:提升组件的复用性

比如:一个网页上任何一个页面都有一个导航条,但是显示效果可能不同,我们也可以实现一个组件,传入不同的参数进行通信
	<div id="box">
		<paoge-navbar></paoge-navbar>
		<paoge-navbar 自定义属性="值/根组件的变量"></paoge-navbar>	-    自定义属性用来进行传参
	</div>

	Vue.component("paogeNavbar",{
			template:`<div style="background:red;">
				<button v-show="bool"><</button>
				<span>{{自定义属性}}</span>
				<button>></button>
			</div>`,
			//props:["自定义属性",...],//第一种写法 数组语法糖
			props:{//第2种写法 对象语法糖
				自定义属性:{
					type:String/Number/Boolean,
					default:"默认值,不传自定义属性的时候使用的"
				}
			},
	}

4、组件通信-子传父:但是封装了组建后,完成开关门

		<div id="box">
			<navbar @自定义事件名="爸爸的函数名"></navbar>
		</div>

		Vue.component("navbar",{
			template:`
				<div style="background: red;">
					<button @click="change">三</button>
					导航条				
				</div>
			,
			methods:{
				change(){
					this.$emit("自定义事件名");
				}
			}
		})

		//一个页面只能有一个这个【根组件】
		new Vue({
			el:"#box",
			data:{
				bool:true,
			},
			methods:{
				爸爸的函数名(){
					console.log("父组件定义的事件,操作");
				}
			}
		})	

//总结:
	父传子 - 用自定义属性搭配props
	子传父 - 用自定义事件搭配this.$emit("自定义事件名")

5、非父子关系通信

bus:中央事件总线,实现较为复杂的通信

创建:var bus=new Vue();

方法:2个:使用前,考虑清楚谁是发布者,谁是订阅者,订阅者需要使用生命周期mounted来触发 - dom渲染完毕后
	1、订阅者:
		bus.$on("自定义名称",(data)=>{
			data->下方发布者传输的数据
		})

	2、发布者:
		bus.$emit("自定义名称",传输的数据);

6、refs:父组件可以随意的摆弄子组件(获取/修改)

ref - 绑定在dom节点上,拿到的就是这个dom对象
ref - 绑定在组件上,拿到的就是当前组件对象
<组件 ref="自定义名称"></组件>

根组件中:
	this.$refs - 得到所有添加了ref属性的组件对象
	this.$refs.自定义名称 - 拿到某个子组件对象
	this.$refs.自定义名称.变量 - 拿到某个子组件对象上的变量

组件注意:

1、ref和refs是固定关键字,不能修改
2、他打破了传统的通信流程,比如我们想要获取一个input的value值,再vue中可以用v-model,确实很棒,但是react中没有,则可以使用ref完成
3、尽量不要使用组件中的props去改变状态data,会导致数据流混乱(不易读) - 不推荐,也没有意义
4、如果组件中写了一个指令v-once,一次性的,状态改变,页面上的组件也不会变化,只需要打开页面渲染一次时
5、内置组件:
	<component :is="组件名"></component> - 告诉他哪个需要显示
	<keep-alive></keep-alive> - 活着,就算选项卡切换,回来依然存在你输入的东西

以上包含了组建的通信,都要一个给,一个拿

面试题:Vue组件的通信有哪些方式?
	1、父传子 - 用props自定义
	2、子传父 - 用this.$emit("自定义事件")
	3、兄弟:中间人模式
	4、bus
	5、refs
	6、vuex - 状态管理器,最舒服,Vue由三部分组成:vue基础+vue router+vuex

day004

1、slot:插槽,组件标签中默认是不允许再嵌套别的标签的,所有提供了slot扩展组件能力,提高了组件的复用性

比如:
	<组件>
		<template v-slot:名字>
			<span>111111111</span>
			<span>222222222</span>
			<span>333333333</span>
		<template>
		<template>
			<span>777777777</span>
			<span>888888888</span>
			<span>999999999</span>
		<template>
		<span slot="user">个人中心</span>
		<span>111111111</span>
		<span>222222222</span>
		<span>333333333</span>
		<span>777777777</span>
		<span>888888888</span>
		<span>999999999</span>
	</组件>

	默认是不允许再嵌套别的标签的,但是搭配上slot就可以了,以下代码教你如何搭配
		Vue.component("组件",{
			template:`
				<div>
					<span>navbar</span>
					<slot name="user"></slot> - 用上你写的<span slot="user">个人中心</span>
					<slot></slot> - 用上所有没有名字的slot
				</div>
			`
		})
                    

2、过渡:添加动画

语法:
<transition enter-active-class="开始动画的class" leave-active-class="离开动画的class">
	<div v-show="isShow">11111111111111111111111</div>	
</transition>

<transition name="class的前缀">
	<div v-show="isShow">11111111111111111111111</div>	
</transition>

注意:
	1、如果希望一打开页面就有一次动画,可以在transition标签上添加一个appear
	2、如果多个元素过渡,别用v-show,使用v-if v-else
		<transition name="paoge" mode="out-in">
			<div v-if="isShow" key="1">11111111111111111111111</div>	
			<div v-else key="2">22222222222222222222222</div>	
		</transition>
	3、多个组件实现过渡,同上
		<transition name="paoge" mode="out-in">
			<component :is="变量"><component>
		</transition>
	4、列表ul li过度
		<transition-group name="paoge" tag="ul">
			<li v-for="(v,i) in arr" :key="v">
				{{v}} - <button @click="del(i)">x</button>
			</li>
		</transition>

3、组件的生命周期:一共8个,4组,自动再不同的时刻自动触发,没写则不行

面试中:问vue的生命周期、组件的生命周期、组件的钩子函数、组件的生命周期钩子函数,都是在问同一个问题
new Vue({
	data:{},
	beforeCreate(){
		//没用
	},
              *created(){
		发起ajax
	},
	beforeMount(){

	},
              *mounted(){
		发起ajax、找到dom后触发js操作(swiper自己的js应该再此处执行)
	},
	beforeUpdate(){

	},
              *updated(){

	},
	beforeDestroy(){////没用
		console.log("清除定时器,事件解绑")
	},
	Destroyed(){////没用
		console.log("清除定时器,事件解绑")
	}
})

4、swiper:www.swiper.com.cn/usage/index…

day005

1、Vue3组件的定义:

var obj={
	data(){
		return {

		}
	},
	methods:{},
	...
}

var app=Vue.createApp(obj);

app.component("组件名",{
	template:`<root></root>`
})

app.mount("#box");

注意:Vue3除了语法不同,生命周期中的两个销毁也不同:beforeUnmount、unmounted
    
    

2、自定义指令:为了操作底层dom,作者给我们留了方案,我么们可以自定义指令

            何时:可以通过指令知道什么时候dom创建完成,从而进行以来都dom的库(swiper)的初始化操作(new Swiper)

创建指令:
	Vue.directivee("指令名别加v-",{
		//指令的生命周期
		inserted(el,binding){
			el->当前使用此指令的元素
			binding->对象,binding.value->拿到用户传给我们的数据
		},
		mounted(el,binding){
			el->当前使用此指令的元素
			binding->对象,binding.value->拿到用户传给我们的数据
		},
		update(el){
			el->当前使用此指令的元素
			binding->对象,binding.value->拿到用户传给我们的数据
		}
	})

简化:
	Vue.directivee("指令名别加v-",(el,binding)=>{
		el->当前使用此指令的元素
		binding->对象,binding.value->拿到用户传给我们的数据
	})

注意:1、vue3的指令的生命周期 变化了, 约等于 组件的生命周期
           2this.$nextTick(()=>{
		比updated执行的都要晚,new Swiper(".swiper",{})
                 })