1.src和href的区别 ?
答:src用于替代当前的元素,而href用于建立这个标签与外部资源之间的关系。
href 是Hypertext Reference的简写,表示超文本引用,指向网络资源所在位置。
常用场景:
<a href="http://www.baidu.com"></a>
<link type="text/css" rel="stylesheet" href="header.css">
src 是source的简写,目的是要把文件下载到html页面中去。
常见场景:
<img src="img/girl.jpg"></img>
<iframe src="top.html">
<script src="show.js">
作用结果:
- href 用于在当前文档和引用资源之间确立联系
- src 用于替换当前内容
浏览器解析方式
当浏览器遇到href会并行下载资源并且不会停止对当前文档的处理。(同时也是为什么建议使用 link 方式加载 CSS,而不是使用 @import 方式)
当浏览器解析到src ,会暂停其他资源的下载和处理,直到将该资源加载或执行完毕。(这也是script标签为什么放在底部而不是头部的原因)
2.页面元素隐藏方式 和各自特点?
答:
oveflow:hidden; 溢出隐藏
display: none; 直接“销毁”元素在页面中的位置;
visibility: hidden; 直接让元素不可见,但元素的物理空间位置还是存在的;
小结一下
以上只是个人对于显示与隐藏的一点小看法,或许还有其他方式,但感觉上应该都差不多,可能是在这些基础上做了一些变化吧。那么具体我们会去使用什么方式来显示隐藏页面元素,还是要结合需求点来考虑。
最后来谈一下display
一般情况隐藏元素大家都还是会去使用 display: none; 的方式,然后通过 display: block; 让元素显示出来。不过这里就小志个人所接触的情况来看,使用 display: block; 显示元素的这个时候,大部分针对的这个元素是 div 标签或者其他的块级元素。
3.用过哪些盒模型,以及他们各自的区别?
盒模型也称为框模型,就是从盒子顶部俯视所得的一张平面图,用于描述元素所占用的空间。它有两种盒模型,W3C盒模型和IE盒模型(IE6以下,不包括IE6以及怪异模式下的IE5.5+)
理论上两者的主要区别是二者的盒子宽高是否包括元素的边框和内边距。当用CSS给给某个元素定义高或宽时,IE盒模型中内容的宽或高将会包含内边距和边框,而W3C盒模型并不会。
div{
padding:20px;
margin:20px;
border:5px solid #ccddff;
width:100px;
}
此div元素,在W3C盒模型中的宽度为190(100+20*2+20*2+5*2)px;在IE盒模型中的宽度是100px.
CSS3新增了box-sizing属性来改变盒模型的类型
box-sizing:content-box; 默认值,代表W3C盒模型:盒子定义宽高 = 内容宽高(content)
box-sizing:border-box; 代表IE盒模型:盒子定义宽高 = 内容宽高(content) + 内边距 (padding)+ 边框(border)
小结:
根据自己的实际情况用那种盒模型,自己定.
4.谈谈你的移动端适配方案有哪些?
答:
采用线下几款主流的热门的框架 : bootstarp element muse Ui 等;
采用 :媒体查询标签 @media 的方式
解释媒体查询
媒体查询(Media Query)是css3新语法。
● 使用@media查询,可以针对不同的媒体可惜定义不同样式。
● @media可以针对不同的屏幕尺寸设置不同样式。
● 当你重置浏览器大小过程中,页面也会根据浏览器的宽度和高度重新渲染页面。
● 目前针对很多苹果手机,Android,平板等设备都用得到多媒体查询。
语法规范
@media mediatype and|not|only(media feature){ Css-code; } |
● 用@media 开头,注意@符号。
● media 媒体类型
● 关键字 and|not|only
● media feature媒体特性,必须有小括号包含
- mediatype查询类型
将不同的终端设备划分不同的类型,称为媒体类型。
值 | 解释说明 |
all | 用于所有设备 |
| 用于打印机和打印预览 |
screen | 用于电脑屏幕,平板电脑,智能手机 |
- 关键字
关键字将媒体类型或多个媒体特性连接到一起作为媒体查询条件,
● and:可以将多个媒体特性连接到一起,相当于“且”的意思。
● not:排除某个媒体类型,相当于“非”的意思,可以省略。
●only:指定某个特定的媒体类型,可以省略。
- 媒体特性
每种媒体类型都具体各自不同的特性,根据不同媒体类型的媒体特性设置不同的展示风格,我们暂且了解三个。注意他们要加小括号包含。
值 | 解释说明 |
width | 定义输出设备中页面可见区宽度 |
Min-width | 定义输出设备中页面最小可见区宽度 |
Max-width | 定义输出设备中页面最大可见区宽度 |
采用 rem +@meadia 两种结合
解释REM
媒体查询+rem实现元素动态大小变化.
Rem单位是跟html来走的,有了rem页面元素设置不同大小尺寸。媒体查询可以根据不同设备宽度来修改样式,媒体查询+rem就可以实现不同设备宽度,实现页面元素大小的动态变化。
方式一: 通过为不同的尺寸设置不同的font-size值.
方式二: 以js窗口改变事件根据不同尺寸设置font-size值.
Ps: 在移动 通常得到的设置图以苹果6分辨率为主, 375*2 = 750px;
Js获取屏幕尺寸:
document.documentElement.clientWidth
document.body.clientWidth
Js改变html字体大小:
document.documentElement.style.fontSize =
5.js 数据类型有几种?它们之间的区别是什么?
答:
基本数据类型 引用数据类型
区别:
基本数据是栈内存,引用数据是堆内存
堆栈:(堆栈内存就是在计算机内存中分配出来的一块空间,用于执行和存储代码)
不同内存分配机制也带来了不同的访问机制
深拷贝与浅拷贝的原因
参数传递的不同(实参传递形参的过程)
6.数据类型强制转化和隐式转化的分别怎么使用?
答:
强制类型转换:又称为“显示类型转换” ,是从存储范围较大的类型转换为存储范围较小的类型,在转换过程中可能会造成数据损失。
如何解决:使用强制类型转换
byte a = (byte) 300;
System.out.println("a="+a);
/*
常数300:0000 0000 0000 0000 0000 0001 0010 1100
byte: 0000 0000
强制转换类型后只能截取到目标数据类型最大范围数
截取------------------------------------- 0010 1100
截取的数据是操作后的数据为补码,所以还要对其取原码
0010 1100 --------正数
正数:原码等于反码等于补码
*/
注意:
/*
注意事项:赋值运算符+= , -= , *= , /= , %=中都隐藏有强制类型转换
*/
short a = 1;
sum += a; //相等于 short sum = (short)(sum+a);
隐式类型转换:又称默认类型转换,是从存储范围较小得类型转换为存储范围大的类型
byte 、short、 char三者之间不转换,一旦参与运算,会先默认转换为 int 类型后再参与运算
short a = 1;
char str = 'a';
byte b = 20;
int sum = a + str ;
int sum2 = a + b ;
int sum3 = b + str ;
System.out.println("sum="+sum) ;
System.out.println("sum2="+sum2) ;
System.out.println("sum3="+sum3) ;
结果:
sum=98
sum2=21
sum3=117
总结:
隐式转换各显式转换要求是同类型的,就是说两种数据类型必须兼容,隐式转换是向上转型(相当是子类转父类),而强制类型转换则是向下转型(相当是父类转子类),就好像Double型的可以包含int型一样。
而强制转换可以是不是同一种类型,(如同class1与class2同级别的类一样),两都进行内容上的解析。Convert.ToInt32与int.Parse都是强制转换,int.Parse是转换String为int(这种情况很多,可能进行了些优化,也可能只是为了方便,处理逻辑一样), 而Convert.ToInt32是转换继承自Object的对象为int的(18种重载). 比如一个object对象,你想把它转换为int,用int.Parse就不可以,要用Convert.ToInt32
==================
隐式、显示,有一定的关系,大小,包函
强制,一般没有关系,Convert(), BitConvert()
7.let const 和 var 的区别 ?
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改
8.箭头函数和普通函数的区别 ?
箭头函数:
let fun = () => {
console.log('lalalala');
}
普通函数:
function fun() {
console.log('lalla');
}
箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种只包含一个表达式,连{ ... }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }和return。
箭头函数是匿名函数,不能作为构造函数,不能使用new
let FunConstructor = () => {
console.log('lll');
}
let fc = new FunConstructor();
箭头函数不绑定arguments,取而代之用rest参数...解决
function A(a){
console.log(arguments);
}
A(1,2,3,4,5,8); // [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]
let B = (b)=>{
console.log(arguments);
}
B(2,92,32,32); // Uncaught ReferenceError: arguments is not defined
let C = (...c) => {
console.log(c);
}
C(3,82,32,11323); // [3, 82, 32, 11323]
箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
var obj = {
a: 10,
b: () => {
console.log(this.a); // undefined
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
},
c: function() {
console.log(this.a); // 10
console.log(this); // {a: 10, b: ƒ, c: ƒ}
}
}
obj.b();
obj.c();
var obj = {
a: 10,
b: function(){
console.log(this.a); //10
},
c: function() {
return ()=>{
console.log(this.a); //10
}
}
}
obj.b();
obj.c()();
箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。
let obj2 = {
a: 10,
b: function(n) {
let f = (n) => n + this.a;
return f(n);
},
c: function(n) {
let f = (n) => n + this.a;
let m = {
a: 20
};
return f.call(m,n);
}
};
console.log(obj2.b(1)); // 11
console.log(obj2.c(1)); // 11
箭头函数没有原型属性
var a = ()=>{
return 1;
}
function b(){
return 2;
}
console.log(a.prototype); // undefined
console.log(b.prototype); // {constructor: ƒ}
箭头函数不能当做Generator函数,不能使用yield关键字
总结
- 箭头函数的 this 永远指向其上下文的 this ,任何方法都改变不了其指向,如 call() , bind() , apply()
- 普通函数的this指向调用它的那个对象
9.解释什么叫回调地狱 以及怎么解决回调地狱 ?
在正式了解“回调地狱”之前,我们先了解两个概念:
- 回调函数
当一个函数作为参数传入另一个参数中,并且它不会立即执行,只有当满足一定条件后该函数才可以执行,这种函数就称为回调函数。我们熟悉的定时器和Ajax中就存在有回调函数:
setTimeout(function(){ //function(){console.log('执行了回调函数')}就是回调函数,它只有在3秒后才会执行
console.log('执行了回调函数');
},3000) //3000毫秒
这里的回调函数是function(){console.log('执行了回调函数')}
,在满足时间3秒后执行.
//1.创建异步对象
var xhr=new XMLHttpRequest();
//2.绑定监听事件(接收请求)
xhr.onreadystatechange=function(){
//此方法会被调用4次
//最后一次,readyState==4
//并且响应状态码为200时,才是我们要的响应结果 xhr.status==200
if(xhr.readyState==4 && xhr.status==200){
//把响应数据存储到变量result中
var result=xhr.responseText;
console.log(result);
}
}
//3.打开链接(创建请求)
xhr.open("get","/demo/ajaxDemo",true);
//4.发送请求
xhr.send();
这里的回调函数是xhr.onreadystatechange绑定的函数,在xhr.send()发送请求并拿到响应后执行。
异步任务
与之相对应的概念是“同步任务”,同步任务在主线程上排队执行,只有前一个任务执行完毕,才能执行下一个任务。异步任务不进入主线程,而是进入异步队列,前一个任务是否执行完毕不影响下一个任务的执行。同样,还拿定时器作为异步任务举例:
setTimeout(function(){
console.log('执行了回调函数');
},3000)
console.log('111');
如果按照代码编写的顺序,应该先输出“执行了回调函数”,再输出“111”。但实际输出为:
这种不阻塞后面任务执行的任务就叫做异步任务。
接下来让我们看看什么是回调地狱。
回调地狱是什么?
根据前面我们可以得出一个结论:存在异步任务的代码,不能保证能按照顺序执行,那如果我们非要代码顺序执行呢?
比如我要说一句话,语序必须是下面这样的:武林要以和为贵,要讲武德,不要搞窝里斗。
我必须要这样操作,才能保证顺序正确:
setTimeout(function () { //第一层
console.log('武林要以和为贵');
setTimeout(function () { //第二程
console.log('要讲武德');
setTimeout(function () { //第三层
console.log('不要搞窝里斗');
}, 1000)
}, 2000)
}, 3000)
可以看到,代码中的回调函数套回调函数,居然套了3层,这种回调函数中嵌套回调函数的情况就叫做回调地狱。
总结一下,回调地狱就是为是实现代码顺序执行而出现的一种操作,它会造成我们的代码可读性非常差,后期不好维护。
那该如何解决回调地狱呢?
如何解决回调地狱
1.Promise
Promise是js中的一个原生对象,是一种异步编程的解决方案,可以替换掉传统的回调函数解决方案。
Promise构造函数接收一个函数作为参数,我们需要处理的异步任务就卸载该函数体内,该函数的两个参数是resolve,reject。异步任务执行成功时调用resolve函数返回结果,反之调用reject。
Promise对象的then方法用来接收处理成功时响应的数据,catch方法用来接收处理失败时相应的数据。
Promise的链式编程可以保证代码的执行顺序,前提是每一次在than做完处理后,一定要return一个Promise对象,这样才能在下一次than时接收到数据。
下面是实例代码:
function fn(str){
var p=new Promise(function(resolve,reject){
//处理异步任务
var flag=true;
setTimeout(function(){
if(flag){
resolve(str)
}
else{
reject('操作失败')
}
})
})
return p;
}
fn('武林要以和为贵')
.then((data)=>{
console.log(data);
return fn('要讲武德');
})
.then((data)=>{
console.log(data);
return fn('不要搞窝里斗')
})
.then((data)=>{
console.log(data);
})
.catch((data)=>{
console.log(data);
})
但是Promise最大的问题就是代码冗余,原来的异步任务被Promise封装一下,不管什么操作都用than,就会导致一眼看过去全是than…than…than…,这样也是不利于代码维护的。
所以下面的async/await 可以时代码看起来更像同步代码。
2.async/await
首先我们看async关键字,他作为一个关键字放到声明函数前面,表示该函数为一个异步任务,不会阻塞后面函数的执行:
async function fn(){
return '不讲武德';
}
console.log(fn());
可以看到async函数返回数据时自动封装为一个Promise对象。
和Promise对象一样,处理异步任务时也可以按照成功和失败来返回不同的数据,处理成功时用than方法来接收,失败时用catch方法来接收数据:
async function fn() {
var flag = true;
if (flag) {
return '不讲武德';
}
else{
throw '处理失败'
}
}
fn()
.then(data=>{
console.log(data);
})
.catch(data=>{
console.log(data);
})
console.log('先执行我,表明async声明的函数是异步的');
当把flag设置为false是,执行结果为:
async关键字说完了,我们看看awai关键字
await关键字只能在使用async定义的函数中使用
await后面可以直接跟一个 Promise实例对象(可以跟任何表达式,更多的是跟一个返回Promise对象的表达式)
await函数不能单独使用
await可以直接拿到Promise中resolve中的数据。
//封装一个返回promise的异步任务
function fn(str) {
var p = new Promise(function (resolve, reject) {
var flag = true;
setTimeout(function () {
if (flag) {
resolve(str)
} else {
reject('处理失败')
}
})
})
return p;
}
//封装一个执行上述异步任务的async函数
async function test(){
var res1=await fn('武林要以和为贵'); //await直接拿到fn()返回的promise的数据,并且赋值给res
var res2=await fn('要讲武德');
var res3=await fn('不要搞窝里斗');
console.log(res1,res2,res3);
}
//执行函数
test();
结果为:
为什么叫await
等待呢,因为当代码执行到async
函数中的await
时,代码就在此处等待不继续往下执行,知道await
拿到Promise对象中resolve的数据,才继续往下执行,这样就保证了代码的执行顺序,而且使异步代码看起来更像同步代码
总结
当我们写代码遇到异步回调时,我们想让异步代码按照我们想要的顺序执行,如果按照传统的嵌套方式,就会出现回调地狱,这样的代码不利于维护,我们可以通过Promise对象进行链式编程来解决,这样尽管可以解决问题,但是ES7给我们提供了更加舒适的async/await语法糖,可以使得异步代码看起来更像是同步代码。
10.说明原生ajax的实现步骤?
1创建对象
2设置请求方式和请求地址
3发送请求
4监听状态变化
5返回数据
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState != 4)return;
if(xhr.status == 200 && xhr.readyState == 4){
console.log(xhr.responseText)
}else{
console.log("请求失败")
}
}
xhr.open("get","http://localhost:3030")
xhr.send()
11.什么情况下会导致跨域?怎么解决
不同源策略时会导致跨域
解决方法:
jsonp是前端解决跨域最实用的方法
原理就是html中 的link,href,src属性都是不受跨域影响的,link可以调用远程的css文件,href可以链接到随便的url上,图片的src可以随意引用图片,script的src属性可以随意引入不同源的js文件
看下面代码,a.html页面中有一个func1方法,打印参数ret
<body>
<script type="text/javascript">
function func1(ret){
console.log(ret)
}
</script>
<script src="http://192.168.100.150:8081/zhxZone/webmana/dict/jsonp.js" type="text/javascript" charset="utf-8"></script>
</body>
而引入的jsonp.js中的代码为:
func1(111)
12.vue 有几个生命周期 以及各个生命周期的调用时机 ?
答:
- beforCreate
实例初始化之后、创建实例之前的执⾏的钩⼦事件
创建实例之前,数据观察和事件配置都没好准备好。也就是数据 也没有、DOM也没⽣成
2.created
实例创建完成后执⾏的钩⼦
实例创建完成后,我们能读取到数据data的值,但是DOM还没⽣成,可以在此时发起ajax
3 .beforeMount
将编译完成的html挂载到对应的虚拟DOM时触发的钩⼦ 此时页面并 没有内容。 即此阶段 解读为: 即将挂载
4.mounted DOM挂载完成
5.beforeUpdate 在更新DOM之前 调⽤该钩⼦,有事件介入时
6.updated 在更新DOM之后调⽤该钩⼦,应⽤:可以获取最新的DOM
7.beforeDestroy 销毁前
8.destroyed 销毁后
ps:当销毁后在重新载入时会重新触发 创建函数
9.Activated 激活前
10.deactivated 激活后
Vue生命周期分为8个阶段分别是创建前/后,载入前/后,更新前/后,销毁前/后
创建前/后:在beforeCreated阶段 vue实例挂载完el还没有
载入前/后:在beforeMount阶段 vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。
13. 使用vue中的v-for时,为什么要绑定 :key? 如果不绑定会有什么效果?
首先,可以通过以下方式设置key值,
id是唯一识别的,使用id属性作为key的值。
也有这样设置key值的,
v-for="(item, index) in list" :key="index"
首先,它们区别主要在于 虚拟DOM的复用,绑定key可以更好的复用,下面来详细讲一下
假如我们有一个数组 arr = [1,2,3,4],我们要在2后面插入一个值9;
如果绑定了key值,那么会是这样的情况:
如果没有绑定key值,那么会是这样的情况:
14.v-show 和 v-if 的作用和区别, v-bind 和 v-model的作用和区别?
v-show
v-show指令的作用是:根据真假值切换元素的显示状态,是响应式的
语法表达v-show = " 表达式 "
原理是修改元素的的CSS属性(display)来决定实现显示还是隐藏
指令后面的内容最终都会解析为布尔值
值为真(true)的时候元素显示,值为假(false)的时候元素隐藏
数据改变之后呢对应的元素的显示状态也是会同步更新的
<body>
<div id="app">
<input type="button" value="切换显示" @click="changeIsShow" />
<p v-show="isShow">不装了,我摊牌了,没错你要找的就是我</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
changeIsShow(){
this.isShow = !this.isShow
}
}
})
</script>
</body>
v-if
- v-if指令的作用:根据表达式的真假切换元素的显示状态
- v-if = "表达式"
- 本质是通过操纵dom元素来进行切换显示
- 表达式的值为true的时候元素存在于dom树中,为false的时候从dom树中移除
<body>
<div id="app">
<input type="button" value="点我切换显示" @click="changeIsShow" />
<p v-if="isShow">不装了,我摊牌了,没错你要找的就是我</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
changeIsShow(){
this.isShow = !this.isShow
}
}
})
</script>
</body>
原理
v-show指令:元素始终被渲染到HTML,它只是简单的伪元素设置css的style属性,当不满足条件的元素被设置style=“display:none”的样,是通过修改元素的的CSS属性(display)来决定实现显示还是隐藏
v-if指令:满足条件是会渲染到html中,不满足条件时是不会渲染到html中的,是通过操纵dom元素来进行切换显示
2.应用场景
v-if需要操作dom元素,有更高的切换消耗,v-show只是修改元素的的CSS属性有更高的初始渲染消耗,如果需要非常频繁的切换,建议使用v-show较好,如果在运行时条件很少改变,则使用v-if较好
v-bind
eg:v-bind:class 可简写为 :class
当加上v-bind:之后,它的值classe不是字符串,而是vue实例对应的data.classed的这个变量。也就是说data.classed是什么值,它就会给class属性传递什么值,当data.classed发生变化的时候,class属性也发生变化,这非常适合用在通过css来实现动画效果的场合。他只是单向变动
v-bind支持的类型
html中的属性、css的样式、对象、数组、number 类型、bool类型
v-bind使用:
// 绑定文本
<p v-bind="message"></p>
// 绑定属性
<p v-bind:src="http://...."></p>
<p v-bind:class="http://...."></p>
<p v-bind:style="http://...."></p>
// 绑定表达式
:class{className:true}
v-model
主要是用在表单元素中,它实现了双向绑定。在同事使用v-bind和v-model中,v-model建立的双向绑定对输入型元素input, textarea, select等具有优先权,会强制实行双向绑定。很多时候v-model使用在表单的中实现双向绑定。
<input v-model="something">
15.vue 组件通信如何实现,至少列举3种方式并说明各自的局限性?
-
父子间通信:父亲提供数据通过属性
props
传给儿子;儿子通过$on
绑父亲的事件,再通过$emit
触发自己的事件 -
利用父子关系
$parent
、$children
, -
ref
获取组件实例,调用组件的属性、方法 -
跨组件通信
Event Bus
(Vue.prototype.bus=newVue)其实基于bus = new Vue)其实基于bus=newVue)其实基于on与$emit -
vuex
状态管理实现通信
局限性:
父传子: 传入的值想作为局部变量来使用,直接使用会 报错
父子关系:不可控性大,有一定风险
vuex: 流程相比较稍微复杂。
Vuex通信方式相比其他方式,比较复杂,而且如果不同的模块,需要建立独立的modules
总结
- 父子组件通信需要一定的媒介,也就是中间站。
- 调用方法进行传值。
16.详细说明vue组件中 data ,computed 和 watch的区别?
data:
初始组件的时候data拿到的是store的值是还没有输入过的原始值,
点击按钮的时候,取data中的值是原始值,不能自己更新。
computed:
换成计算属性时,是当值发生变化的时候,从新计算,不变化的时候拿到的是之前缓存的值。
两个数相加求和:
代码:(可以翻看上一个vuex详细了解的完整例子)
data:
//这里只记录小部分
data(){//只能获取到原始值
return{
ha:this.$store.state.s_a;
hb:this.$store.state.s_b;
}
}
computed:
computed:{//计算属性,获取监听变化后的值
m(){//自定义一个方法,获取到输入后变化后的值
return (this.$store.state.s_a-0)+(this.$store.s_b-0)
//这里用减号(-0)是相加在一起,当不用减号时(两个数字会拼接在一起)
}
}
watch:也可以实现实时监听.
computed和watch区别?
Computed特点:
需要主动调用,具有缓存能力只有数据再次改变才会重新渲染,
否则就会直接拿取缓存中的数据。
Watch特点:
无论在哪只要被绑定数据发生变化Watch就会响应,
这个特点很适合在异步操作时用上。
17.keep-alive的作用是什么? 使用它的目的是什么?
keep-alive
可以实现组件缓存,当组件切换时不会对当前组件进行卸载
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染
比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染
常用的两个属性include/exclude,允许组件有条件的进行缓存
两个生命周期activated/deactivated,用来得知当前组件是否处于活跃状态
目的:
清除缓存
18.vue-router的作用是什么? 为什么不使用a标签?
答:
至于我们为啥不能用a标签,这是因为用Vue做的都是单页应用,就相当于只有一个主的index.html页面,所以你写的标签是不起作用的,你必须使用vue-router来进行管理。
19.vuex 是什么? 怎么使用?为什么用使用它?
vuex是基于vue框架的一个状态管理库。可以管理复杂应用的数据状态,比如兄弟组件的通信、多层嵌套的组件的传值等等。
vuex有这么几个核心概念——State、Getter、Mutation、Action、Module
state:vuex的基本数据,用来存储变量
2. geeter:从基本数据(state)派生的数据,相当于state的计算属性
3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
4. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
在main。Js引入store,注入。只用来读取的状态集中放在store中;改变状态的方式是提交mutatios,这是个同步的事物;异步逻辑应该封装在action中。
使用 vue 框架,需要关注点基本就是数据,因为框架解决了数据和页面更新的实现。页面和数据的关系是y=f(x)
那么我们需要关注数据(model) 和 视图(组件) 之间的关系.
一个组件使用一个 model,一对一的关系
2. 一个组件使用多个 model,一对多的关系
3. 多个组件使用一个 model,多对一的关系
4. 多个组件使用多个 model,多对多的关系
所以组件和数据之间的对应关系,随着项目的复杂,变得混乱。所以需要统一管理数据,把数据的存取集中到一个地方,所有的组件都从这个地方取数据,更新数据也集中到同一个地方。
20.请谈一下你对 使用原生js开发和 使用vue开发的看法。(至少20字以上)
答:
原生JS的API选择器等等进行了封装,便于操作DOM,本质还是操作DOM实现逻辑,数据和界面还是连接在一起的。
适用于需要操作DOM的业务:动画,交互效果,页面特效。
vue.js
MVVM模型,将数据层和视图层完全分离开,不仅对API进行封装, 还提供了一系列的解决方案。这是一个思想的转变。数据驱动的机制,主要操作的是数据而不是频繁操作DOM(导致页面频繁重绘)。
适用的业务:数据相关的处理以及操作。