前端js基础汇总(一)

一、谈谈标准盒模型和怪异盒模型(IE盒模型)

盒模型分为标准盒模型和怪异盒模型(IE模型)

	box-sizing:content-box  //标准盒模型
	box-sizing:border-box  //怪异盒模型
标准盒模型 元素的宽度等于style里的width+margin+padding宽度

标准盒模型:元素的宽度等于style里的width+margin+padding宽度

如下代码 整个宽高就是120px
div{
	box-sizing: content-box;
    margin: 10px;
    width: 100px;
    height: 100px;
    padding: 10px;
}

怪异盒模型:元素宽度等于style里的width宽度

如下代码 整个宽高就是100px
div{
	box-sizing: content-box;
    margin: 10px;
    width: 100px;
    height: 100px;
    padding: 10px;
}

二、rem与em的区别

	rem是根据根的font-size变化,而em是根据父级的font-size变化
rem:相对于根元素html的font-size,假如html为font-size:12px,那么,在其当中的div设置为font-size:2rem,就是当中的div为24px
em:相对于父元素计算,假如某个p元素为font-size:12px,在它内部有个span标签,设置font-size:2em,那么,这时候的span字体大小为:12*2=24px

三、水平垂直居中的几种方式

1、定位 上下左右0+margin:auto;
2、定位 l50% t50% translate(-50%,-50%)
3、定位 l50% t50% ml:-宽度一半 mt:-高度一半;
4、父元素 line-height:200px font-size:0;
子元素 inline-block vertical-align:middle
5、弹性布局 父 display:flex justify-content:center; align-items:center;

四、谈谈闭包

什么是闭包
函数A 里面包含了 函数B,而 函数B 里面使用了 函数A 的变量,那么 函数B 被称为闭包。
	function A() {
		var a = 1;
		function B() {
	 	console.log(a);
 	 }
 	 return B();
	}
闭包的好处
能够实现封装和缓存等
闭包的坏处
就是消耗内存、不正当使用会造成内存溢出的问题
使用闭包的注意点
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露
解决方法是:在退出函数之前,将不使用的局部变量全部删除
闭包的经典问题
for(var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
这段代码输出3个3
解析:首先,for 循环是同步代码,先执行三遍 for,i 变成了 3;然后,再执行异步代码 setTimeout,这时候输出的 i,只能是 3 个 3 了
有什么办法输出 0 1 2
使用let
for(let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
在这里,每个 let 和代码块结合起来形成块级作用域,当 setTimeout() 打印时,会寻找最近的块级作用域中的 i,所以依次打印出 0 1 2
使用立即执行函数解决闭包的问题
for(let i = 0; i < 3; i++) {
  (function(i){
    setTimeout(function() {
      console.log(i);
    }, 1000);
  })(i)
}

五、组件化和模块化

组件化

组件化开发的优点和必要性
增强代码可读性,降低维护成本,达到组件通用性
组件化开发的原则
  • 专一
  • 可配置性
  • 标准性
  • 复用性
  • 可维护性

模块化

模块化的好处
  • 避免变量污染,命名冲突
  • 提高代码复用率
  • 提高了可维护性
  • 方便依赖关系管理
模块化的几种方法
  • 函数封装
var myModule = {
    var1: 1,
    
    var2: 2,
    
    fn1: function(){
    
    },
    
    fn2: function(){
    
    }
}
  • 立即执行函数表达式
var myModule = (function(){
    var var1 = 1;
    var var2 = 2;
    
    function fn1(){
    
    } 
    
    function fn2(){
    
    }

	return {
	    fn1: fn1,
	    fn2: fn2
	};
})();

六、对This对象的理解

this总是指向函数的直接调用者(而非间接调用者)
如果有new关键字,this指向new出来的那个对象
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window

七、vue生命周期

Vue生命周期总共有几个阶段?
它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
DOM渲染在哪个周期中就已经完成?
DOM 渲染在 mounted 中就已经完成了
每个生命周期适合哪些场景?
生命周期钩子的一些使用方法:
beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted : 挂载元素,获取到DOM节点
updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框
nextTick : 更新数据后立即操作dom

八、v-show与v-if区别

v-show是css切换,v-if是完整的销毁和重新创建
使用 频繁切换时用v-show,运行时较少改变时用v-if
v-if=‘false’ v-if是条件渲染,当false的时候不会渲染

九、组件之间的传值通信

父组件给子组件传值
使用props,父组件可以使用props向子组件传递数据
父组件vue模板father.vue
<template>
    <child :msg="message"></child>
</template>

<script>
import child from './child.vue';
export default {
    components: {
        child
    },
    data () {
        return {
            message: 'father message';
        }
    }
}
</script>
子组件vue模板child.vue
<template>
    <div>{{msg}}</div>
</template>

<script>
export default {
    props: {
        msg: {
            type: String,
            required: true
        }
    }
}
</script>
子组件向父组件通信
父组件向子组件传递事件方法,子组件通过$emit触发事件,回调给父组件
父组件vue模板father.vue
<template>
    <child @msgFunc="func"></child>
</template>

<script>
import child from './child.vue';
export default {
    components: {
        child
    },
    methods: {
        func (msg) {
            console.log(msg);
        }
    }
}
</script>
子组件vue模板child.vue:
<template>
    <button @click="handleClick">点我</button>
</template>

<script>
export default {
    props: {
        msg: {
            type: String,
            required: true
        }
    },
    methods () {
        handleClick () {
            //........
            this.$emit('msgFunc');
        }
    }
}
</script>
非父子,兄弟组件之间通信
可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发和监听来实现通信和参数传递
Bus.js可以是这样:
import Vue from 'vue'
export default new Vue()
在需要通信的组件都引入Bus.js:
<template>
	<button @click="toBus">子组件传给兄弟组件</button>
</template>

<script>
import Bus from '../common/js/bus.js'
export default{
	methods: {
	    toBus () {
	        Bus.$emit('on', '来自兄弟组件')
	    }
	  }
}
</script>
另一个组件也import Bus.js 在钩子函数中监听on事件
import Bus from '../common/js/bus.js'
export default {
    data() {
      return {
        message: ''
      }
    },
    mounted() {
       Bus.$on('on', (msg) => {
         this.message = msg
       })
     }
   }

十、路由传参的几种方式

1、路由配置传参

首先确定自己要传的参数名,将路由配置修改一下,传name,age,sex三个参数:
		{
			path:'/componentsB/:name/:age/:sex',
			name:'componentsB',
			component:componentsB
		}
componentsA.vue页面通过this.$router.push配置与之对应的参数:
componentsA.vue
<template>
	<div>
		<div>我是组件A</div>
		<button @click='routerToB1'>方式一跳转到组件B</button>
	</div>
</template>
<script>
	export default{
		data(){
			return{
				person:{name:'Gene',age:'18',sex:'male'}
			}
		},
		methods: {
			routerToB1() {
				this.$router.push({
					path:`componentsB/${this.person.name}/${this.person.age}/${this.person.sex}`
				})
			}
		},
	}
</script>
<style>
</style>
componentsB.vue页面通过this.$route.params配置与之对应的参数:
componentsB.vue
<template>
	<div>
		<div>我是组件B</div>
	</div>
</template>
<script>
	export default{
		created(){
			this.getRouterData()
		},
		methods: {
			getRouterData(){
				const param = this.$route.params
				console.log(param)//{name:'Gene',age:'18',sex:'male'}
			}
		},
	}
</script>
<style>
</style>
点击按钮"方式一跳转到组件B",componentsB页面打印出{name:‘Gene’,age:‘18’,sex:‘male’},成功获取到A页面传过来的参数,并且地址栏显示为localhost:8889/#/componentsB/Gene/18/male(端口号根据自己设置的来),表明这种传参方式url会携带参数。

2、params传参

首先将刚才路由配置修改部分还原,在componentsA.vue页面添加按钮"方式二跳转到组件B":
componentsA.vue
<template>
	<div>
		<div>我是组件A</div>
		<button @click='routerToB1'>方式一跳转到组件B</button>
		<button @click='routerToB2'>方式二跳转到组件B</button>
	</div>
</template>
methods中添加方法routerToB2,使用路由属性name来确定匹配的路由,使用属性params来传递参数:
componentsA.vue
			routerToB2(){
				this.$router.push({
					name:'componentsB',
					params:{
						exa:'我是传到组件B的参数'
					}
				})
			},
componentsB.vue保持不变,params传参方式获取参数也是通过this.$route.params,点击A页面新添加的按钮"方式二跳转到组件B",在B页面打印出{exa: “我是传到组件B的参数”},传参成功,地址栏为localhost:8889/#/componentsB,表明这种方式url不会携带参数。

3、query传参

这种方式和params传参方式类似,在componentsA.vue页面继续添加按钮"方式三跳转到组件B":
componentsA.vue
<template>
	<div>
		<div>我是组件A</div>
		<button @click='routerToB1'>方式一跳转到组件B</button>
		<button @click='routerToB2'>方式二跳转到组件B</button>
		<button @click='routerToB3'>方式三跳转到组件B</button>
	</div>
</template>
methods中添加方法routerToB3,使用路由属性name或者path来确定匹配的路由,使用属性query 来传参:
componentsA.vue
			routerToB3(){
				this.$router.push({
					name:'componentsB',// path:'/componentsB'
					query:{
						que:'我是通过query传到组件B的参数'
					}
				})
			}
ccomponentsB.vue页面通过this.$route.query来获取参数:
ccomponentsB.vue
			getRouterData(){
				const query = this.$route.query
				console.log(query)//{que: "我是通过query传到组件B的参数"}
			}
查看地址栏为localhost:8889/#/componentsB?que=我是通过query传到组件B的参数,显然这种方式url会携带参数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值