xiqe / blog Goto Github PK
View Code? Open in Web Editor NEWblog相关资源
blog相关资源
移动端页面布局的问题,在当今前端是比较常见的话题,因为不同终端设备的分辨率,dpr等不同,导致前端无法用单一的px值来将页面的元素固定,需要通过技术手段在不同的环境下进行适配,来保证页面最佳的可读性,这里将会总结一些常见的方案。
这是最早的布局解决方案,解决成本低,高效。
将页面元素的宽度以百分比来进行设置,高度不变。
缺点也显而易见,在例如ipad横屏下,页面被拉伸很多,造成视觉体验较差。
为了解决百分比布局带来的宽屏视觉上的缺点,引入了media的方案,将设备按分辨率分成几个标准化的区间,视觉根据区间设计出2-3个方案(方案数量决定了精细化的程度),前端根据media来区分在某个分辨率区间读取相应的css方案。
缺点是需要设计和前端同时多出多个方案。
代码模式:
html{font-size:10px}
@media screen and (min-width:320px) and (max-width:480px){html{font-size:12px}}
@media screen and (min-width:480px) and (max-width:640px){html{font-size:14px}}
@media screen and (min-width:640px){html{font-size:16px}}
根据标准视觉稿,先作出一套以rem为单位的页面,然后通过在不同分辨率的情况下,用js或media去改变根html的font-size的值,从而到达页面的自适应效果。
Flexible作为比较知名的成熟方案,也已经出现很久了,技术原理主要就是为了能让页面更好的适配各种不同的终端,通过Hack手段来根据设备的dpr值相应改变标签中viewport的值,从而让页面达么缩放的效果,也变相的实现页面的适配功能。
<!-- dpr = 1--> <meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no">
<!-- dpr = 2--> <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">
<!-- dpr = 3--> <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no">
Flexible技术原理:
根据dpr的值来修改viewport实现1px的线
根据dpr的值来修改html的font-size,从而使用rem实现等比缩
使用Hack手段用rem模拟vw特性
(效果图见Viewport)
Viewport相关的单位有四个,分别为vw、vh、vmin和vmax。
vw:是Viewport's width的简写,1vw等于window.innerWidth的1%。
vh:和vw类似,是Viewport's height的简写,1vh等于window.innerHeihgt的1%。
vmin:vmin的值是当前vw和vh中较小的值。
vmax:vmax的值是当前vw和vh中较大的值。
在这个方案中,我们用vw来代替rem的缩放方案,就可以将页面做到任意环境下的同等自适应缩放。
最后想要说的是,以上几个方案并非唯一绝对的方案,而是可以根据自身业务产品需求,进行有效组合取舍,找到适合自己项目的才是真正的最佳实践。
本文Demo使用了Viewport的方式来进行布局,并且通过media来实现web端在2k,4k物理像素屏(例如大屏电视)下的自适应兼容,利用高度来区分电脑屏和电视屏(高度仅测试,无实际意义)。为实现一套代码多端兼容的简单Demo。
自定义属性:组件props中声明的属性
原生属性:没有声明的属性,默认自动挂载到组件根元素上,设置inheritAttrs为false可关闭自动挂载
特殊属性:挂载到组件根元素上,支持字符串、对象、数组等多种语法
@click @input @change @xxx等事件
this.$emit('eventName'...)出发
@input.trim @click.stop @submit.prevent 等
一般用于原生HTML元素,自定义组件需要自行开发支持
<template slot="xxx">...</template>
<template v-slot:xxx>...</template>
<template slot="xxx" slot-scope="props">...</template>
<template v-slot:xxx="props">...</template>
属性、事件、插槽完全都可以通过属性解决,大属性的概念
双向绑定:model与view互相更新
单项数据流:model更新view
<PersonalInfo
v-model="phoneInfo"
:zip-code.sync="zipCode"
/>
<PersonalInfo
:phone-info="phoneInfo"
@change="val=>(phoneInfo = val)"
:zip-code.sync="zipCode"
@update:zipCode="val=>(zipCode = val)"
/>
JQuery:Event ===> Element
Vue:Event ====> State ====> Element
如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。
如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。
export default {
name: 'functional-button',
functional: true,
render(createElement, context) {
return createElement('button', 'click me')
}
}
<template>
<FunctionalButton>
click me
</FunctionButton>
</template>
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
<input v-focus>
<span>Message:{{ msg }}</span>
<span>Message:{ this.msg }</span>
template & JSX都是语法糖
Vue是单项数据流的。Object.defineProperty()
返回值是 this
如果需要需要返回值可以使用回调参数
替换。
更新DOM性能问题
会引入状态bug问题(因为array改变后,index会动态的相应改变)
- 支持:push、pop、shift、unshift、splice、sort、reverse
- 不支持:filter、concat、slice
- 原理同样使用Object.defineProperty对数组方法进行改写
watch:{
firstName:function(val){
clearTimeout(this.firstTimeout);
this.firstTimeout = setTimeout(()=>{
this.fullName = val + '"" + this.lastName
},500)
}
}
只能用watch,无法使用computed
*该笔记基于 Vue开发实战课程 整理
XHR | $.ajax | fetch | axios | |
---|---|---|---|---|
是否底层API | ✓ | - | ✓ | - |
实现 | - | XHR | - | XHR |
Promise | - | - | ✓ | ✓ |
浏览器兼容 | ActiveXObject | ✓ | polyfill | polyfill |
适用 | MVC | MVC | MVVM | MVVM |
Status Code | - | - | ✓ | ✓ |
Jsonp | - | ✓ | - | - |
拦截器 | - | ✓ | - | ✓ |
abort | ✓ | ✓ | - | ✓ |
timeout | ✓ | ✓ | - | ✓ |
progress | ✓ | ✓ | - | ✓ |
node | - | - | - | ✓ |
引入成本 | - | 高 | - | 低 |
//main.js
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
INCREMENT(state){
state.count++
}
},
actions:{
increment(commit){
setTimeout(() => {
commit('INCREMENT')
}, 1000)
}
},
getters:{
doubleCount(state){
return state.count+2
}
}
})
//App.vue
<template>
<div id="app">
{{count}}
<br />
{{$store.getters.doubleCount}
<button @click="$store.commit('INCREMENT')">count++</button>
<button @click="$store.dispatch('increment')">count++</button>
</div>
</template>
...
computed:{
count(){
return this.$store.state.count
}
}
...
import Vue from 'vue'
const Store = function Store (options={}){
const {state={},mutations={}} = options;
this._vm = new Vue({ // 将state放在Vue的data下,就变成了响应式的数据
data:{
$$state: state
}
})
this._mutations = mutations
}
Store.prototype.commit = function(type,payload){
if(this._mutations[type]){
this._mutations[type](this.state,payload)
}
}
Object.defineProperties(Store.prototype,{ // 将state的get重写,每次get值的时其实是访问_vm实例下state 的值
state:{
get:function(){
return this._vm._data.$$state
}
}
})
computed: mapState({
products: state => state.products
})
// 等价于
computed: {
products(){
return this.$store.state.products
}
}
methods:mapAction('cart',{
'addProductToCart'
})
// 等价于
methods;{
addProductToCart(product){
this.$store.dispatch('cart/addProductToCart',product)
}
}
*该笔记基于 Vue开发实战课程 整理
前端是一个快速发展的领域,而在前端的技术栈当中,前端请求又是最见的一个领域,通过请求接口数据,才能将一个静态的页面动态化。本文将以前端发展的时间轴来逐一分析前端请求的技术演变及其优劣,针对这一课题,作者查阅了相关资料加以自己的理解,如有错误,烦请指出。
XMLHttpRequest是最早出现的与服务器交换数据的方案,有了XMLHttpRequest,开发者终于可以在不重新加载页面的情况下更新网页,可以在页面加载后请求接受以及发送数据。而所有浏览器均可以获取XMLHttpRequest对象:
var xhr = new XMLHttpRequest(); //获取xhr对象
但是XMLHttpRequest是个比较粗燥的底层对象,各个浏览器对其的创建方法也不同,以下是兼容方法:
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP'); //IE5,6
} catch (e) {}
}
}
使用XMLHttpRequest发起一个get请求
//get请求
xhr.open("GET","test1.txt",true);
xhr.send();
完整的post请求代码如下:
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
if (xhr) {
xhr.onreadystatechange = onReadyStateChange;
xhr.open('POST', '/api', true);
// 设置 Content-Type 为 application/x-www-form-urlencoded
// 以表单的形式传递数据
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('username=admin&password=root');
}
// onreadystatechange 方法
function onReadyStateChange() {
// 该函数会被调用四次
if (xhr.readyState === 4 &&xhr.status === 200) {
console.log('执行成功');
} else {
console.log('执行出错');
}
}
说到Jquery,这是一个时代,几乎**了前端10年有余,彻底解决了UI层与数据层交互的问题,直到三大框架(Angular/React/Vue)的出现,前端进入MVVM浪潮。而Ajax将XHR进行封装,让开发者可以更加便捷方便进行使用。
$.ajax({ //标准写法
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
$.get(url,function(){}); //get请求
$.post(url,body,function(){}); //post请求
$.getJSON(url,function(){}); //get请求从服务器加载Json编码
优点:
缺点:
fetch其实是一个新世界,脱离的XHR,完全是基于Promise的异步处理机制,使用起来会比起ajax更加简单。
使用fetch的代码会相比xhr来说更具有条理性
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
在使用ES6的箭头函数后
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
优点:
看到以上,或许你会觉得fetch真的很美好,但是请了解,fetch本身是一个 low-level 的 API,它注定不会像你习惯的 $.ajax 或是 axios 等库帮你封装各种各样的功能或实现。
所以它是存在一定的缺点:
//安装
npm install fetch-jsonp --save-dev
//使用
fetchJsonp(url, {
timeout: 3000,
jsonpCallback: 'callback'
}).then(function(response) {
console.log(response.json());
}).catch(function(e) {
console.log(e)
});
fetch(url,{
credentials: 'include' //include表示cookie既可同域,也可跨域,‘same-origin’表示只可同域
});
可以用Promise.race()实现,Promise.race(iterable) 方法返回一个Promise对象,只要 iterable 中任意一个Promise 被 resolve 或者 reject 后,外部的Promise 就会以相同的值被 resolve 或者 reject。
fetch中的Response.body 中实现了getReader()方法用于读取原始字节流, 该字节流可以循环读取。参考javascript - Progress indicators for fetch? - Stack Overflow
2016 - the year of web streams
axios也是比较新的网络请求的类库,并且被尤雨溪尤大推荐,已成为VUE的网络请求标配,也是十分的火爆。它本身也是对原生XHR的封装。
兼容性上虽然axios本质上也是对原生XHR的封装,但是它也依赖原生ES6 Promise的实现,和fetch一样需要polyfill的兼容。
安装
//npm
npm install axios
//cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"><\/script>
基本使用如下:
axios({
method: 'GET',
url: url,
})
.then(res => {console.log(res)})
.catch(err => {console.log(err)})
// get请求
axios.get(url)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// post请求
axios.post(‘/user’, {
name: 'Jerry',
lastName: 'Liang'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
在开发过程中,经常会遇到比较尴尬的场景就是多请求的串行与并发,并发比较容易解决,不存在回调地狱,但是代码可读性就会容易变得很渣,而串行问题对于前端是绝望的,最好的办法是后端来做合并,如果后端不做这块的处理,前端就必须来面对回调地狱。
// ajax
$.ajax({
url: '',
data: '',
success: function (data) {
$.ajax({
url: '',
data: '',
success: function (data) {
$.ajax({
// 如此一层嵌套一层
})
}
})
}
})
//axios
axios.get(url)
.then(res => {
return axios.get(url,{
{name:result.name}
});
}).then(res => {
//如此一层层嵌套
});
//ajax 通过计数器实现(虽然Jquery支持$.when的方式,但此处不做案例)
var num = 0;
function all(){
num++;
if(n>=3)console.log('三个请求全部完成');
}
$.ajax({
url: '',
data: '',
success: function (data) {
console.log("ajax请求1 完成");
all();
}
})
$.ajax({
url: '',
data: '',
success: function (data) {
console.log("ajax请求2 完成");
all();
}
})
$.ajax({
url: '',
data: '',
success: function (data) {
console.log("ajax请求3 完成");
all();
}
})
//axios
function getInfo() {
return axios.get(url);
}
function getUser() {
return axios.get(url);
}
axios.all([getInfo(), getUser()])
.then(axios.spread(function (info, user) {
// 两个请求现在都执行完成
}));
XHR | $.ajax | fetch | axios | |
---|---|---|---|---|
是否底层API | ✓ | - | ✓ | - |
实现 | - | XHR | - | XHR |
Promise | - | - | ✓ | ✓ |
浏览器兼容 | ActiveXObject | ✓ | polyfill | polyfill |
适用 | MVC | MVC | MVVM | MVVM |
Status Code | - | - | ✓ | ✓ |
Jsonp | - | ✓ | - | - |
拦截器 | - | ✓ | - | ✓ |
abort | ✓ | ✓ | - | ✓ |
timeout | ✓ | ✓ | - | ✓ |
progress | ✓ | ✓ | - | ✓ |
node | - | - | - | ✓ |
引入成本 | - | 高 | - | 低 |
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.