.border { border: 1px solid #ccc }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border { border: 0.5px solid #ccc }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border { border: 0.333333px solid #ccc }
}
这样的1张6X6的图片, 9宫格等分填充border-image, 这样元素的4个边框宽度都只有1px
@media screen and (-webkit-min-device-pixel-ratio: 2){
.border{
border: 1px solid transparent;
border-image: url(border.gif) 2 repeat;
}
}
.shadow {
-webkit-box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5);
box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5);
}
//devicePixelRatio=2设置meta
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
//devicePixelRatio=3设置meta
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
//第一种方法
//构建1个伪元素, 将它的长宽放大到2倍, 边框宽度设置为1px, 再以transform缩放到50%
.radius-border{
position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
.radius-border:before{
content: "";
pointer-events: none; /* 防止点击触发 */
box-sizing: border-box;
position: absolute;
width: 200%;
height: 200%;
left: 0;
top: 0;
border-radius: 8px;
border:1px solid #999;
-webkit-transform(scale(0.5));
-webkit-transform-origin: 0 0;
transform(scale(0.5));
transform-origin: 0 0;
}
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.radius-border:before{
content: "";
pointer-events: none; /* 防止点击触发 */
box-sizing: border-box;
position: absolute;
width: 200%;
height: 200%;
left: 0;
top: 0;
border-radius: 8px;
border:1px solid #999;
-webkit-transform(scale(0.3333));
-webkit-transform-origin: 0 0;
transform(scale(0.3333));
transform-origin: 0 0;
}
}
rem是什么是一个相对单位参照根元素的字体大小 只要动态修改跟元素字体大小所有rem单位都会跟着改变 那么rem的根元素改变参照点是谁: 设计图 以设计图大小对应的的屏幕作为参照点 假设一个设计图大小对应的真实屏幕的根元素值 例如750设计图真实屏幕是375 根元素100px 计算其他屏幕就使用 其他屏幕大小/375 * 100 求到其他屏幕的根元素大小
css3中box-shadow的溢出问题 子容器加了box-shadow在父容器中可能存在溢出 可以通过给父元素添加overflow:hidden解决
box-shadow阴影被覆盖问题
例如 var arr = [1,2,3]
arr.toString() == '1,2,3';
例如 var arr = [1,2,3]
arr.join(',') == '1,2,3'; 还可以自由控制需要什么隔开例如 - , 如果不需要什么隔开就写空 arr.join('') == '123';
但是默认sort是按照ASCII编码排序的 如果需要按照数值的从小到大 从大到小需要使用第二个参数 是一个回调函数 回调函数需要两个参数 用来说明你要按照什么方式排序
例如a,b
如果 a - b < 0 表示 a 比 b小 那么真实的a代表的数字就会排在b前面
如果 a - b == 0 那么表示2个值相等 就按顺序排序
如果 a - b > 0 表示 a比b大 那么真实a代表的数组就会排在b后面
function sortNumber(a, b) {
return a - b // 从小到大
// return b - a // 从大到小
}
var arr = [10, 5, 40, 25, 1000, 1]
document.write(arr + "<br />")
document.write(arr.sort(sortNumber));// 1 5 10 25 40 1000 从小到大
var arr = [10, 20, 1, 2];
var t;
for(var i=0;i<arr.length;i++){
for(j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
console.log(arr); //[1, 2, 10, 20]
// 快速排序
var quickSort = function(arr) {
if(arr.length < 1) {//如果数组就是一项,那么可以直接返回
return arr;
}
var centerIndex = Math.floor(arr.length / 2);//获取数组中间的索引
var centerValue = arr[centerIndex];//获取数组中间项
var left = [], right = [];
for(var i = 0; i < arr.lenght; i++){
if(arr[i] < centerValue){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
return quickSort(left).contanct([centerValue], quickSort(right));//递归调用
}
var obj = JSON.parse(str);
什么是原型链 简单来说就是对象和构造函数之间连接的一个链条 简称原型链
原型链的作用 可以通过原型链继承构造函数对象定义的一些公共的属性方法
原型链的流程图
(function(){
console.log(a);// undefined 虽然此时在函数内打印有a 因为var变量声明会提前所以不会报错 但是赋值不会提前所以a没有值是 undefined
var a = b = 1;
})();
console.log(b);//1 因为 var a = b = 1 其实b并没在里面var所以 b是全局变量并且赋值为了1所以是1
console.log(a);// 因为 var a = b = 1; 这个var是在自执行函数里面的自执行函数是一个函数作用域 所以var a是函数内的局部变量所以外界拿不到 即是报错 a is not defined
var name = '王五';
var obj = {
name: '张三',
getName:function(){
return this.name;
},
children:{
name:'李四',
getName:function(){
return this.name;
}
}
}
console.log(obj.getName());//张三
console.log(obj.children.getName());//李四
var getName = obj.children.getName;
console.log(getName());//王五
// 那么如果我想调用getName() 但是想打印张三怎么办 可以使用call函数改变调用当前函数的this指针
console.log(getName.call(obj));//张三
// 定义一个栈的类 实现栈的push pop getMax getMin等函数
// 并实现先进后出 后进先出 而且能够不断求出 当前栈里面的数据的最大值最小值
class Stack {
constructor(){
this.dataStack = [];
this.maxStack = [];
this.minStack = [];
}
// 入栈
push(item){
if(this.minStack.length <= 0){
this.minStack.push(item)
}
else if(item <= this.getMin()){
this.minStack.push(item)
}
if(this.maxStack.length <= 0){
this.maxStack.push(item)
}
else if(item >= this.getMax()){
this.maxStack.push(item)
}
this.dataStack.push(item);
}
// 出栈
pop(){
if(this.dataStack.length <= 0){
return
}
let value = this.dataStack.pop();
if(value == this.getMin()){
this.minStack.pop()
}
if(value == this.getMax()){
this.maxStack.pop();
}
return value;
}
// 求最小值
getMin(){
if(this.minStack.length <=0){
return 0;
}
return this.minStack[this.minStack.length-1];
}
// 求最大值
getMax(){
if(this.maxStack.length <=0){
return 0;
}
return this.maxStack[this.maxStack.length-1];
}
}
// 创建栈的对象
var stack = new Stack();
// 调用入栈
stack.push(3);
stack.push(5);
stack.push(10);
stack.push(7);
stack.push(6);
// 调用求最大值 最小值的函数
console.log(stack.dataStack);
console.log(stack.getMax());
console.log(stack.getMin());
// 出栈
stack.pop();
stack.pop();
// 出栈后的最大值最小值
console.log(stack.getMax());
console.log(stack.getMin());
console.log(stack.minStack);
console.log(stack.maxStack);
stack.pop();
console.log(stack.getMax());
console.log(stack.getMin());
console.log(stack.minStack);
console.log(stack.maxStack);
stack.pop();
console.log(stack.getMax());
console.log(stack.getMin());
console.log(stack.dataStack);
console.log(stack.maxStack);
stack.pop();
console.log(stack.getMax());
console.log(stack.getMin());
console.log(stack.dataStack);
console.log(stack.maxStack);
相同点:都存储在客户端 不同点:1.存储大小
· cookie数据大小不能超过4k。
· sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
2.有效时间
· localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
· sessionStorage 数据在当前浏览器窗口关闭后自动删除。
· cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
· cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
· sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
相同点
· 都支持服务器端渲染
· 都有Virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent规范
· 数据驱动视图
· 都有支持native的方案,React的React native,Vue的weex
不同点
· React严格上只针对MVC的view层,Vue则是MVVM模式
· virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制
· 组件写法不一样, React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即'all in js'; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,js写在同一个文件但是会区分开标签;
· 数据绑定: vue实现了数据的双向绑定,react数据流动是单向的
· state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理
<!DOCTYPE html>
<html lang="en">
<head>
<title>双向绑定最最最初级demo</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<input type="text" id="txt">
<p id="show-txt"></p>
</div>
</body>
<script>
var obj={}
Object.defineProperty(obj,'txt',{
get:function(){
return obj
},
set:function(newValue){
document.getElementById('txt').value = newValue
document.getElementById('show-txt').innerHTML = newValue
}
})
document.addEventListener('keyup',function(e){
obj.txt = e.target.value
})
</script>
</html>
activated调用时机:
第一次进入缓存路由/组件,在mounted后面,beforeRouteEnter守卫传给 next 的回调函数之前调用:
beforeMount=> 如果你是从别的路由/组件进来(组件销毁destroyed/或离开缓存deactivated)=>
mounted=> activated 进入缓存组件 => 执行 beforeRouteEnter回调
因为组件被缓存了,再次进入缓存路由/组件时,不会触发这些钩子:
// beforeCreate created beforeMount mounted 都不会触发。
所以之后的调用时机是:
组件销毁destroyed/或离开缓存deactivated => activated 进入当前缓存组件
=> 执行 beforeRouteEnter回调
// 组件缓存或销毁,嵌套组件的销毁和缓存也在这里触发
(1)不缓存: 进入的时候可以用created和mounted钩子,离开的时候用beforeDestory和destroyed钩子,beforeDestory可以访问this,destroyed不可以访问this。
(2)缓存了组件: 缓存了组件之后,再次进入组件不会触发beforeCreate、created 、beforeMount、 mounted,如果你想每次进入组件都做一些事情的话,你可以放在activated进入缓存组件的钩子中。 同理:离开缓存组件的时候,beforeDestroy和destroyed并不会触发,可以使用deactivated离开缓存组件的钩子来代替
完整的触发顺序
触发钩子的完整顺序:
将路由导航、keep-alive、和组件生命周期钩子结合起来的,触发顺序,假设是从a组件离开,第一次进入b组件:
1. beforeRouteLeave:路由组件的组件离开路由前钩子,可取消路由离开。
2. beforeEach: 路由全局前置守卫,可用于登录验证、全局路由loading等。
3. beforeEnter: 路由独享守卫
4. beforeRouteEnter: 路由组件的组件进入路由前钩子。
5. beforeResolve:路由全局解析守卫
6. afterEach:路由全局后置钩子
7. beforeCreate:组件生命周期,不能访问this。
8. created:组件生命周期,可以访问this,不能访问dom。
9. beforeMount:组件生命周期
10. deactivated: 离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。
11. mounted:访问/操作dom。
12. activated:进入缓存组件,进入a的嵌套子组件(如果有的话)。
13. 执行beforeRouteEnter回调函数next。
data(){
return {
example0:"",
example1:"",
example2:{
inner0:1,
innner1:2
}
}
},
watch:{
example0(newVal,oldVal){//监控单个变量
……
},
example2(newVal,oldVal){//监控对象
……
},
}
watch一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数据
计算属性可用于快速计算视图(View)中显示的属性。这些计算将被缓存,并且只在需要时更新
什么时候需要使用vuex : 当项目业务复杂 页面之间很多关联数据需要交互的时候
本地存储和vuex的区别
当应用遇到多个组件共享状态时候,即:多个视图依赖于同一个状态,不同视图的行为需要变更同一状态。
vuex的官网也说了,对于页面之间的传参对于多层嵌套组件将会很繁琐,而且对于兄弟组件之间的状态传递无能为力。所以就将这些组件的共享状态抽取出来,以一个全局单例模式管理,即vuex
1.【响应式】vuex的状态存储是响应式的,当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会得到高效更新。
2.【不能直接改变store】不能直接改变store的变化,改变store中状态的唯一途径是commit mutation。方便于跟踪每一个状态的变化
vuex有哪几种属性 有五种,分别是 State、 Getter、Mutation 、Action、 Module
vuex的State特性是?
vuex的Getter特性是?
vuex的Mutation特性是?
Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
用一对反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,也可以在字符串中嵌入变量,js表达式或函数,变量、js表达式或函数需要写在${ }中
var str = `abc
def
gh`;
console.log(str);
let name = "小明";
function a() {
return "ming";
}
console.log(`我的名字叫做${name},年龄${17+2}岁,性别${'男'},游戏ID:${a()}`);
function A(a,b=1){
console.log(a+b);
}
A(1); //2
A(2+3); //5
箭头函数
//省略写法
var people = name => 'hello' + name;
var getFullName = (firstName, lastName) => {
var fullName = firstName + lastName;
return fullName;
}
var o = {
method() {
return "Hello!";
}
};
// 等同于
var o = {
method: function() {
return "Hello!";
}
};
var obj={name: "john", age: "21", getName: function () { alert(this.name)}};
console.log(Object.keys(obj)); // ["name", "age", "getName"]
console.log(Object.keys(obj).length); //3
console.log(Object.keys(["aa", "bb", "cc"])); //["0", "1", "2"]
console.log(Object.keys("abcdef")); //["0", "1", "2", "3", "4", "5"]
var target = {}; //目标对象
var source1 = {name : 'ming', age: '19'}; //源对象1
var source2 = {sex : '女'}; //源对象2
var source3 = {sex : '男'}; //源对象3,和source2中的对象有同名属性sex
Object.assign(target,source1,source2,source3);
console.log(target); //{name : 'ming', age: '19', sex: '男'}
//导入部分
//全部导入
import Person from './example'
//将整个模块所有导出内容当做单一对象,用as起别名
import * as example from "./example.js"
console.log(example.name)
console.log(example.getName())
//导入部分
import { name } from './example'
//导出部分
// 导出默认
export default App
// 部分导出
export class User extend Component {};
语法:
var promise = new Promise((resolve, reject) => {
var success = true;
if (success) {
resolve('成功');
} else {
reject('失败');
}
}).then(
(data) => { console.log(data)},
(data) => { console.log(data)}
)
执行过程:
setTimeout(function() {
console.log(0);
}, 0);
var promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(function () {
var success = true;
if (success) {
resolve('成功');
} else {
reject('失败');
}
},2000);
}).then(
(data) => { console.log(data)},
(data) => { console.log(data)}
);
console.log(promise); //<pending> 进行中
setTimeout(function () {
console.log(promise); //<resolved> 已完成
},2500);
console.log(2);
//1
//Promise {<pending>}
//2
//0
//成功
//Promise {<resolved>: undefined}
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
数组的解构赋值 数组中的值会自动被解析到对应接收该值的变量中,数组的解构赋值要一一对应 如果有对应不上的就是undefined
var [name, pwd, sex]=["小周", "123456", "男"];
console.log(name) //小周
console.log(pwd)//123456
console.log(sex)//男
对象的解构赋值 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值
var obj={name:"小周", pwd:"123456", sex:"男"}
var {name, pwd, sex}=obj;
console.log(name) //小周
console.log(pwd)//123456
console.log(sex)//男
//如果想要变量名和属性名不同,要写成这样
let { foo: foz, bar: baz } = { foo: "aaa", bar: "bbb" };
console.log(foz) // "aaa"
console.log(foo) // error: foo is not defined
var str="abcd";
console.log([...str]) // ["a", "b", "c", "d"]
var sets=new Set([1,2,3,4,5])
console.log([...sets]) // [1, 2, 3, 4, 5]
var a1=[1,2,3];
var a2=[4,5,6];
console.log([...a1,...a2]); //[1, 2, 3, 4, 5, 6]
rest参数 …变量名称
rest 参数是一个数组 ,它的后面不能再有参数,不然会报错
function func(...args){
console.log(args);//[1, 2, 3, 4]
}
func(1, 2, 3, 4);
function f(x, ...y) {
console.log(x);
console.log(y);
}
f('a', 'b', 'c'); //a 和 ["b","c"]
f('a') //a 和 []
f() //undefined