毕设那些事儿

封装Axios

https://juejin.im/post/59a22e71518825242c422604

滚动条在IOS不流畅

// 在设置overflow的那个node节点上添加:
    -webkit-overflow-scrolling: touch;

promise的用法

// 比如A、B都是异步。
// B要在A返回结果后再执行
A () {
    return new Promise((resolve, reject) => {
        this.$axios.get(`${prefix}/plan/getWeekCalendar`)
            .then((res) => {
                if (res.data.success) {
                    // A返回结果了
                    resolve()
                }
            })
            .catch((err) => {
                console.log(err)
            })
        })
    },

A()
.then(B) // 注意,这里B没有括号

vue阻止事件冒泡

@click.stop

axios和session问题

http://www.jb51.net/article/118555.htm

两个inline-block不对齐问题:

// 一般会出现img 配 div 时,
// 原因是:基线问题
vertical-align: top;

微信内置浏览器点击事件会闪烁

    -webkit-tap-highlight-color: transparent;

VUE里的data

// 子组件中(写法1):
template: '<div>{{ template }}</div>',
props: ['temp'],
data () {
    return {
        template: this.temp // 这里template得到的只是快照。所以这里的值,只会是父组件mounted()前的temp的值
    }
}

// 子组件中(写法2):
template: '<div>{{ template }}</div>',
props: ['template'], // 因为props一直是最新的。可以和data一样使用实现响应式,只不过是只读的

// 子组件中(写法3):
template: '<div>{{ template }}</div>',
props: ['temp'],
computed: {
    template () {
        return this.temp // 通过计算属性,源源不断的给他计算出最新的temp值
    }
}

// 子组件中(写法4):
template: '<div>{{ template }}</div>',
props: ['temp'],
data () {
    return {
        template: ''
    }
},
watch: { // 监听props的值,然后动态更新我们子组件里面的template
    temp () {
        this.template = this.temp
    }
},
created () {
    this.template = this.temp
}

VUE里的set

Vue.set( ) 用来设置对象的属性,如果对象是响应式的,那么为了确保对象的属性在被新创建后也是响应式的,同时保证会触发试图更新。
所以这个方法主要用于避开Vue不能检测属性被添加的限制
https://www.w3cplus.com/vue/vue-reactivity-and-pitfalls.html

坑:
<div v-for="item in items">
    <!--这里item的isSubscribed属性是拉取接口后,我手动新增的,因此不会被vue检测到-->
    <div :class="{ isSubscribed: item.isSubscribed }"></div>
</div>
// 解决方案1:
this.$set(this.items, 'isSubscribed', true)

// 解决方案2:
this.items = Object.assign({}, this.items)

VUE里的slot

slot 是插槽的意思
一般我们在父组件里引用子组件,不会塞任何东西的,如:

<div class="IamParent">
    <h1>我是父标题</h1>
    <Child></Child>
</div> 

有时候可以在<Child></Child> 里面塞东西,就要用到<slot>

// 在父组件中:
<div class="IamParent">
    <h1>我是父标题</h1>
    <Child>
        <p>这是给儿子的第一个礼物</p>
        <p>这是给儿子的第二个礼物</p>
    </Child>
</div>

// 在子组件中:
<div class="IamChild">
    <h2>我是子标题</h2>
    <slot>
        我没有收到父亲的礼物(这段文字只有在,父组件没有给子组件分发任何内容时才会显示)
    </slot>
</div>

// 最终渲染结果:
<div class="IamParent">
    <h1>我是父标题</h1>
    <div class="IamChild">
        <h2>我是子标题</h2>
        <p>这是给儿子的第一个礼物</p>
        <p>这是给儿子的第二个礼物</p>
    </div>
</div>

上面的是单个插槽,如果要特定插入到子组件的哪个插槽,那就要用到<slot>的 name 属性

// 在父组件中:
<div class="IamParent">
    <h1>我是父标题</h1>
    <Child>
        <p slot="first">这是给儿子的第一个礼物</p>
        <p slot="foot">这是给儿子的第二个礼物</p>
    </Child>
</div>

// 在子组件中:
<div class="IamChild">
    <h2>我是子标题</h2>
    <slot name="first">父组件没有给我第一个礼物</slot>
    <slot name="second">父组件没有给我第二个礼物</slot>
</div>

// 最终渲染:
<div class="IamParent">
    <h1>我是父标题</h1>
    <div class="IamChild">
        <h2>我是子标题</h2>
        <p slot="first">这是给儿子的第一个礼物</p>
        父组件没有给我第二个礼物
    </div>
</div>

VUE里的watcher

写法1:

watch: {
    'fetchAgain': 'shouldFetch' // shouldFetch是函数名
}

写法2:

watch: {
    fetchAgain: function (newVal, oldVal) { // 一个参数,则为newVal
        this.shouldFetch() // 这里不能用箭头函数,否则this不是这个vue实例!而是全局,此时this包括整个生命周期/data等等,不单单是methods
    }
}

position: sticky

  • 因为fixed是相对于浏览器窗口的,那如果希望相对于父容器,怎么做?
1/给子元素设定position: sticky;
2/同时也设定toprightbottomleft四值其中之一,这个叫阈(yu)值。(比如设定top: 20px)
【注意】
   这些值是相对于“最近的块级父元素的顶部“(有时候是相对于浏览器窗口顶部?);

3/随着滚动,子元素会慢慢上升。(此时是相对定位position: relative)
【注意】
   若top的值 < 子元素height,子元素才会慢慢上升;否则会保持不动!(刚好可以利用这一个特性,来达到将fixed的参照物设定为最近的块级父元素顶部)


4/当上升到 子元素和“最近的块级父元素“顶部的距离 < 20px时,不再上升(此时是固定定位position: fixed)

position: fixed失效

要使用position: fixed的子元素突然失效了?
- 原因:父元素带有transform: translate(…)

vscode常用插件

这里写图片描述

然后在setting.json(首选项 -- 设置),添加如下:
    "workbench.colorTheme": "One Dark Pro",
    "workbench.iconTheme": "material-icon-theme",
    "material-icon-theme.folders.theme": "classic",
    "material-icon-theme.folders.color": "#42a5f5"

for…of 和for…in 和v-for=” …of/in”

v-for=”…of/in”都是一样的,只是…of的写法更贴近于js的of迭代器

var arr = [1, 9, 9, 6]

var obj = {
    name: 'heshiyu',
    age: 21
}

var items = [{
    name: 'heshiyu',
    age: 21
}, {
    name: 'caozuoxiao',
    age: 22
}]
Tables for…of for…in
arr 1 9 9 6 0 1 2 3
obj 报错! name age
items {name: ‘heshiyu’, age: 21} {name: ‘caozuoxiao’, age: 21} 0 1
Tables v-for…of
arr 1 9 9 6
obj heshiyu 21
items {name: ‘heshiyu’, age: 21} {name: ‘caozuoxiao’, age: 21}

数组的includes( )

[1, 9, 9, 6].includes(9) // true

数组的find( )

[1, 9, -9, 6].find((n) => {
    return n < 0
}) // -9
// 数组中的每个成员都一次执行这个方法,直到 第一个 返回true的就结束
// 类似的方法findIndex( )是一样的,只是返回第一个返回true的下标

Array.of()

可以将给的参数变成一个数组

rest参数 和 扩展运算符…

rest参数用于获取函数的多余参数

  • 是将一个个参数转成一个真正的数组
  • 是放在函数的参数部分的
  • 和arguments的区别在于:arguments是一个类似数组的对象,而rest参数是真正的一个数组,它里面装着多余的参数
    function add (arr, ...rest) {
        rest.forEach((item) => {
            arr.push(item)
        })
    } 

扩展运算符…

  • 和rest参数是逆过来的,是将一个数组转成一个个参数
// 用例0:深复制数组
var arr1 = [1, 2]
var arr2 = [...arr1]

// 用例1:
function add (x, y) {
    // 这里只需要2个参数
    return (x + y)
}
var nums = [1, 9]
add(...nums)

// 用例2:将一个数组直接添加到另一个数组的尾部
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

短路赋值

function log (x, y) {
    y = y || 'World';
    console.log(x, y);
}
log('Hello');// "Hello World"
log('Hello', false);// "Hello World"
log('Hello', '');// "Hello World"
短路赋值因为false或者'',而忽视了我们设定的y的默认值

ES5解决方法:
if (typeof y === 'undefined') {
    y = 'World'
}

ES6解决方法:
function log (x, y = 'World') {
}
// 若参数里 y = 表达式求值,那每次都会重新计算一次!

Math中常用:

1/去除小数:
Math.trunc(1.23) // 1

2/进一
Math.ceil(0.35) // 1

3/判断正负零:
Math.sigh(1.23) 
// 正:+1
// 负:-1
// 0:0
// -0:-0
// 其他值:NaN

RegExp

实例化正则对象:

var regex = new RegExp(/a/, ‘i’)

flags:
i 不区分大小写
g 全局匹配

正则对象的方法(使用圆括号进行组匹配)

var regex = new RegExp(/(\d{4})-(\d{2})-(\d{2})/, ‘ig’)
var str = ‘my name is Heshiyu’

exec(str)

regex.exec(str) // 返回一个数组arr
// arr[0] :str本身
// arr[1] :第一个组匹配
// arr[2] :第二个组匹配
// arr[3] :第三个组匹配

字符串对象 & 正则表达式

var str = ‘my name is Heshiyu’

match(pattern) 找很多人

str.match(regex) // 返回第一个(若flags有g,则匹配到所有)匹配到的字(没有下标),否则返回null

search(pattern) 找到一个就行

str.search(regex) // 返回一个(onlyOne)匹配到的下标,否则返回-1

replace(pattern) 替换

str.replace(regex) // 返回一个字符串,它是第一个(若flags有g,则匹配到所有)匹配到的字符被替换后,所形成的

模版字符串

用法:
let name = 'heshiyu'
`Hello! My name is ${name}`

注意:
 - 反印号里的所有 空格 和 换行 都会被保留,要去除,就用trim()
 - ${函数也行}

新增的3个检验字符串的方法:

ES5:

indexOf

var str = "Hello world!"
str.indexOf('world'); // 返回第一个字符匹配的所在位置

ES6:(都是返回true/false)

includes(数组也有这个方法)

var str = "Hello world!"
str.includes('world'); // 是否包含。。。字符串

startsWith

var str = "Hello world!"
str.startsWith('world'); // 是否以。。。开头

endsWith

var str = "Hello world!"
str.endsWith('world'); // 是否以。。。结尾

解构赋值的用途

1/交换变量的值(不引入第三个变量)

var x0 = 0, x1 = 1;
[x0, x1] = [x1, x0];

2/提取json值

var myJson = {
    name: 'heshiyu',
    age: 21
}
let {name, age} = myJson;
name // 'heshiyu'
age // 21

3/导入模块的指定方法
const { func1, func2 } = require(“source-map”);

(对象的)解构赋值中的默认值

var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

(对象的)解构赋值

// 这是“右对象的属性名“ 与 “左对象的变量名“同名时
let {foo, bar} = {foo: 'fo', bar: 'ba'};

// 这是“右对象的属性名“ 与 “左对象的变量名“不同名时
let {foo: hsy, bar} = {foo: 'fo', bar: 'ba'};

// 真正被赋值的是后者(hsy),而不是前者(foo)。

(数组的)解构赋值中的默认值

let [x = 1] = [];
x // 1

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null

// 只有当数组里的元素严格等于undefined(===),x的默认值才会生效

(数组的)解构赋值

解构不成功(如下面的middle),将会变成undefined
...tail 如果没有东西,会变成[]
// 代码
var [head, middle, ...tail] = [1]
head;// 1
middle;// undefined
tail;// [] 

在es5中,window顶层对象的属性 = 全局变量

var name = 'heshiyu';
window.name; // 'heshiyu'

将一个对象冻结:Object.freeze({…})

这样以后,这个对象就不能再添加新的属性了;
也不能更改属性的值

const保证的不是值不变,而是地址不变;

这个地址不变,如果是一个对象/数组,那对象/数组里装的东西可以变呀

暂时性死区

var tmp = 123;
if (true) {
    console.log(tmp); // ReferenceError
    let tmp = 3;
}
// 因为这里tmp在代码块里,用了let声明,所以不会有变量提升;
// 而且变量tmp会绑定这个块级作用域,从一开始就形成封闭作用域(暂时性死区),听不到外面的tmp变量
// 也不可以重复声明

打印全局i

var a = [];
for (var i=0; i<10; i++) {
    a[i] = function () {
        console.log(i);
    }   
}
a[1]();// 10
// a[i]只记住了要打印,但是到最后这个i是全局变量,导致是i=10

配Snippets

首选项 -- 用户代码片段 -- 可以选javascript.json或者css.json
注意!如果是用了sass,那就是scss.json

VS Code的setting.json

快捷键 command ,

获取url后缀(文件格式)

    downloadRename (url) {
        var postfix = /\.[^\.]+$/.exec(url)
        return postfix;
    },

改了host后,vue-cli出现 invalid host header

在webpack.dev.conf.js中的devServer字段,增加:
    disableHostCheck: true

判断用户是否手机,重定向

   if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){
       window.location.href = 'http://wap-sight.netease.com';
   }

引入vux提示:压缩体积过大,请升级到vux-loader最新版本

解决办法:将vue-loader降至12.2.2

将axios加入到Vue实例的原型链中

① 在main.js中导入axios

import axios from ‘axios’
② 加入到Vue的原型中
Vue.prototype. a x i o s = a x i o s t h i s . axios即可(也可以取其他名字)

//get用法:
this.$axios.get(url)
.then(function(res){
})
.catch(function(error){
})
//post用法:
var querystring = require('querystring');//Json数据查询器
this.$axios.post(url, querystring({是一个json参数对象}))
.then(function(res){
})
.catch(function(error){
})

自己写个hover菜单显示子菜单

最终功能图:
这里写图片描述

① 在某一个li下面,再加多一层div
这里写图片描述

② 这层div的css样式(划线两个为主要):
这里写图片描述

③ 给他的父li增加这个hover样式,即可
这里写图片描述

在vue-cli项目中引入node-sass

① 先装一个淘宝镜像:
npm install -g cnpm --registry=https://registry.npm.taobao.org

② 通过淘宝镜像去安装node-sass
cnpm i sass-loader node-sass --save-dev

③ 在webpack.base.conf.js加入这个rule
      {
        test: /\.scss$/,
        loaders: ["style", "css", "sass"]
      },

④ 在.vue里的style这样写,即可
<style lang="scss" type="text/css" scoped>

vue-cli在ios调试失败

原因:Can’t find variable: SockJS
因为webpack(3.6.0)的热加载需要websocket来通知浏览器,而SockJS是一个必须的库。对于google它有很多种方式解决,而safari却没有。
解决办法:在webpack.config.js中devtool将“eval-source-map“改为“inline-source-map“即可

webpack

  • webpack的热加载是通过websocket通知浏览器来实现的

path.resolve

//webpack.config.js
const path = require('path')

path: path.resolve(__dirname, 'dist')
//这样,后半部分就拼接成了一个字符串:'项目路径/dist'
//相当于: 
//cd __dirname
//cd dist
// pwd

猜你喜欢

转载自blog.csdn.net/ak47bo88/article/details/78624808