前言
开始找工作啦,在面试的路上越挫越勇~~ 2022-08-01 第一家公司面试题如下:
1. watch和computed的区别
1. computed:
- 计算属性,可以如data中定义的变量一样,直接使用
- 有缓存
- 页面一加载,就会触发
2. watch
- 数据变化,才会触发
- 无缓存
- 可以得到新值和旧值
- 可以监听路由和数据
3.补充----methods
- 无缓存
- 是函数,调用才可以触发
2. MVVM
M:model代表数据和业务逻辑层
V:代表页面展示,视图层
VM:viewModel代表视图和数据之前的桥梁,是个对象
MVC MVM都是单向的,只能数据层改变视图层
MVVM,数据和视图层是双向的,都可以被对方影响
也就是我们常说的,数据双向绑定
- 扩展:什么是数据双向绑定
vue采用数据劫持,结合发布者-订阅者模式的方式来实现数据的响应式
通过Object.defineProperty中的getter和setter进行数据的值的获取和设置,
在setter进行重新赋值后,通过订阅者去进行数据的处理
- 扩展:什么是发布者-订阅者模式
我个人更喜欢举例子说明:
有一家卖烧饼的店,顾客来买产品,这个时候,没有这个产品,需要预定
商家就留顾客一个电话,每来一个顾客,都留下一个电话
然后,等到有产品的时候,我可以通过我的小程序功能去编辑信息
给是店铺会员的人发一条,产品到了会员是8.5折
----------------------------------------------------------------------------------
在这个过程中,我给店铺留了手机号,我就是订阅者
店家就是发布者,
商家发消息通知我
3. vuex的属性
state:存储属性的状态
mutation:只能通过mutation去commit属性的状态,必须是同步更新,有type和回调函数
getters:相当于state的计算属性,也就是我存储这个属性之后,在计算
action:action提交的是mutation,不直接变更状态且包含任意异步操作
modules:使vuex模块化,可以让每个模块都有自己的vuex属性
4. 熟悉的处理数组的方式
// 可以改变原数组的方法
push():删除并返回数组最后一个元素
pop():向数组尾部添加元素,并返回新数组
shift():删除数组中的第一个元素,并返回新数组
unshift():向数组头部添加一个元素并返回新数组
reverse():反转数组,并返回一个新数组
splice():截取数组中的一部分,返回截取后的数组
sort():排序
----------------------------------------------------------------------------------
// 不改变原数组的方法
concat():用于连接多个数组
join():把数组中的元素,放入一个字符串,通过分隔符分隔
slice(start,end):截取数组
toString():将数组转为字符串
filter():过滤,满足条件为真,返回到新数组内
map():现有数组上进行修改,但返回一个新数组
find():直到找到符合要求的那一项为止
5. 组件之间的传值:
- 父组件到子组件通讯:子组件接收父组件数据 props: ['fatherMessage']
- 通过$on传递父组件方法:
<!--父组件-->
<template>
<div>
<Button @click="handleClick">点击调用子组件方法</Button>
<Child ref="child"/>
</div>
</template>
<script>
import Child from './child';
export default {
methods: {
handleClick() {
this.$refs.child.$emit("childmethod") //子组件$on中的名字
},
},
}
</script>
---------------------------------------------------------------
<!--子组件-->
<template>
<div>我是子组件</div>
</template>
<script>
export default {
mounted() {
this.$nextTick(function() {
this.$on('childmethods', function() {
console.log('我是子组件方法');
});
});
},
};
</script>
- 获取父组件然后使用父组件中的数据
// 父组件无需发送,子组件也无需接收,直接调用即可
this.$parent.parentMethod();
- 子组件到父组件通讯
与父组件到子组件通讯中的$on配套使用,可以向父组件中触发的方法传递参数供父组件使用。
<!--父组件-->
<template>
<div>
<h2>父组件</h2>
<br>
<!--接收数据和方法-->
<Child-one @childEvent="parentMethod"></Child-one>
</div>
</template>
<script>
import ChildOne from './ChildOne';
export default{
components: {
ChildOne,
},
data() {
return {
parentMessage: '我是来自父组件的消息',
};
},
methods: {
// 使用方法展示数据
parentMethod({ name, age }) {
console.log(this.parentMessage, name, age);
},
},
};
</script>
<style scoped>
</style>
---------------------------------------------------------------------
<!--子组件-->
<template>
<div>
<h3>我是子组件一</h3>
</div>
</template>
<script>
export default{
mounted() {
// 用$emit发送数据和方法
this.$emit('childEvent', { name: 'zhangsan', age: 10 });
},
};
</script>
<style scoped>
</style>
- refs获取 少用
可以通过在子组件添加ref属性,然后可以通过ref属性名称获取到子组件的实例。准确来说这种方式和this.$parent一样并不属于数据的传递而是一种主动的查找。
<template>
<div>
<h2>父组件</h2>
<br>
<!--ref主动寻找子组件组件-->
<Child-one ref="child"></Child-one>
</div>
</template>
<script>
import ChildOne from './ChildOne';
export default{
components: {
ChildOne,
},
mounted(){
// 使用this.$refs调用子组件方法即可,用法:this.$refs['child'].xxx()
console.log(this.$refs['child']);
},
};
</script>
<style scoped>
</style>
- 全局事件总线 // 使用完数据之后,最好用销毁钩子函数把bus关掉,用法:this.$bus.$off
// App.vue
beforeCreate(){
Vue.prototype.$bus = this
}
// //发送数据
this.$bus.$on('gaiming',this.name,this.age)
//接受数据
this.$bus.$emit('gaiming', data => {
console.log(data);
});
- vueX
vueX的思想类似$bus
6. 适配PC分辨率
1. 媒体查询 @media
2. rem单位
3. 百分比布局
4. 视口单位vw
5. 图片自适应:max-width
---------------------------------------------------------------------------
6. PC适配的成型方案
用`rem`来做字体的适配,用`srcset`来做图片的响应式,宽度可以用`rem`,`flex`,
栅格系统等来实现响应式,然后可能还需要利用媒体查询来作为响应式布局的基础,
因此综合上面的实现方案,项目中实现响应式布局需要注意下面几点:
- 设置viewport
- 媒体查询
- 字体的适配(字体单位)
- 百分比布局
- 图片的适配(图片的响应式)
- 结合flex,grid,BFC,栅格系统等已经成型的方案
- 流式布局(即百分比布局)和媒体查询混合使用
-----------------------------------分割线------------------------------------------
8月2号晚上的面试,我简直丢人丢到太平洋去了,尴尬的我都能抠出一栋别墅, 面试官问的问题,是我在自己博客里写的,我竟然没有回答好?!!!!!
痛定思痛,我决定,继续努力,好好学习,不光是为了面试,也为了能成为一个更好的开发者 。。。。。
话说。今天早上,我回忆了一下,发现,面试官问了我一个问题,是在我们通话前 我还念念有词的给朋友讲了一边!!!!结果,我完全不记得了,这也说明了,掌握的不扎实
加油吧~~
------------------------------8月2日晚电话面试---------------------------------------
跨域问题
1、为什么会有跨域问题
个人理解:
JSONP为什么能解决跨域问题呢?
Script通过src赋值url然后,把一个callback一个函数名,传一个函数给后端。后端把这个返回到响应体里,然后前端 再去发这个请求,
相当于 我把这个url传给后端。后端给我传回来了,这样就保证了我是在同一个服务里拿到的数据
- 同源策略会导致跨域问题,如果发送异步请求是不同的两个协议/域名/端口号,会产生安全问题,所以浏览器出了一个同源策略,不允许不同源的请求进行交互
- 解决跨域问题的方法都有哪些
- 如何解决跨域问题
JSONP
CORS:后台配置,解决跨域问题
proxy
2. JSONP是如何解决跨域的
JSONP通过script标签的src属性,可以解决跨域问题
src/href都不涉及跨域问题
1. JSONP如何实现解决跨域问题
<script>
function request(data){
console.log(data)
}
</script>
<script src="此处填写涉及跨域问题的url?callback=request"></script>
2.过程:
1)前端将回调函数,作为参数传给后端
2)后端拿到这个参数,在返回的响应体里调用这个函数,把json当作一个参数传给前端
3)前端拿到这个响应体之后,script会执行这个cb回调函数,前端此时拿到数据
3. 缺点:只能通过get请求
4. 优点:兼容很多古老浏览器~~
3. JSONP的src为什么可以解决跨域问题
跨域是因为 同源策略,用src属性解决,是因为,src通过绑定函数去传给后端,后端在响应体里返回,这就使得src请求回来的资源和当前的域是相同的,所以可以解决这个跨域问题
4. proxy是在vue哪个文件配置的?为什么在这个文件配置?
1. proxy是在vue.config.js文件中配置的
2. vue-cli 是什么:vue官方提供快速搭建vue项目的脚手架,
是基于webpack开发的,里面内置了许多默认的配置,vue.config.js 是默认的配置文件,
其中 devServer 可以用于解决本地开发的时请求接口造成的跨域,devServer 中是关于 proxy 代理的配置
5. proxy如何实现跨域?
//proxy代理一个或多个
module.exports = {
devServer: {
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
}
6. proxy为什么可以解决跨域问题
同源策略是浏览器协议,而我们在执行的时候,运行的是服务端,
所以http-proxy-middleware
http 代理中间件,利用服务器发送请求,就解决了跨域问题
服务器与服务器之间,不存在跨域的问题,proxy相当于代理了另一个服务器 去请求,两个服务器之间不存在跨域问题,所以就解决了跨域问题
7. vue-router的模式
vue-router有两个模式 hash和history