V-model:双向数据绑定-----必问
Vue数据双向绑定是通过采用数据劫持结合发布者-订阅者模式的方式来实现的。通过Object.defineProperty()来劫持各个属性的setter,getter。修改触发set方法赋值,获取触发get方法取值,在数据变动时发布消息给订阅者,触发相应的回调并通过数据劫持发布信息。
MVVM----必问
Computed和watch的区别
computed和watch的使用场景
Vue中页面传参的方式
Webpack打包方式–devserver 中的proxy,
封装组件之后的怎么用,是用webpack打包吗,不用打包,引入就行,
开发过程中的ie兼容问题
平时遇到的困难,如何解决
商城哪些项目模块可以说自己做的
Vue2和vue3
Git
产品上线和回滚
生命周期以及各个阶段做的事情,
销毁阶段对页面上的东西可以做什么操作,页面销毁之前做什么
vue常用的指令以及功能
V-model怎么实现----原理,MVVM,异步,nexttick
组件传值—父子,子父,兄弟
vue多层嵌套的组件传值,,比如从最外面的组件传到最里面的组件,,
多层组件传值:(传递属性,传递方法)
1.由最外往最内传值: 最外组件绑定属性:a=‘5’,中间组件绑定v-on=‘
a
t
t
r
s
′
最
内
组
件
t
h
i
s
.
attrs' 最内组件 this.
attrs′最内组件this.attrs获取a=5;
2.由最内往最外传值:通过事件监听: 最内发射事件:this.
e
m
i
t
(
′
b
′
,
′
C
h
i
n
a
′
)
,
中
间
组
件
绑
定
v
−
o
n
=
′
emit('b','China'), 中间组件绑定v-on='
emit(′b′,′China′),中间组件绑定v−on=′listeners’ 最外组件监听事件’b’,触发绑定方法;
父组件主动获取子组件的数据,或者调用子组件的方法:
调用子组件的时候 定义一个ref
2.父组件主动获取子组件的数据和方法:
子组件中有child方法
父组件中
<headerchild ref="headerChild"></headerchild>
this.$refs..child.headerChild.属性
this.$refs.child.headerChild.方法
子组件主动获取父组件的数据和方法:this.$parent.get() ---get是父组件的方法
可参考 点
js数据类型
number string boolean undefined null
object array function
undefined和null的区别
null表示为空,一般是复杂数据类型,表示不存在,常用来表示函数企图返回一个不存在的对象。undefined一般是简单数据类型,声明了未赋值(也可以说是声明了没有初始化)。
null转换为数值时为0(Number(null) // 0)
undefined转换为数值时为NAN 5 + null // 5
用途方面:
null:
作为对象原型链最顶部的不存在对象
undefined:
被声明时变量没有赋值
调用函数时,应该提供的参数没有提供
对象没有赋值的属性
函数没有返回值时
undefined的类型(typeof)是undefined;
null的类型(typeof)是object;
Number(null)
// 0
5 + null
// 5
Number(undefined)
// NaN
5 + undefined
// NaN
undefined + null
//NaN
Js对原型和原型链的理解-----继承是通过原型和原型链的方式
Js中需要有一种继承的机制,来把所有的对象联系起来,就可以使用构造函数。但是构造函数生成实例对象的缺点就是无法共享属性和方法。
所以为构造函数设置了一个prototype属性,就是原型,属性值是一个普通的对象,实例对象需要共享的方法,都放在此对象上。
每个实例对象都有一个属性叫proto,指向构造函数的原型对象,并从中继承属性和方法,构造函数的原型对象也是一个对象,也有一个proto属性,一层一层往上找就形成了原型链。
构造函数的prototype属性等于实例化对象的proto属性
此属性并不是ES5中的规范属性,只是为了在浏览器中方便获取原型而做的一个语法糖。可以用Object.getPrototype()方法来获取原型
constructor 原型没有指向实例,因为一个构造函数可以有多个对象实例 但是原型指向构造函数是有的,每个原型都有一个constructor属性指向关联的构造函数
This指向问题
1,普通函数调用,指向全局对象window
2,当作为构造函数时,this => 构造出的实例对象
3,当作为对象的方法调用时,this => 调用方法的那个对象
4,箭头函数的this, this => 就是外层函数的this
Call和apply和Bind改变this的区别—
call–this的指向是第一个参数,
fn.call([this],[param]...) let obj = {name:"obj"}; fn.call(obj,1,2);
传递时传递的是第二个以及之后的实参,call中如果不传参数,或者第一个参数是null或nudefined,this都指向window。
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj, 1, 2);
fn.call(1,2); // this:1 a:2 b=undefined
fn.call(); // this:undefined a:undefined b:undefined
fn.call(null); // this:null a:undefined b:undefined
fn.call(undefined);
apply—把需要传递给fn的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn一个个的传递.
apply中如果不传参数,或者第一个参数是null或nudefined,this都指向window。
fn.apply(obj, [1, 2]);
bind—语法和call一模一样,区别在于立即执行还是等待执行,bind不兼容IE6~8
fn.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行
fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行
this改变为obj了,但是绑定的时候立即执行,当触发点击事件的时候执行的是fn的返回值undefined
document.onclick = fn.call(obj);
1
1
bind会把fn中的this预处理为obj,此时fn没有执行,当点击的时候才会把fn执行
document.onclick = fn.bind(obj);
对Promise的理解
Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态: pending(等待态),resolved(成功态),rejected(失败态);状态一旦改变,就不会再变。只能由 pending变成fulfilled或者由pending变成rejected。只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态。
创造promise实例后,它会立即执行,无法中途取消。Promise是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。Promise实例生成以后,可以用then方法、catch方法分别指定Resolved状态和Rejected状态的回调函数:
在需要用到异步处理并且需要回调值时,用promise,但是promise本身并不是异步的。
在遇到重复且嵌套的回调地狱时,需要用到promise去优化我们的代码结构。
在遇到并发请求,并且需要回调参数时,也可以用promise优化代码。
async await可以和promsie辅助使用,await必须写在async渲染的方法或者函数里面,否则会报错。
.catch会捕获异常
如果有多个.catch捕捉异常,最终会执行哪一个,
会执行第一个,后面的都不执行
。
对盒模型的理解
盒模型两种模式的区别–另一个是怪异盒模型,
标准盒模型的width和height是内容区域,即content的width和height。
IE盒模型(怪异盒模型)的width和height是content的width和hight加上左右的padding和border
css里面画一个高度为0.5px的线----盒子阴影
div{
background:black;//一定是background而非color
width:100%;
height:1px;
transform:scaleY(0.5)
}
.hr.gradient {
height: 1px;
background: linear-gradient(0deg, #fff, #000);
}
http状态码
200请求成功 301永久重定向 302临时重定向 304自上次请求,未修改的文件 400 请求错误 401未被授权,需要身份验证,例如token信息等等 403 请求被拒绝 404 资源缺失,接口不存在,或请求的文件不存在等等。500 服务器未知错误 502 网关错误 503 服务器暂时无法使用
Webpack配置,常用的属性,比如怎么配置代理
1111中
v-if和v-show
V-if是通过dom节点的销毁和重新渲染来控制显示隐藏,v-show是通过设置dom的display属性,none是隐藏,block是显示。
V-if是惰性加载的,如果初始条件为false,则什么也不做,只有条件第一次变为真时才开始局部编译。V-show是在任何条件下都被编译,
性能消耗方面:v-if有更高的切换消耗,V-show有更高的初始渲染消耗。
频繁切换用v-show,运行时条件很少改变,用v-if.
V-model的原理必问,
双向数据绑定 响应式
Vue双向数据绑定是通过采用数据劫持结合发布者-订阅者模式的方式来实现的。通过Object.defineProperty()来劫持各个属性的setter,getter。修改触发set方法赋值,获取触发get方法取值,在数据变动时发布消息给订阅者,触发相应的回调并通过数据劫持发布信息。
MVVM必问–
Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;
View 代表UI 组件,它负责将数据模型转化成UI 展现出来,
ViewModel 是一个同步View 和 Model的对象,通过双向数据绑定把 View 层和 Model 层连接了起来,包含DOM Listeners和Data Bindings,DOM Listeners和Data Bindings是实现双向绑定的关键。DOM Listeners监听页面所有View层DOM元素的变化,当发生变化,Model层的数据随之变化;Data Bindings监听Model层的数据,当数据发生变化,View层的DOM元素随之变化。
好处:
低耦合。View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。可以把一些视图的逻辑放在ViewModel里面,让很多View重用这段视图逻辑。
独立开发。开发人员可以专注与业务逻辑和数据的开发(ViewModel)。设计人员可以专注于界面(View)的设计。
可测试性。可以针对ViewModel来对界面(View)进行测试
Axios请求Body时的解决办法
搜到了几个相关题:
axios post请求body为字符串时的解决方法
修改Content-Type请求头,把请求头修改为headers: {“Content-Type”: “text/plain”}—
watch和computed的区别和使用场景----必问
watch和computed的区别:
computed支持缓存,只有当依赖数据发生改变,才会重新计算。不支持异步,有异步操作时无效,无法监听数据的变化。watch不支持缓存,数据变,直接会触发相应的操作,执行回调,支持异步。
当需要在数据变化时执行异步或开销较大的操作时,使用watch是最有用的。
computed 变量不在 data中定义,而是定义在computed中。根据一个现有数据去生成一个新数据,并且这两个数据会永久的建立关系,还会建立缓存,当无关数据改变的时候,不会重新计算而是直接使用缓存中的值
watch 监听的是已经在 data 中定义的变量, 当该变量变化时,会触发 watch 中的方法
如果想在第一次绑定的时候执行watch监听函数 则需要 设置immediate为true。
深度监听 当要监听对象或数组的时候需要添加deep:true属性,可以监听多个值。
computed中的函数必须要用return返回,watch中的函数不是必须要用return。
使用场景:computed----当一个属性受多个属性影响的时候,使用computed-------购物车商品结算。watch----当一条数据影响多条数据的时候,使用watch-------搜索框。
1、功能上:computed是计算属性,是依赖其他变量计算出来得到的一个变量。也就是它受别的变量的影响,别的变量一变,它就会变。watch是侦听器,当侦听的值发生变化时,其他变化也会跟着改变或者有些操作被触发,执行对应的回调。
2、是否调用缓存:,computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值。只要computed依赖的属性没有发生变化,计算属性会返回之前的计算结果,不需要重新计算。而watch在每次监听的值发生变化的时候都会执行回调。
V-on可以监听多个方法吗
可以,
<input
type=“text”
v-on=“{
input:onInput,
focus:onFocus,
blur:onBlur,
}”
<button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来</button>
<button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来</button>
<!-- 一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号-->
<button @click="onEnter(),onLeave ()">点我onEnter onLeave </button>
onEnter () {
console.log('mouse enter')
},
onLeave () {
console.log('mouse leave')
vue中常用的修饰符,
v-model表单修饰符:
.lazy 输入框改变,这个数据就会改变,lazy这个修饰符会在光标离开input框才会更新数据:
.trim
输入框过滤首尾的空格:
.number
先输入数字就会限制输入只能是数字,先字符串就相当于没有加number,注意,不是输入框不能输入字符串,是这个数据是数字
事件修饰符:
.stop
阻止事件冒泡,相当于调用了event.stopPropagation()方法:
.prevent:
阻止默认行为,相当于调用了event.preventDefault()方法,比如表单的提交、a标签的跳转就是默认事件:
.self:
只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个div里面有个按钮,div和按钮都有事件,我们点击按钮,div绑定的方法也会触发,如果div的click加上self,只有点击到div的时候才会触发,变相的算是阻止冒泡:
.once:
事件只能用一次,无论点击几次,执行一次之后都不会再执行
.capture:
事件的完整机制是捕获-目标-冒泡,事件触发是目标往外冒泡
.sync
对prop进行双向绑定
键盘事件:
enter 上下左右等
this.¥router.push this.¥router.replace this.¥router.go是编程式导航,
vue-router实现路由跳转的三种方式为:
1,router-link
<router-link to="/myRegister">注册</router-link>
2,编程式导航
jumpToLogin: function () {
this.$router.push('/myLogin');
}
vue实现组件传参的方式,query和params,缓存
Vue-router和location.href的用法区别
vue-router使用pushState进行路由更新,静态跳转,页面不会重新加载;
location.href会触发浏览器,页面重新加载一次;
vue-router使用diff算法,实现按需加载,减少dom操作;
vue-router是路由跳转或同一个页面跳转;location.href是不同页面间跳转;
vue-router是异步加载this.$nextTick(()=>{获取url});location.href是同步加载
Vue-router的query和params传参的区别和使用
query传参可以用path和name引入,params传参用name引入。
query是拼接在url后面,在路由配置时可以不需要参数。params是路由的一部分,必须在路由后面添加参数名,在跳转的时候没有传这个参数,会导致跳转失败或者页面会没有内容。
直白的来说query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数,而params相当于post请求,参数不会再地址栏中显示。
但是query会保存传递过来的值,刷新不变 。params传参刷新会无效,
针对params和query拓展出来this.¥router和this.¥route
看下面图片,看看query传参的url
看看下面图片,params的传参,看看图片上的url
又扩展到this.¥route.push this.¥route.replace this.¥route.go
路由跳转中,this.KaTeX parse error: Expected 'EOF', got '#' at position 273: …,t_70,g_se,x_16#̲pic_center) th…router.replace()
描述:同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。上一个记录是不存在的。
this.$router.go(n)
相对于当前页面向前或向后跳转多少个页面,类似 window.history.go(n)。n可为正数可为负数。正数返回上一个页面
Vue-router的导航钩子
全局导航钩子:
前置守卫:
router.beforeEach((to, from, next) => {
// do someting
});
后置钩子
router.afterEach((to, from) => {
// do someting
});
不同于前置守卫,后置钩子并没有 next 函数,也不会改变导航本身。
组件内守卫:
const File = {
template: `<div>This is file</div>`,
beforeRouteEnter(to, from, next) {
// do someting
// 在渲染该组件的对应路由被 confirm 前调用
},
beforeRouteUpdate(to, from, next) {
// do someting
// 在当前路由改变,但是依然渲染该组件是调用
},
beforeRouteLeave(to, from ,next) {
// do someting
// 导航离开该组件的对应路由时被调用
}
}
独享守卫:
cont router = new VueRouter({
routes: [
{
path: '/file',
component: File,
beforeEnter: (to, from ,next) => {
// do someting
}
}
]
});
Vue-router的路由模式—hash和history 常问
生产环境下:两者无区别
开发环境或者测试环境下:
hash 模式的路由中带有 # 号,通过 window.onhashchange 方法监听路由的修改,
可以前进后退刷新,在页面刷新的时候,发送的请求 url 是不带 # 后面的内容,也就是说hash虽然在url中,但不会包含在http请求中,也就是说刷新时不会报错,
hash 模式可以兼容部分低版本的浏览器
hash 模式打包后,直接在浏览器中打开 /dist/index.html 可以正常的访问
history 模式是使用正常的 url 路径显示
history 模式通过 pushState 和 replaceState 方式修改路由改变
history 模式在页面刷新的时候,会请求当前地址栏中完成的 url,这时需要服务器对这个 url 有处理,否则就会404报错,如果没有对应的文件,需要返回 index.html(后端配合重定向返回首页,避免报错)
history 模式因为是使用的 HTML5 的新规范,所以不能兼容低版本的浏览器 不兼容ie6~8
history 模式打包后,直接在浏览器中打开 /dist/index.html 会报错
Vue的路由懒加载方式
vue异步组件
{
path: '/home',
name: 'home',
component: resolve => require(['@/components/home'],resolve)
},{
path: '/index',
name: 'Index',
component: resolve => require(['@/components/index'],resolve)
},
es提案的import()
// 下面2行代码,指定了相同的webpackChunkName,会合并打包成一个js文件。 把组件按组分块
const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home')
const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index')
webpack的require.ensure()
{
path: '/home',
name: 'home',
component: r => require.ensure([], () => r(require('@/components/home')), 'demo')
}, {
path: '/index',
name: 'Index',
component: r => require.ensure([], () => r(require('@/components/index')), 'demo')
}
知道Vuex吗?–必问,可以写五个模块,每个模块的—就是把那一块背下来,原理啥的也搜搜?
- state:vuex的基本数据,用来存储变量
- geeter:从基本数据(state)派生的数据,相当于state的计算属性
- mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
- action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
- modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
vuex是什么,怎么使用,哪种功能场景使用它
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态。也就是说:应用遇到多个组件共享状态时,使用vuex。
场景:多个组件共享数据或者是跨组件传递数据时
vuex的流程
页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation,mutation会修改state中对应的值。最后通过getter把对应值跑出去,在页面的计算属性中,通过,mapGetter来动态获取state中的值
Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
首先要考虑这个异步请求是全局公用还是单个组件私有,
如果是公用,还是写在 vuex 的actions 当中为妙,而私有 则 写在methods中
如果被其他地方复用,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。
关于vuex:https://zhuanlan.zhihu.com/p/142567359 点
vue中常用的指令
1.v-bind 绑定 语法糖是 :冒号
常用于绑定一些 标签属性 等
//
注意加冒号 里面解析的是js语法 不加 解析的是 字符串 如果想要解析成数字 最好还是加冒号
2.v-if // v-show
都可以用于 元素的显示和隐藏
v-if 是利用元素的创建和删除 导致 元素隐藏的
v-show 是利用 display:none//block 使元素显示隐藏 面试经常问道
3.v-model 表单元素双向绑定
4.v-html / v-text
v-text 只能解析里面文本
v-html 能解析 里面的 html代码片段
5. v-if // v-else
用来控制元素 显示 v-if 显示的话 v-else 就不显示 反之亦然
6.v-once
元素 只渲染一次
7.v-for 遍历对象或者数组 很常用
<ul>
<li v-for="item in listItem" :key="item.id">{undefined{item.name}} </li>
<ul>
7.v-on 事件绑定 语法糖 @
给元素绑定事件
<button @click=“click”>点击
vue中的插槽
ref ¥refs ¥route