vue项目常见问题总结

38次阅读

共计 9171 个字符,预计需要花费 23 分钟才能阅读完成。

  1. vue 中为什么使用 key?

    如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复 / 再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

  2. vue 项目中 websocket 的使用。

    1、定义 websocket.js 文件,使用 install 注册组件, 代码结构如下:export default {install(Vue) {
            Vue.prototype.websocket = null;
            var timerDate = null;
            // 建立连接的方法
            Vue.prototype.create_websocket = function(obj) {this.websocket.onerror = function() {}
             this.websocket.onmessage = function() {}
             this.websocket.onopen = function() {}
             this.websocket.onclose = function() {}
            }
        }
    }
    websocket 的 readStatus 状态有 0,1,2,3
    
    2、在 main.js 中引入并挂载到 Vue 上
    import socket from "./utils/websocket"
    Vue.use(socket)

3.vue 项目中 form 表单组件的封装

4.vue 项目中 table 组件的封装

5.vue 项目中 form 表单的 disabled 属性
使用场景:表单初始化时为 disabled 禁止修改状态,当点击修改按钮的时候,表单为可编辑状态。可以通过对 form 表单的

6.vant-circle 的使用中遇到的问题

7.vue 项目中字体图标库 fontawsome 的使用

1、npm 安装 font-awesome: cnpm install font-awesome --save
2、在 main.js 中引入:import 'font-awesome/css/font-awesome.min.css'
3、在页面中使用:<i class="fa fa-align-justify"></i>

8.ref

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:

9.setTimeout、Promise、Async/Await 的区别

1. setTimeout
console.log('script start')    //1. 打印 script start
setTimeout(function(){console.log('settimeout')    // 4. 打印 settimeout
})    // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('script end')    //3. 打印 script start
// 输出顺序:script start->script end->settimeout
2. Promise
Promise 本身是同步的立即执行函数,当在 executor 中执行 resolve 或者 reject 的时候, 此时是异步操作,会先执行 then/catch 等,当主栈完成后,才会去调用 resolve/reject 中存放的方法执行,打印 p 的时候,是打印的返回结果,一个 Promise 实例。console.log('script start')
let promise1 = new Promise(function (resolve) {console.log('promise1')
    resolve()
    console.log('promise1 end')
}).then(function () {console.log('promise2')
})
setTimeout(function(){console.log('settimeout')
})
console.log('script end')
// 输出顺序: script start->promise1->promise1 end->script end->promise2->settimeout
当 JS 主线程执行到 Promise 对象时,promise1.then() 的回调就是一个 task

promise1 是 resolved 或 rejected: 那这个 task 就会放入当前事件循环回合的 microtask queue

promise1 是 pending: 这个 task 就会放入 事件循环的未来的某个 (可能下一个) 回合的 microtask queue 中

setTimeout 的回调也是个 task,它会被放入 macrotask queue 即使是 0ms 的情况

3. async/await
async function async1(){console.log('async1 start');
    await async2();
    console.log('async1 end')
}
async function async2(){console.log('async2')
}

console.log('script start');
async1();
console.log('script end')

// 输出顺序:script start->async1 start->async2->script end->async1 end
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了 async 函数体。举个例子:async function func1() {return 1}

console.log(func1())
在这里插入图片描述
很显然,func1 的运行结果其实就是一个 Promise 对象。因此我们也可以使用 then 来处理后续逻辑。func1().then(res => {console.log(res);  // 30
})
await 的含义为等待,也就是 async 函数需要等待 await 后的函数执行完成并且有了返回结果(Promise 对象)之后,才能继续执行下面的代码。await 通过返回一个 Promise 对象来实现同步的效果。

10. 前端中的模块化开发

答案:模块化的好处就是,抽离代码,重复使用。模块化和组件化的区别与联系:组件是具体的:按照一些小功能的通用性和可复用性来抽象组件。组件化更多的关注 UI 部分,比如用户看到的弹出框,页脚,确认按钮等,这些组件可以组合成新的组件,又可以和其他组件组合组合成新的组件

模块是抽象的:按照项目业务划分的大模块
模块化侧重于数据的封装,一组相关的组件定义成一个模块,一个 json 对象可以是一个模块。封装之后需要解决的就是模块之间的依赖,babel 是目前比较火的 es6 转换器,

11.Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?

答案:1、promise 函数是同步执行的,.then 方法是异步执行的。2、模块化的规范,有 CMD 和 AMD
3、CMD (Common Module Definition), 是 sea.js 在推广过程中对模块定义的规范化产出,主要用于浏览器端。它主要特点是:* 对于依赖的模块是延迟执行,依赖可以就近书写,等到需要用这个依赖的时候再引入这个依赖,应用有 sea.js.*
   AMD 规范(Asynchronous Module Definition):是 RequireJS 在推广过程中对模块定义的规范化产出,也是主要用于浏览器端。其特点是:** 依赖前置,需要在定义时就写好需要的依赖,提前执行依赖,应用有 require.js**

12.vue 兼容 IE 浏览器:

npm 下载 babel-polyfill 模块:cnpm install babel-polyfill --save
在 main.js 中引入 require("babel-polyfill");

13. 编码规范

  • 变量在使用前一定要判断是否存在
  • 不能滥用 if 和 for 循环
  • 对于一些普通的 if 判断尽可能使用双目运算符,减少代码量
  • 代码 斜体文字 发布时不能随便在编码中输出 console 或 alert
  • 对于数据的处理可以借助第三方插件,如 underscore 或者 lodash
  • 尽可能的提取公共的代码,组件化编码,提高代码的复用率及便于后期的进行问题的定位

14.cookie 和 token 都存放在 header 中,为什么不会劫持 token?

cookie:登陆后后端生成一个 sessionid 放在 cookie 中返回给客户端,并且服务端一直记录着这个 sessionid,客户端以后每次请求都会带上这个 sessionid,服务端通过这个 sessionid 来验证身份之类的操作。所以别人拿到了 cookie 拿到了 sessionid 后,就可以完全替代你。token:登陆后后端不返回一个 token 给客户端,客户端将这个 token 存储起来,然后每次客户端请求都需要开发者手动将 token 放在 header 中带过去,服务端每次只需要对这个 token 进行验证就能使用 token 中的信息来进行下一步操作了。xss:(跨站脚本攻击)用户通过各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本获取信息,发起请求,之类的操作。csrf:(跨站请求攻击),简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了 web 中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。csrf 并不能够拿到用户的任何信息,它只是欺骗用户浏览器,让其以用户的名义进行操作。csrf 例子:假如一家银行用以运行转账操作的 URL 地址如下:http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName
那么,一个恶意攻击者可以在另一个网站上放置如下代码:<img src="<http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman>">
如果有账户名为 Alice 的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失 1000 资金。上面的两种攻击方式,如果被 xss 攻击了,不管是 token 还是 cookie,都能被拿到,所以对于 xss 攻击来说,cookie 和 token 没有什么区别。但是对于 csrf 来说就有区别了。以上面的 csrf 攻击为例:cookie:用户点击了链接,cookie 未失效,导致发起请求后后端以为是用户正常操作,于是进行扣款操作。token:用户点击链接,由于浏览器不会自动带上 token,所以即使发了请求,后端的 token 验证不会通过,所以不会进行扣款操作。这是个人理解的为什么只劫持 cookie 不劫持 token 的原因。

15. 冒泡排序如何实现,时间复杂度是多少,还可以如何改进?

16. 箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用 new 生成实例,那么箭头函数可以吗?为什么?

17.a.b.c.d 和 a’b'[‘d’],哪个性能更高?

18. 在 Vue 中,子组件为何不可以修改父组件传递的 Prop,如果修改了,Vue 是如何监控到属性的修改并给出警告的。

子组件为何不可以修改父组件传递的 Prop
单向数据流,易于监测数据的流动,出现了错误可以更加迅速的定位到错误发生的位置。如果修改了,Vue 是如何监控到属性的修改并给出警告的。

19. 介绍 http 握手过程

客户端使用 https 的 url 访问 web 服务器, 要求与服务器建立 ssl 连接
web 服务器收到客户端请求后, 会将网站的证书 (包含公钥) 传送一份给客户端
客户端收到网站证书后会检查证书的颁发机构以及过期时间, 如果没有问题就随机产生一个秘钥
客户端利用公钥将会话秘钥加密, 并传送给服务端, 服务端利用自己的私钥解密出会话秘钥
之后服务器与客户端使用秘钥加密传输

ssl. 加密套接字协议层(一种加密的通讯协定,用在使用者与网服器之间,Security Socket Layer)

20. 双向绑定和 vuex 是否冲突?

在严格模式中使用 Vuex,当用户输入时,v-model 会试图直接修改属性值,但这个修改不是在 mutation 中修改的,所以会抛出一个错误。当需要在组件中使用 vuex 中的 state 时,有 2 种解决方案:1、在 input 中绑定 value(vuex 中的 state),然后监听 input 的 change 或者 input 事件,在事件回调中调用 mutation 修改 state 的值
2、使用带有 setter 的双向绑定计算属性。见以下例子(来自官方文档):<input v-model="message">
computed: {message: { get () {return this.$store.state.obj.message}, set (value) {this.$store.commit('updateMessage', value) } } }


21. 如何把一个字符串的大小写取反(大写变小写小写变大写),例如’AbC’ 变成 ‘aBc’

function toString (s) {var arr = s.split('');
var new_arr = arr.map((item) => {return item === item.toUpperCase() ? item.toLowerCase() : item.toUpperCase();
});
return new_arr.join('');
}
console.log(processString('AbC'));

22. 如何让一个 div 水平垂直居中

23. 冒泡排序如何实现,时间复杂度是多少,还可以如何改进?

24.react-router 里的 <Link> 标签和 标签有什么区别?

Link 的本质也是 a 标签。只不过在 Link 中禁用了 a 标签的默认事件,改用了 history 对象提供的方法进行跳转。

25. 数组里面有 10 万个数据,取第一个元素和第 10 万个元素的时间相差多少

数组可以直接根据索引取的对应的元素,所以不管取哪个位置的元素的时间复杂度都是 O(1)

得出结论:消耗时间几乎一致,差异可以忽略不计

26.a.b.c.d 和 a’b'[‘d’],哪个性能更高?

应该是 a.b.c.d 比 a['b']['c']['d'] 性能高点,后者还要考虑 [ ] 中是变量的情况,再者,从两种形式的结    构来看,显然编译器解析前者要比后者容易些,自然也就快一点。

27. 箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用 new 生成实例,那么箭头函数可以吗?为什么?


箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:1、函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。2、不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。3、不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。4、不可以使用 new 命令,因为:没有自己的 this,无法调用 call,apply。没有 prototype 属性,而 new 命令在执行时需要将构造函数的 prototype 赋值给新的对象的 __proto__
new 过程大致是这样的:function newFunc(father, ...rest) {var result = {};
  result.__proto__ = father.prototype;
  var result2 = father.apply(result, rest);
  if ((typeof result2 === 'object' || typeof result2 === 'function') &&
    result2 !== null
  ) {return result2;}
  return result;
}


区别:1. 箭头函数没有自己的 this 属性、arguments 属性、而普通函数有,箭头函数的 this 指向当前函数作用域的 this。new:2. 箭头函数没有 prototype 显示原型,所以不能作为构造函数。箭头函数带来的好处:没有箭头函数的时候,函数闭包 var that = this 的事没少干,有了箭头函数,就不需要这么写了。极简语法,函数式风格,写一时爽一时,一直写一直爽!

1、组件刷新

  • 实现方式 1:借助 vue 组件 path 地址 butong, 参数不同时,自动刷新的能力,想要刷新当前组件,只需要执行方法:`

     refresh() {
     this.$router.replace({
       path: "/aboutus/index",
       query: {t: Date.now()
       }
     });
    },`
    
  • 实现方法 2:借助中间组件,先跳转到中间组件然后在中间组建中设置立即跳转回来,用户看到的效果就类似于刷新了当前页面。

2、组件内使用高德地图,组件内数据更新后,更新高德地图上点的位置和显示内容

3、vue 项目中使用高德地图

  • 1、注册 key 值,
  • 2、引入高德地图相关 js

4、slot 在父子组件中的使用

5、关于 this 的指向问题

6、微信公众号中,使用微信地图接口显示当前位置

  • 注意配置的经纬度字段值类型必须为 number 类型,不能为 string 类型,否则点击地图,将无法调取微信地图页面,也不会报错。

7、父子路由的配置,子级 path 自动补全父级 path

8、method 不能使用箭头函数,method 中方法使用定时器需要使用箭头函数

methods: {goPage: function (index) {this.newPage = index},
  inv: function () {this.invt = setInterval(() => {this.goPage(this.nextPage)
      console.log(this)
      // 此时的 this 指向是该 vue 组件,不管在哪使用,指向都是该 vue 组件
    }, 1000)
  }
}

作者:小生方勤
链接:https://juejin.im/post/5d1a15fc6fb9a07eca6993c3
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 普通函数中,setInterval() 与 setTimeout() 是 window 对象的函数,所以 this 会指向 window

9、el_table 表格嵌套时,嵌套表格样式错乱,问题定位发现:当 page 变为 2 时,页面不仅显示第 2 页的数据,第一页的数据仍然存在。

10、Vue 子组件调用父组件的方法

  • 第一种方法是直接在子组件中通过 this.$parent.event 来调用父组件的方法
  • 第二种方法是在子组件里用 $emit 向父组件触发一个事件,父组件监听这个事件就行了。

11、vue 中的 ref 是什么?

  • ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。

12、$route 和 $router 的区别?

  • $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。

$router 是 ’ 路由实例 ’ 对象包括了路由的跳转方法,钩子函数等。

13、input 设置 placeholder, 注意:1、el-input 设置 placeholder 可能失效,要对 input 元素进行设置。2、-webkit-input-placeholder 属性前面要加上 input 及父级 class 类名。

.placeholder_box input::-webkit-input-placeholder {
  color: #ccc !important;
  z-index: 100000 !important;
  font-size: 14px !important;
}
.placeholder_box input::-moz-placeholder {
  color: #ccc !important;
  z-index: 100000 !important;
  font-size: 14px !important;
}
.placeholder_box input:-ms-input-placeholder {
  color: #ccc !important;
  z-index: 100000 !important;
  font-size: 14px !important;
}

.white_placeholder input::-webkit-input-placeholder {
  color: #fff !important;
  z-index: 100000 !important;
  font-size: 12px !important;
}
.white_placeholder input::-moz-placeholder {
  color: #fff !important;
  z-index: 100000 !important;
  font-size: 12px !important;
}
.white_placeholder input:-ms-input-placeholder {
  color: #fff !important;
  z-index: 100000 !important;
  font-size: 12px !important;
}

14、wx 端代码修改的时候,不同的公众号需要修改的地方有以下几点:

  1. 要修改,微信自定义分享时设置的 appid,
  2. 相关接口的修改,如:将 www.shengdongyushang.com 修改为:yxzj.saiyunxi.com
  3. 相关图片的修改,如:主界面:分享图片及 title 及描述文字的修改。
  4. 注意:一定要注意 appid 的修改,否则会出现 redirect_url 错误。。。重要的事情要记住。。。

15、element 的 select 选中可能页面显示的值不会变,但其实获取到的传给后台的值已经变化。遇到此问题,修改方式有两种:

1. this

16、关于百度富文本上传图片和视频,显示失效问题:因为:后台返回的地址里面缺少 http:// 所有造成无效源问题。解决方法:后台修改返回地址。其实前台不用修改相关上传 viedo 代码,而我改成了 <embed> 标签


发现没有 http:// 还是不能显示视频,所以前台改不改 ueditor 相关配置文件都无所谓。额鹅鹅鹅,自己改了半天其实和不改一样一样的,心累。。。。。。。。。

正文完
 0