您的位置 首页 php

vue+element-ui 纯干货 可码 有点乱

***论阅读源码的重要性***

/*解决https下面无法加载http路径图片的问题

 <meta http-equiv ="Content-Security-Policy" content="upgrade-insecure-requests">  

es6新语法

箭头函数

在传统函数的写法上,去掉function关键字, 并且在参数列表的()与{} 函数体之间加上=>,若该函数没有参数,小括号不能省略。

 var foo = function(){};var foo =()=> {};foo();  

模板字符串

而在ES6的语法当中,采用一对反引号“来表示字符串,称之为模板字符串。

1、模板字符串内部可以随意的回车、换行、加空格,均有效,不需要另外考虑字符串拼接的问题。

2、在模板字符串内部可以用${变量名}的方式来直接取变量的值,此时在模板字符串内部,变量与字符串之间不需要用连字符+号进行拼接。

 var str1 = `ab ca`; var a = 'hello'; console.log(str1); console.log(`${a} world`); //ab ca // hello world const 和let var之后都可以被ES6语法当中的const和let所代替。const:用const定义的变量,之后不允许再对其赋值(赋值也不起作用);const a = 10;a = 20;console.log(a); // 10如果const定义的是一个对象,该对象不允许再变,但该对象当中的某个属性所对应的属性值是允许再被改变赋值的。const b={a:10};console.log(b.a); // 10b.a=20;console.log(b.a); // 20  

如果定义一个变量,该变量的值之后不会再发生变化,可以使用const, 一般我们把node当中载入的模块使用const定义的变量来接收,防止以后再对该变量进行赋值,使代码更加严谨。

let:使用let定义变量相当于定义了一个局部作用域变量,只会影响当前这个作用域。

如果定义一个变量,该变量的取值之后是会发生变化的,即用let来定义。避免使用var使得变量的污染域变大。

V8对于ES6的语法的支持情况分为三个级别:根本不支持、直接支持、严格模式下支持。对于const和箭头函数及模板字符串都是直接支持的,而let关键字为严格模式下支持。若直接使用会出现如下的报错信息。

 'use strict';let a=10;a=20;console.log(a); // 20  

javascript中的作用域和闭包

任何js代码在执行前都有大量工作要做,如果只依靠引擎自己,其实很难做到,需要用到引擎的一个得力助手:作用域

作用域为引擎提供了环境内每一个标识符的位置信息,引擎依赖这些信息可以迅速查找到他们定义的位置。标识符的位置信息,是你在写代码时将标识符写在哪里来决定的,在词法分析阶段(编译的第一个阶段),这些标识符的位置信息就会以有序列表的形式保存到环境的scope属性中(也就是作用域),以供引擎使用。也可以简单理解为,作用域里面保存的信息,在你写代码的时候已经决定了,而且会一直保持这个作用域不变。


作用域的查找规则

1、查找标识符的过程会始终从当前作用域开始,然后逐级的向外层嵌套的作用域展开,知道找到标识符,或抵达最外层的作用域(全局作用域)为止,如果找不到标识符,通常会导致错误发生。(从里向外查找)

2、每个执行环境都可以进入到外层作用域中查找标识符,但不能进入到内层作用域中查找标识符。


闭包原理:

1、southtree代码管理工具 gitlab代码管理平台的使用

2、阿里云云效平台使用rdc、工作任务分配管理、bug修改

3、电销后台管理系统

4、vue 组件化开发

5、vue filter过滤器、find函数、map、set

6、h5与app联调 (navigator 对象包含有关浏览器的信息)** app && h5混合开发

判断安卓和ios环境:isAndroid: navigator.userAgent.includes(‘Android’),

isIOS: navigator.userAgent.includes(‘OS’)

安卓: 判断navigator.userAgent.includes(‘yangcheJS’) 是否存在yangcheJS

存在则与app匹配成功 => 赋值:this.mobilePhone = JSON.parse(window.yangcheJS.getUserPhone())

h5向app传值: (均为app端定义的方法,h5则直接调用app方法传值)

 let arrData = { payLink: this.body }window.yangcheJS.WebViewJavascriptBridge('RequestPayment', JSON.stringify(arrData), '', 'onlinePay', '')  

app回调h5的方法 将h5的方法暴露到window上

 let me = this;window['getStatus'] = (status) => {me.getStatus(status);}  

getStatus()

IOS:

 IOS:window.webkit.messageHandlers.getUserPhone.postMessage('111');先向ios发送一串指令(类似注册)(getUserPhone为约定方法)  

后接收ios传过来的数据(同安卓)暴露一个getUserPhone()方法method里接收数据

7、vue图片前端签名直传阿里云oss

接口获取阿里云服务端 签名、policy、OSSAccessKeyId

 const x2js = require('x2js');let formData = new FormData()  

// 参数顺序不能变

 formData.append('key', '${filename}') // key默认${filename}formData.append('policy', this.aliForm.policy)formData.append('OSSAccessKeyId', this.aliForm.ossAccessKeyId)formData.append('success_action_status', '201') // 默认201状态*formData.append('Signature', this.aliForm.signature)formData.append('file', file.raw)this.$http({method: 'post',url: '#39;,data: formData}).then((resd) => {let myheadInfo = this.$x2js.xml2js(resd.data)console.log(resd)this.ruleForm.headImg = myheadInfo.PostResponse.Location}).catch((err) => {})  

8、promise.all/async await 异步接口并发处理

9、encodeURI(string)对字符串编码,encodeURIComponent(string)对字符串解码(特殊字符:冒号、正斜杠、问号和井字号)

10、vue 引入百度地图获取定位 解决new BMap未定义 (高德地图就是个垃圾)

11、不是为了vue写的插件不支持Vue.use()加载方式 使用Vue.prototype挂载到vue原型上添加全局属性和方法

12、组件之间传值方法

 父组件 =》 子组件页面:<userManage-box @ msg =“getMsg :msg=msg></userManage-box>父组件定义 component:{"userManage-box": () => import("./userManage-box")} 传值 :msg=msg子组件使用prop接收 接收值类型:Array String Number。。子组件 =》 父组件this.$emit(msg,getMsg) msg:方法名字,getMsg:要传出的值父组件定义方法接收 @msg=“getMsg” method里getMsg(e)接收子组件传过来的值兄弟组件之间通过父组件通信  

13、vue webSocket 通信

14、 微信 web-view(小程序内置h5)

h5端:引入微信jssdk/使用npm安装jssdk

 <script type="text/javascript" src="#34;></script>npm install weixin-js-sdk --saveimport wx from 'weixin-js-sdk';Vue.prototype.$wx = wx;  

h5向小程序传值

 mounted(){wx.miniProgram.getEnv(res => {this.inLiteApp = res.miniprogram})}方法: {if (this.inLiteApp == true) {wx.miniProgram.navigateTo({url: '/pages/payment/index/main?orderId=' + this.detail.orderId + '&orderCode=' + this.detail.orderCode + '&amount=' + this.detail.stats[2].value})}}  

小程序接收h5传过来的值(h5传过来的值直接从optios里取)

 async onLoad(options) {this.payInfo = options}  

小程序向h5 传值

 <web-view :src="webviewUrl" @message="postMessage"/>onLoad(options) {// params为其他页面或者接口里接收到的数据const params = {userId: this.userId,ticket: this.ticket,appTicket: this.appTicket}this.webviewUrl = `#/home?parmas=${this.params}`;}  

h5接收小程序传过来的值

 created() {wx.miniProgram.getEnv(res => {if (res.miniprogram) { //判断微信环境const queryUrl = this.getRequest()let urlParams = Object.assign(queryUrl, this.$route.query) //参数合并 Object.assign()是浅拷贝let wxParmas = JSON.parse(queryUrl.parmas)console.log('我接收到的参数', wxParmas)document.cookie = "app_ticket=" + wxParmas.appTicket; //接收到的微信参数放入cookie里this.$store.dispatch("auth/saveToken", { 调取store里的user.js的auth/saveToken方法,更新数据token: wxParmas.ticket,remember: 365})}})},methods: {getRequest() {var url = decodeURIComponent(location.search); // 对参数解码获取到'#'后面的参数var theRequest = new Object();if (url.indexOf("?") != -1) { // 查找是否包含'?'var str = url.substr(1); // 截取字符串var strs = str.split("&"); // 分割字符串for(var i = 0; i < strs.length; i ++) {theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]); // unescape()函数解码字符串}}return theRequest; //返回结果},}  

15、md5密码加密

 let password = md5(this.password);默认小写32位let password = md5(this.password).toUpperCase(); 大写32位  

16、关于vue深拷贝与浅拷贝的思考

假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝;

假设B复制了A,当修改A时,如果B没变,那就是深拷贝

深拷贝的实现


*递归复制所有层级属性

 function deepClone(obj){let objClone = Array.isArray(obj)?[]:{};if(obj && typeof obj==="object"){for(key in obj){if(obj.hasOwnProperty(key)) {// 判断ojb子元素是否为对象,如果是,递归复制if(obj[key]&&typeof obj[key] ==="object"){objClone[key] = deepClone(obj[key]);}else{//如果不是,简单复制objClone[key] = obj[key];}}}}return objClone;}let a=[1,2,3,4],b=deepClone(a);a[0]=2;console.log(a,b);  

*JSON对象的parse和stringify实现

 function deepClone(obj) {let _obj = JSON.stringify(obj),objClone = JSON.parse(_obj);return objClone}let a=[0,1,[2,3],4],b=deepClone(a);a[0]=1;a[2][0]=1;console.log(a,b);  

17、vue操作数组的几种方法(push()、pop()、shift()和unshift()实现数组的增删操作、sort()和 reverse()对数组项进行排序操作)

 concat():先给当前数组创建一个副本,然后将接收到的参数添加到这个副本(数组)的末尾,最后返回一个新的数组var arr = [`大漠`,'30','W3cplus'];console.log(arr); // ["大漠", "30", "W3cplus"]var arr2 = arr.concat('Blog','2014');console.log(arr2); // ["大漠", "30", "W3cplus", "Blog", "2014"]**concat()方法是在数组的副本上进行操作并返回新构建的数组,所以并不会影响到原来的数组。  

18、 解构 赋值

 对象的解构赋值用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };x // 1y // 2z // { a: 3, b: 4 }  

19、Promise / vue中axios的封装

 promise是异步编程的一种解决方案,比传统异步解决方案【回调函数】和【事件】更合理、更强大安装:axios npm install axios引入:在项目的src目录中新建一个request文件夹,然后在里面新建一个http.js和api.js文件。http.js文件用来封装axios,api.js用来统一管理接口// 在http.js中引入axiosimport axios from 'axios'; // 引入axiosimport QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到// vant的toast提示框组件,大家可根据自己的ui组件更改。import { Toast } from 'vant';  

环境的切换:项目环境中可能有开发、测试、生产环境,我们通过node的环境变量来匹配我们的默认接口url前缀。axios.defaults.baseURL可以设置axios的默认请求地址

// 环境的切换

 // 环境的切换if (process.env.NODE_ENV == 'development') {axios.defaults.baseURL = '#39;;}else if (process.env.NODE_ENV == 'debug') {axios.defaults.baseURL = '#39;;}else if (process.env.NODE_ENV == 'production') {axios.defaults.baseURL = '#39;;}  

设置请求超时:通过axios.default.timeout设置默认的请求超时时间。例如超过10s,就会告知用户当前接口请求超时,请刷新等

 axios.default.timeout = 10000;post请求头的设置:post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为application/x-www-form-urlencoded;charset=UTF-8axios.default.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';请求拦截:有些请求是需要用户登录之后才能访问的,或者post请求时我们需要序列化我们提交的数据,这时候我们可以在请求的发送之前进行拦截,从而进行我们想要的操作//先导入vuex,因为我们要使用到里面的状态对象//vuex的路径根据自己的路径去写import store from '@/store/index';//请求拦截器axios.interceptors.request.use( config  => {// 每次发送请求之前判断vuex中是否存在token// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断const token = store.state.token;token && (config.headers.Authorization = token);return config;},error => {return Promise.error(error);})  

token:一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,然后用户每次在进入页面的时候(main.js中),会首先从本地存储中读取token,如果token存在则说明用户已经登录过了,则更新vuex中的token状态。然后,在每次请求接口的时候都会在header中带上token,

后台就可以根据你带的token判断你的登录是否过期,如果没有携带,则说明没有登录过。

响应拦截:服务器返给我们的数据,我们在拿到之前根据后台返回的状态码对他进行一些处理(200 成功,401 未登录, 403 token过期, 404 请求不存在, 其他直接抛出错误提示)

//响应拦截器

axios.interceptors.response.use(

response => {

// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据

// 否则的话跑出错误

if(response.status === 200) {

return Promise.resolve(response);

} else {

return Promise.reject(response);

}

},

//状态码不是2开头的情况

//这里可以跟你们后台开发人员协商好统一的错误码

//然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等

// 下面列举几个常见的操作,其他需求可自行扩展

error => {

if(error.response.status) {

switch (error.response.status) {

//401:未登录

//未登录则跳转登录页面,并携带当前页面的路径

// 在登录成功后返回当前页面,这一步需要在登录页面操作

 case 401:router.replace({path: '/login',query: {redirect: router.currentRoute.fullPath}});break;//403 token过期// 登录过期对用户进行提醒// 清除本地token和清空vuex中的token对象// 跳转登录页面case 403:Toast({message: '登录过期,请重新登录',duration: 1000,forbidClick: true});//清除tokenlocalStorage.removeItem('token');store.commit('loginSuccess', null);//跳转登录页面,并将要浏览的页面fullPath传过去,登陆成功后跳转需要访问的页面setTimeout(() => {router.replace({path: '/login',query: {redirect: router.currentRoute.fullPath}});}, 1000);break;//404请求不存在case 404:Toast({message: '网络请求不存在',duration: 1500,forbidClick: true});break;//其他错误,直接抛出错误提示default:Toast({message: error.response.data.message,duration: 1500,forbidClick: true});}return Promise.reject(error.response);}});  

封装get方法和post方法

20、vuex (vue状态管理器)

解释:一个专为vue应用程序开发的状态管理模式 它集中式存储管理应用的所有组件的状态,而更改状态的唯一方法就是提交mutation

例:this.$store.commit(‘SET_VIDEO_PAUSE’, video_pause), SET_VIDEO_PAUSE为mutations属性中定义的方法

五种状态和属性:State、Getter、Mutation、Action、Module(mapAction)

流程:页面通过mapAction异步提交事件到action。action通过commit把对应的参数同步提交到mutation。mutation会修改state里对应的值。最后通过getter把对应的值跑出去,在页面计算属性中通过mapGetter来动态获取state里的值

State的特性:存放数据的地方,类似一个仓库

当mutation修改了state里的数据的时候,会动态修改所有调用这个变量的所有组件里的值(若是store中的数据发生变化,依赖这个数据的组件就会实时更新)

Getter的特性:getter用来获取数据,mapGetter经常在计算属性中被使用(通常放在mixins里全局使用)

Mutation的特性:Action类似于mutation,不同在于:

Action提交的是mutation,而不是直接变更状态

Action可以包含任意异步操作

优势:1、响应式的数据管理 一个页面发生数据变化,动态的改变对应的页面,相比使用localStorage只能存储字符串数据格式,因此还得封装自己的写入写出,localStorage优势在于永久存储

1、多个组件依赖于同一状态时。

2、来自不同组件的行为需要变更同一状态。

21、typeOf {} //object 用于返回数据的数据类型

22、webpack(模块打包机)

是什么:webpack是一个打包模块化js的工具,分析你的项目结构,找到js模块以及其他的一些浏览器不能直接运行的拓展语言(scss,ts等),并将其打包为合适的格式以供浏览器使用。

23、vue前端性能优化

1、vue-router路由懒加载(按需加载页面,提高页面加载性能,提高用户体验)

export default new Router({

mode: ‘history’,

routes: [

{

path: ‘/’,

component: resolve => require([‘@/components/DefaultIndex’],resolve),

children: [

{

path: ”,

component: resolve => require([‘@/components/Index’],resolve)

},

{

path: ‘*’,

redirect: ‘/Index’

}

]

})

2、webpack压缩图片(减少图片大小)

安装image-webpack-loader

npm install image-webpack-loader –save-dev

配置

在webpack.base.conf.js文件中引入配置

1: 引入:

require(“image-webpack-loader”)

2:配置:

module: {

rules: [

…(config.dev.useEslint ? [createLintingRule()] : []),

{

test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,

loader: ‘url-loader’,

options: {

loader: ‘image-webpack-loader’,

options: {

bypassOnDebug: true,

}

}

},

或者也可配置为:

{

test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,

use:[

{

loader: ‘url-loader’,

options: {

limit: 10000,

name: utils.assetsPath(‘img/[name].[hash:7].[ext]’)

}

},

{

loader: ‘image-webpack-loader’,

options: {

bypassOnDebug: true,

}

}

]

}

3、取消额外打包的js文件

配置

在config/index.js文件里面修改

build:{}里面的productionSourceMap为false

4、打包后的js过大,将js打包多个文件

entry:{

main:’xxx.js’

}

plugins:{

new commonsChunkPlugin({

name:’commons’,

minChunks:function(module){

// 下边return参考的vue-cli配置

// any required modules inside node_modules are extracted to vendor

return (

module.resource &&

/\.js$/.test(module.resource) &&

module.resource.indexOf(

path.join(__dirname, ‘../node_modules’)

) === 0

)

}

}) ,

// 以下才是关键

new commonsChunkPlugin({

name:’charts’,

chunks:[‘commons’]

minChunks:function(module){

return (

module.resource &&

/\.js$/.test(module.resource) &&

module.resource.indexOf(

path.join(__dirname, ‘../node_modules’)

) === 0 && [‘jquery.js’, ‘highcharts.js’,’echarts’].indexOf( module.resource.substr(module.resource.lastIndexOf(‘/’)+1).toLowerCase() ) != -1

)

}

})

}

5、去掉不必要的插件

plugins: [//webpack.config.jsnew webpack.optimize.UglifyJsPlugin({ warnings: false,

compress: {

join_vars: true,

warnings: false,

},

toplevel: false,

ie8: false,

]

6、gzip压缩

# 开启gzip

gzip on;

# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩

gzip_min_length 1k;

# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明

gzip_comp_level 2;

# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。

gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;

# 是否在http header中添加Vary: Accept-Encoding,建议开启

gzip_vary on;

# 禁用IE 6 gzip

gzip_disable “MSIE [1-6]\.”;

7、服务器缓存

location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {

access_log off;

expires 30d;

}

location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {

access_log off;

expires 24h;

}

location ~* ^.+\.(html|htm)$ {

expires 1h;

}

8、遍历数组往每一项中添加一个字段

this.lists = res.body.map(item => {

this.$set(item, ‘type’, -1)

return item

})

 1、vue-router路由懒加载(按需加载页面,提高页面加载性能,提高用户体验)export default new Router({mode: 'history',routes: [{path: '/',component: resolve => require(['@/components/DefaultIndex'],resolve),children: [{path: '',component: resolve => require(['@/components/Index'],resolve)},{path: '*',redirect: '/Index'}]})2、webpack压缩图片(减少图片大小)安装image-webpack-loadernpm install image-webpack-loader --save-dev配置在webpack.base.conf.js文件中引入配置1: 引入:require("image-webpack-loader")2:配置:module: {rules: [...(config.dev.useEslint ? [createLintingRule()] : []),{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader',options: {loader: 'image-webpack-loader',options: {bypassOnDebug: true,}}},或者也可配置为:{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,use:[{loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]')}},{loader: 'image-webpack-loader',options: {bypassOnDebug: true,}}]}3、取消额外打包的js文件配置在config/index.js文件里面修改build:{}里面的productionSourceMap为false4、打包后的js过大,将js打包多个文件entry:{main:'xxx.js'}plugins:{new commonsChunkPlugin({name:'commons',minChunks:function(module){// 下边return参考的vue-cli配置// any required modules inside node_modules are extracted to vendorreturn (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0)}}) ,// 以下才是关键new commonsChunkPlugin({name:'charts',chunks:['commons']minChunks:function(module){return (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0 && ['jquery.js', 'highcharts.js','echarts'].indexOf( module.resource.substr(module.resource.lastIndexOf('/')+1).toLowerCase() ) != -1)}})}5、去掉不必要的插件plugins: [//webpack.config.jsnew webpack.optimize.UglifyJsPlugin({ warnings: false,compress: {join_vars: true,warnings: false,},toplevel: false,ie8: false,]6、gzip压缩# 开启gzipgzip on;# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩gzip_min_length 1k;# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明gzip_comp_level 2;# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;# 是否在http header中添加Vary: Accept-Encoding,建议开启gzip_vary on;# 禁用IE 6 gzipgzip_disable "MSIE [1-6]\.";7、服务器缓存location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {access_log off;expires 30d;}location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {access_log off;expires 24h;}location ~* ^.+\.(html|htm)$ {expires 1h;}8、遍历数组往每一项中添加一个字段this.lists = res.body.map(item => {this.$set(item, 'type', -1)return item})  

文章来源:智云一二三科技

文章标题:vue+element-ui 纯干货 可码 有点乱

文章地址:https://www.zhihuclub.com/38330.shtml

关于作者: 智云科技

热门文章

网站地图