<![CDATA[element ui问题总结]]>http://www.wingblog.top/archives/505/element ui 多层dialog被遮罩住,不能进行操作

在第二个dialog上加append-to-body属性

<el-dialog :title="sCompanyEditTitle" :visible.sync="sCompanyFormVisible" :close-on-click-modal="false" :before-close="sCompanyFormHandleClose" append-to-body>
]]>
JavaScript
<![CDATA[JS 时间总结]]>http://www.wingblog.top/archives/502/IOS不支持 new Date('2018-07-06 15:32:24') 只支持 new Date('2018-07-06')]]>JavaScript<![CDATA[web开发字体大小以及样式总结]]>http://www.wingblog.top/archives/499/

在web或者移动端,小程序开发过程中,许多字体,字号,字体样式,和颜色都是定义好的

在写一个系统之前,应该先把用的字体样式写一个统一的样式,其他的都继承这些字体样式就好了

]]>
JavaScript
<![CDATA[Mpvue采坑之路]]>http://www.wingblog.top/archives/487/在不同页面使用时通过组件method改变组件data失效
  • 源代码
data() {
        _this = this
        return {
            show: false
        }
    },
    methods: {
        select(item) {
            if (_this.show) {//展开状态

                _this.list = _.concat([], _.sortBy(_this.list, tItem => tItem.val != item.val))
                _this.show = false
            } else {
                _this.show = true
            }
        },
        close() {
            _this.show = false
        }
    }

原因是mpvue编译的时候data里赋值的_this和methods中不是同一个上下文。

  • 新代码
data() {
        _this = this
        return {
            show: false
        }
    },
    methods: {
        select(item) {
            if (this.show) {//展开状态

                this.list = _.concat([], _.sortBy(this.list, tItem => tItem.val != item.val))
                this.show = false
            } else {
                this.show = true
            }
        },
        close() {
            this.show = false
        }
    }

配置page.json

  • 页面的main.js
import Vue from 'vue'
import App from './index'

const app = new Vue(App)
app.$mount()
export default {
    // 这个字段走 page.json
    config: {
        enablePullDownRefresh: true,
        backgroundTextStyle: 'dark'
    }
}

配置页面的事件(如下拉刷新等)

mounted() {
        _this.getLocation().then(() => {
        })
        _this.getShops()
    },
    async onReachBottom() {

    },
    async onPullDownRefresh() {
        // to doing..
        // 停止下拉刷新
        wx.stopPullDownRefresh();

    },
    async onPageScroll(e) {
        //    _this.headerActive = false
    }

获取用户信息权限的事件回调

<button class="btn" open-type="getUserInfo" @getuserinfo="getUserAuthCallback">
                <img class="btn-icon" :src="imgs[1]" alt="">
            </button>
methods: {
        getUserAuthCallback(e) {
            wx.showLoading({ title: '登录中...', mask: true })
            if (e.mp.detail.errMsg == 'getUserInfo:ok') {//授权成功
                _this.getUserAuth()
            } else {
                wx.hideLoading()
                wx.showToast({ title: '授权失败,请重新授权', icon: 'none' })
            }
        }

    }

微信小程序原生组件的事件

<swiper duration="100" class="inter-body" @animationfinish="changeSwiper"></swiper>


methods: {
        changeSwiper(e) {
            _this.activeBody = e.mp.detail.current
        },
}

微信异步请求封装

/*
    Author:宋乐
    Time:2018-07-13

    fetch 用法

    fetch进行请求有两种格式,一种是参数形式,一种是对象形式

    1.fetch(url,【data,token,method,header】)       【】代表可选项
        (1) fetch(url)   Get请求
        (2) fetch(url,{id:12},true)   Post请求且需要login_token
    2.fetch({
        url:url,
        【
            data:data(Json格式),
            token:true|false(是否需要login_token,默认true),
            method:'GET'|'POST'(请求方式,默认post)
            header:request header
        】
    })
        (1)fetch({
            url:url,
            token:false,
            method:'GET'
        })   Get请求且不需要login_token
*/

let CryptoJS = require('crypto-js')
let md5 = require('js-md5')

// 加密
var encryption = function(word, key3) {
    var key = CryptoJS.enc.Utf8.parse(key3)
    var srcs = CryptoJS.enc.Utf8.parse(word)
    var encrypted = CryptoJS.AES.encrypt(srcs, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    })
    return encrypted.toString()
}

// 解密
var decryption = function(word, key3) {
    var key = CryptoJS.enc.Utf8.parse(key3)
    var decrypt = CryptoJS.AES.decrypt(word, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    })
    return CryptoJS.enc.Utf8.stringify(decrypt).toString()
}

// 处理data数据
var paramsData = function(data, key1, key2) {
    var paramsStr = key1
    for (var p in data) {
        paramsStr += data[p]
    }
    paramsStr += key2
    console.log('Prams Plus Key2:', paramsStr)
    data['key'] = md5(paramsStr)
    return data
}

export default function fetch(obj) {
    let tmpObj = null
    if (arguments.length > 1) {
        tmpObj = {
            url: arguments['0'],
            data: arguments['1'],
            token: arguments['2'],
            method: arguments['3'] || null,
            header: arguments['4'] || null
        }
        if (tmpObj.token == null) tmpObj.token = true
    } else {
        if (obj instanceof Object) {
            tmpObj = obj
            if (tmpObj.token == null) tmpObj.token = true
        } else {
            tmpObj = {
                url: arguments[0],
                method: 'GET'
            }
        }
    }

    //做排序
    let sortKeys = _.sortBy(_.keys(tmpObj.data), item => !item)
    let sortObj = {}
    _.forEach(sortKeys, key => {
        sortObj[key] = tmpObj.data[key]
    })
    tmpObj.data = sortObj
    //排序完成
    console.log('Request Param Object:', tmpObj.data)
    let MA11111 = ''
    let MA22222 = ''
    let MA33333 = ''
    let userObj = null
    if (tmpObj.token) {
        userObj = wx.getStorageSync('userInfo')
        MA11111 = userObj.key1
        MA22222 = userObj.key2
        MA33333 = userObj.key3
    } else {
        MA11111 = 'iqpqdVLawksP0wW2Wfdsfdsfdstjh9l1awePMHGmAog'
        MA22222 = 'w2w22DFHYUojWJuxQMfdsfdsf30VPduy4ewV2Tjg8'
        MA33333 = 'vowGIuiUdsfdssjhddjeq'
    }

    let withKeyParams = paramsData(tmpObj.data || {}, MA11111, MA22222)
    var paramsJson = JSON.stringify(withKeyParams)
    var reqData = {
        data: encryption(paramsJson, MA33333)
    }
    if (tmpObj.token) {
        reqData['login_token'] = userObj.login_token
    }
    console.log('Request Encrypt Param Object:', reqData)
    let params = {
        url: 'https://www.maiyia.cn/appserver_test/public/' + tmpObj.url,
        data: reqData,
        method: tmpObj.method || 'POST',
        header: {
            'content-type': 'application/json',
            Accept: 'application/json',
            //'Authorization': 'Bearer ' + token,
            ...tmpObj.header
        }
    }

    return new Promise((res, rej) => {
        wx.request(
            Object.assign(params, {
                success(resp) {
                    let result = null
                    try {
                        result = JSON.parse(decryption(resp.data.data, MA222222))
                        console.log('Request Return Object:', result)
                    } catch (error) {
                        rej(result)
                    }
                    if (resp.data.statusCode !== 1) {
                        console.log(resp.data.message)
                        console.log('Request Error Object:', resp.data)
                        rej(result)
                    } else {
                        res(result)
                    }
                },
                fail(e) {
                    rej(e)
                }
            })
        )
    })
}

mpvue开发删除node_modules,重新安装报错

  • 错误:未找到 app.json
    删除package.json文件中"mpvue-loader": "^1.0.13",里面的‘^’,再重新npm install、npm run dev即可正常。原因:如果不锁定版本安装,默认会安装最新的版本,造成新版本不兼容而编译不成功。

mpvue组件式开发,组件的状态在组件内部维护的时候,当小程序从A--B--A--B的时候,组件自己的状态不会改变,而网页可以。

  • 首页来到搜索页,切换为附近以后,返回首页,再进搜索,搜索状态不会刷新为热门
    因为网页是会重新加载,重新创建组件实例,而小程序不会重新创建,所以组件状态没有刷新

小程序组件scroll-view 不能高度超过屏幕的范围,否则下拉的时候不会有空白的回弹

position为fixed时候,v-show不起作用,需要用v-if才起作用

深度数组改变值时候视图需要变化的时候

小程序(mpvue开发)弹窗组件式滑动穿透

之前参照网上还是能滑动,是因为在组件内部使用了position:fixed,如果组件内部使用absolute,将fixed提出到vue page页面,就能够禁止滑动了

  • 当弹窗内scroll-view内容不足以滑动的时候,还是会穿透,解决办法是在scroll-view内套一个div,让这个div最小高度超过scroll-view的高度
  • 弹窗组件
<template>
    <div class="body">
        <div class="panel" :class="{'show':isShow}">
            <div class="close">
                <img :src="imgs[0]" alt="" class="close-icon">
            </div>
            <scroll-view scroll-y="true" class="scroll-body">
            </scroll-view>
        </div>

    </div>
</template>

<script>
import config from '../utils/config'
let _this = null

export default {
    props: [],
    data() {
        _this = this
        return {
            isShow: false,
            imgs: [
                config.imgServer + 'ic_ly_guanbi@2x.png'
            ]
        }
    },
    mounted() {
        this.isShow = true
    },
    methods: {

    }
}
</script>

<style lang="scss" scoped>
@import '../../static/css/base.scss';
.scroll-body {
    height: 74vh;
    margin-top: 6px;
}
.body {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5) fixed;
    z-index: 999;
    height: 100vh;
    width: 100vw;
    overflow: hidden;
    .panel {
        position: absolute;
        height: 80vh;
        width: 100%;
        bottom: -80vh;
        transition: bottom 0.6s;
        background: rgba(255, 255, 255, 0.96);
        &.show {
            bottom: 0;
        }
        .close{
            .close-icon{
                
            }
        }
    }

}
</style>
  • vue页面应用
<div class="stop-modal-scroll" @touchmove.stop="">
    <div class="wapper">
        <comments-panel></comments-panel>
    </div>
</div>


.stop-modal-scroll {
    height: 100vh;
    width: 100vw;
    position: fixed;
    overflow: hidden;
    background: rgba(204, 204, 204, 0.9);
    bottom: 0;
    left: 0;
    z-index: 999;
    .wapper {
        position: relative;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }
}

使用 scroll-view 的时候调用页面的 下拉刷新

<scroll-view scroll-y="true" class="inter-body recommend"  @scroll="scrollBody">
</scroll-view>
data() {
    _this = this
    return {
        timer: null,
        topScrollFirstTime: 0,
        topScrollEndTime: 0,
    }
},
methods:{
    scrollBody(e) {
        if (e.mp.detail.scrollTop < -15) {
            if (this.topScrollFirstTime == 0 && this.topScrollEndTime == 0) {
                let time = new Date().getTime()
                this.topScrollFirstTime = time
                this.topScrollEndTime = time
                this.timer = setInterval(() => {
                    this.topScrollEndTime = new Date().getTime()
                    if (this.topScrollEndTime - this.topScrollFirstTime >= 450) {
                        clearInterval(this.timer)
                        this.timer = null
                        this.topScrollFirstTime = 0
                        this.topScrollEndTime = 0
                        wx.startPullDownRefresh({
                            success: function () {
                                _this.regetCurrentPageData().then(() => {
                                    wx.stopPullDownRefresh()
                                })
                            }
                        })
                    }
                }, 100)
            }

        } else {
            clearInterval(this.timer)
            this.timer = null
            this.topScrollFirstTime = 0
            this.topScrollEndTime = 0
        }
    },
}
]]>
JavaScript
<![CDATA[免费 Https 认证及部署过程]]>http://www.wingblog.top/archives/483/1.生成 csr

首先去 csr 在线生成网站生成自己的csr

  • 注意:填写所有的信息是不能包含中文和特殊字符
    下载下来会有2个文件,csr和key文件

2.申请免费证书

免费证书申请网站

在阿里云域名设置里添加记录

然后在freessl网站进行验证,然后下载

full_chain.pem是freessl签发的证书,key.key是第一步csr生成网站下载下来的。
将这两个文件上传到服务器

3.服务器设置ssl

(1) 宝塔linux站点设置ssl

(2) node express设置ssl

]]>
JavaScript
<![CDATA[宝塔Linux使用日常]]>http://www.wingblog.top/archives/474/redis 软件配置文件修改密码以后无法在宝塔linux面板操作

ssh root用户连接服务器以后,执行

pkill -9 redis

然后在宝塔linux面板进行重启就好了

]]>
JavaScript
<![CDATA[网页实现某些效果的技巧]]>http://www.wingblog.top/archives/466/input边输入边ajax

oninput时请求数据,但是因为异步,可能前一个的数据把后边才请求到的数据覆盖掉,所以需要设置一个定时器

searchText: function (newVal) {
            let _this = this
            this.list = []
            if (newVal == '') {
                this.searchList = []
                this.show.searchResult = false
            }
            let time = 500
            function getData() {
                _this.timeSearch.time == new Date().getTime()
                _this.timeSearch.obj = setTimeout(() => {
                    Promise.all(_this.searchPromises).then(() => {
                        let promise = _this.search(_this.searchText)
                        //_this.showLoading(promise)
                        _this.searchPromises.push(promise)
                    })
                }, time);

            }
            if (this.timeSearch.time == 0) {
                getData()
            } else if (new Date().getTime() - this.timeSearch.time < time) {
                clearTimeout(this.timeSearch.obj)
                this.timeSearch.obj = null
            } else {
                getData()
            }



        }

vue写modal时候需要在组件内部和外部都能修改值

<template>
  <div class="modal" :value="value" v-show="visible">
      <div class="close" @click="cancel">X</div>
  </div>
</template>

<script>
export default {
    props: {
      value: {
        type: Boolean,
        default:false
      }
    },

  data () {
    return {
      visible:false
    }
  },
  watch:{
      value(val) {
        console.log(val);
        this.visible = val;
      },
      visible(val) {
        this.$emit('input', val);
      }
  },
  methods:{
    cancel(){
      this.visible = false;
    }
  },
  mounted() {
    if (this.value) {
      this.visible = true;
    }
  }
}
</script>


///调用modal组件

  <modal v-model="isShow"></modal>

export default {
  name: 'app',
  data () {
    return {
      isShow:false
    }
  }
}
</script>
]]>
JavaScript
<![CDATA[Canvas]]>http://www.wingblog.top/archives/460/画一个半圆

深度截图_选择区域_20180511104722.png

function drawScreen(myCanvas, r, lw, lr, rr, g) {
    // x,y => 圆心坐标点
    // r => 圆弧半径
    var arc = {
        x: myCanvas.width / 2,
        y: myCanvas.height / 2 + 16,
        r: (myCanvas.height - r) / 2
    }
    var ctx = myCanvas.getContext('2d')
    ctx.save()
    ctx.lineWidth = lw

    if (g) {
        //计算渐变起始坐标
        let L = Math.sqrt(Math.pow(arc.r, 2) / 2)
        let gx0 = arc.x - L
        let gy0 = arc.y + L
        /* 指定渐变区域 */
        var grad = ctx.createLinearGradient(
            arc.x - L,
            arc.y + L,
            arc.x - L,
            arc.y
        )
        grad.addColorStop(1, '#FEE891')
        grad.addColorStop(0, '#FEB832')
        ctx.strokeStyle = grad
    } else {
        ctx.strokeStyle = '#F2F3F8'
    }

    // 顺时针旋转
    ctx.beginPath()
    ctx.arc(arc.x, arc.y, arc.r, getRads(lr), getRads(rr))
    ctx.stroke()
}
function getRads(degrees) {
    return Math.PI * degrees / 180
}
function getDegrees(rads) {
    return rads * 180 / Math.PI
}
export default {
    mounted: () => {
        //获取根元素字体大小计算rem
        let fontSize = document.documentElement.style.fontSize
        CONST.fontSize = parseInt(fontSize.substring(0, fontSize.length - 2))
        CONST.width = document.body.clientWidth
        CONST.widthRem = CONST.width / CONST.fontSize
        drawScreen(document.getElementById('circle'), 0, 6, 135, 45) //绘制外层灰色
        drawScreen(document.getElementById('circle'), 36, 1.5, 132, 48) //绘制内层灰色
        drawScreen(document.getElementById('circle'), 0, 6, 135, 200, true) //绘制渐变
    }
}
]]>
JavaScript
<![CDATA[CSS动画[png]]]>http://www.wingblog.top/archives/455//* 全局loading组件 Author: 宋乐 */ <template> <div class="g-loading"> <div class="contain"> <div class="loading"> <ul> <li><img src="../../../static/images/gLoadImg/0.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/1.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/2.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/3.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/4.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/5.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/6.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/7.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/8.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/9.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/10.png" alt=""></li> <li><img src="../../../static/images/gLoadImg/11.png" alt=""></li> </ul> </div> <div class="load-text">加载中...</div> </div> </div> </template> <script> export default {} </script> <style lang='scss' scoped> $length: 11rem; $bottom: 24%; @keyframes Myflash { from { left: 0; } to { left: -11*$length; } } .g-loading { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 999999; .contain { position: relative; height: 100%; width: 100%; .loading { left: calc((100% - #{$length})/2); position: absolute; bottom: $bottom; width: $length; height: $length; overflow: hidden; ul { animation: Myflash 1s steps(11) 0s infinite; position: relative; width: 11*$length; height: $length; li { height: $length; width: $length; float: left; } img { width: $length; height: 100%; } } } .load-text { font-size: $length * 0.06; color: #615f5f; text-align: center; width: 100%; position: absolute; bottom: $bottom * 1.14; padding-left: $length * 0.03; z-index: 2; } } } </style> ]]>JavaScript<![CDATA[Vue项目常用配置]]>http://www.wingblog.top/archives/453/全局 filter

custom.js

// 2018-11-02 15:12:43  --> 15:12
let subTimeToHour = time => {
    return time.substring(11, 16)
}
export { subTimeToHour }

main.js

import * as customFilters from './filters/custom'
//引入全局filter
Object.keys(customFilters).forEach(key => {
    Vue.filter(key, customFilters[key])
})
  • 需要 webpack 重新编译

引入Swiper

import '../node_modules/swiper/dist/css/swiper.min.css'
import oswiper from '../node_modules/swiper/dist/js/swiper.min.js'
window.Swiper = oswiper

vue在js使用filter

this.$options.filters.[filter名字]

vue 单页应用微信分享在Andriod只有某页设置生效的问题解决

function setWxConfig(rs) {
    setTimeout(() => {
        wx.config({
            debug: false,
            appId: rs.appId, //公众号名称,由商户传入
            timestamp: rs.timestamp, //时间戳,自1970年以来的秒数
            nonceStr: rs.nonceStr, //随机串
            signature: rs.signature, //微信签名方式:
            jsApiList: [
                'openEnterpriseChat',
                'openEnterpriseContact',
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'onMenuShareQQ',
                'onMenuShareWeibo',
                'onMenuShareQZone',
                'startRecord',
                'stopRecord',
                'onVoiceRecordEnd',
                'playVoice',
                'pauseVoice',
                'stopVoice',
                'onVoicePlayEnd',
                'uploadVoice',
                'downloadVoice',
                'chooseImage',
                'previewImage',
                'uploadImage',
                'downloadImage',
                'translateVoice',
                'getNetworkType',
                'openLocation',
                'getLocation',
                'hideOptionMenu',
                'showOptionMenu',
                'hideMenuItems',
                'showMenuItems',
                'hideAllNonBaseMenuItem',
                'showAllNonBaseMenuItem',
                'closeWindow',
                'scanQRCode'
            ]
        })
    }, 500)
}

function wxJsConfig(to) {
    let data = {
        url: window.location.href.split('#')[0]
    }

    console.log('WxJsSignature data:', data)
    httpSrv.sendPost(
        null,
        'wx/wx/getWxJsSignature',
        data,
        function(rs) {
            console.log(rs)
            setWxConfig(rs)
        },
        function() {},
        false
    )
}

//vue-router全局守卫
router.afterEach((to, from) => {
    wxJsConfig(to)
    wx.ready(function() {
        wx.hideAllNonBaseMenuItem()
    })
    if (from.meta.keepAlive) {
        from.meta.scroll = $(window).scrollTop()
    }
})
]]>
JavaScript
<![CDATA[前端常见坑合集]]>http://www.wingblog.top/archives/451/img onload事件 被浏览器缓存后不执行 onload 方法

https://www.cnblogs.com/alanaZ/p/4648581.html

vue keepalive mint ui 无线加载方案bug

Mint UI 的无线滚动指令是通过监听浏览器是否滚动到浏览器底部某个位置来实现的,但是是给全局都加上了。如果一个组件进行复用的时候,当滑动到底部,这几个复用的组件都会执行loadMore方法。
解决方案是自己通过JQ来监听是否到达底部,然后在复用的组件里通过keepalive的回调动态给window的添加scroll的监听器

activated() {
        window.addEventListener('scroll', this.initLoadMore)
    },
deactivated() {
        window.removeEventListener('scroll', this.initLoadMore)
    },
initLoadMore() {
    let _this = this
    if ($(document).scrollTop() >= $(document).height() - $(window).height()) {
        _this.loadMore()
    }
},
]]>
JavaScript
<![CDATA[JS写全端软件(Android,IOS,Mac, Linux, Win)]]>http://www.wingblog.top/archives/449/

手机端全端适配

Hbuilder 将 Web app 打包为 Andriod 和 IOS 的安装包

桌面程序全端适配

nw.js 和 electron.js 打包为 Mac, Linux, Win 的安装包

  • nw.js不适合底层打印以及和其他语言混合使用
  • electron.js 配合其他语言使用俱佳
]]>
JavaScript
<![CDATA[Deepin Linux System Software Bundle]]>http://www.wingblog.top/archives/448/

backup deepin linux system software name

快速启动

  • Synapse

取色

  • pick

取色

  • pick

终端

  • cool retro term
  • tilda

markdown编辑器

  • 小书匠
]]>
JavaScript
<![CDATA[全端适配]]>http://www.wingblog.top/archives/446/rem

]]>
JavaScript
<![CDATA[prettier]]>http://www.wingblog.top/archives/444/https://juejin.im/post/5a791d566fb9a0634853400e

]]>
JavaScript
<![CDATA[Mac Mybatis 自动生成工具失效]]>http://www.wingblog.top/archives/442/

失效原因:路径问题

  • .\src 改为 ./src 就可以正常生成了
]]>
JavaScript
<![CDATA[UI篇]]>http://www.wingblog.top/archives/430/能给你温暖,就是最好的告白
字体合集
手机夜篇
生活
圆形头像
人物

]]>
JavaScript
<![CDATA[此内容被密码保护]]>http://www.wingblog.top/archives/423/

请输入密码访问

]]>
JavaScript
<![CDATA[Vue项目问题汇总]]>http://www.wingblog.top/archives/416/### webpack打包图片路径问题

  • css引用使用相对路径
  • webpack output: publicPath './'

### vue-router 传参

//router.js
必须设置路由 name

### 在watch或者其他方法里给data赋值不起作用

原因是使用ES6的语法,导致 this 获取的不是组件的

//错误的写法
watch:{
    list(){
       this.jurge=false
   },
   isShow:()=>{
       this.jurge=false
   }
},
data(){
    return {
        jurge:true
   }
}
 //正确的写法
 watch:{
   list:function{
      this.jurge=false
  }
 },
 data(){
   return {
       jurge:true
  }
 }

v-for render完成判断

<ul id="demo">
    <li v-for="item in list">{{item}}</div>
</ul>
new Vue({
    el:'#demo',
    data:{
        list=[0,1,2,3,4,5,6,7,8,9,10]
    },
    methods:{
        push:function(){
            this.list.push(11);
            this.nextTick(function(){
                alert('数据已经更新')
            });
            this.$nextTick(function(){
                alert('v-for渲染已经完成')
            })
        }
    }
})

Vue 引入Swiper时样式为scoped时改变page-ball样式


]]>
JavaScript
<![CDATA[Linux常见Error]]>http://www.wingblog.top/archives/415/ssh

REMOTE HOST IDENTIFICATION HAS CHANGED

ssh-keygen -R root@Ip // 重新ssh连接
  • 或者删除 .ssh/know_hosts 里 ip 相关的 key
]]>
JavaScript
<![CDATA[angle-between-points]]>http://www.wingblog.top/archives/407/where point quadrant
angle-between-points

顺时逆时
判断两点所在象限

]]>
JavaScript
<![CDATA[房东的喵--云烟成雨吉他谱]]>http://www.wingblog.top/archives/399/

你的晚安,是下意识的恻隐

1-1G105100452.jpg

]]>
音乐
<![CDATA[Eslint]]>http://www.wingblog.top/archives/397/

参考
中文规则

.eslintrc.js

module.exports = {
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "sourceType": "module"
    },
    "rules": {
        "indent": [
            "error",
            "tab"
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "never"
        ]
    }
};
]]>
JavaScript
<![CDATA[EditorConfig]]>http://www.wingblog.top/archives/396/

参考地址

.editorconfig

# 表明是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件
root = true
[*]
# 换行符的类型。lf, cr, crlf三种
end_of_line = lf

# indent_style 缩进使用tab或者space
indent_style = tab
# 缩进为tab时,缩进的宽度
tab_width = 4

# 是否使文件以一个空白行结尾
insert_final_newline = true

# 文件的charset。有以下几种类型:latin1, utf-8, utf-8-bom, utf-16be, utf-16le
charset = utf-8
# 是否将行尾空格自动删除
trim_trailing_whitespace = true

# md行尾空格自动删除false
[*.md]
trim_trailing_whitespace = false
[*.json]
indent_style = tab
tab_width = 4
]]>
JavaScript
<![CDATA[前端知识梳理]]>http://www.wingblog.top/archives/384/[[算法设计手册].(The.Algorithm.Design.Manual,.2ed),.Skiena,.文字版.pdf](http://www.wingblog.top/usr/uploads/2017/11/1823771949.pdf)>兼容性检查
数据结构及算法在线学习1
数据结构及算法在线学习2

CSS

盒子模型 链接

  1. content-box:标准盒模型,CSS定义的宽高只包含content的宽高
  2. border-box:IE盒模型,CSS定义的宽高包括了content,padding和border

Javascript

原型与原型链 链接

普通对象和函数对象

JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象

普通对象函数对象
var o1 = {};function f1(){};
var o2 =new Object();var f2 = function(){};
var o3 = new f1();var f3 = new Function('str','console.log(str)');
console.log(typeof Object); //function 
console.log(typeof Function); //function  

console.log(typeof f1); //function 
console.log(typeof f2); //function 
console.log(typeof f3); //function   

console.log(typeof o1); //object 
console.log(typeof o2); //object 
console.log(typeof o3); //object

o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。
凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。

构造函数

function Person(name, age, job) {
 this.name = name;
 this.age = age;
 this.job = job;
 this.sayName = function() { alert(this.name) } 
}
var person1 = new Person('Zaxlct', 28, 'Software Engineer');
var person2 = new Person('Mick', 23, 'Doctor');

person1 和 person2 都是 Person 的实例。这两个实例都有一个 constructor (构造函数)属性,该属性(是一个指针)指向 Person。 即:

  console.log(person1.constructor == Person); //true
  console.log(person2.constructor == Person); //true

我们要记住两个概念(构造函数,实例):
person1 和 person2 都是 (构造函数 Person[函数对象]) 的**实例
**
一个公式:实例的构造函数属性(constructor)指向构造函数。

原型对象

在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象

公式:每个对象都有 proto 属性,但只有函数对象才有 prototype 属性

深度截图_选择区域_20171123102607.png

function Person() {}
Person.prototype.name = 'Zaxlct';
Person.prototype.age  = 28;
Person.prototype.job  = 'Software Engineer';
Person.prototype.sayName = function() {
  alert(this.name);
}
  
var person1 = new Person();
person1.sayName(); // 'Zaxlct'

var person2 = new Person();
person2.sayName(); // 'Zaxlct'

console.log(person1.sayname == person2.sayname); //true

改写:

Person.prototype = {
   name:  'Zaxlct',
   age: 28,
   job: 'Software Engineer',
   sayName: function() {
     alert(this.name);
   }
}

原型对象就是 Person.prototype
在上面我们给 A 添加了 四个属性:name、age、job、sayName。其实它还有一个默认的属性:constructor

在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person

Person.prototype.constructor == Person
person1.constructor == Person //上边例子中 person1实例

person1 为什么有 constructor 属性?那是因为 person1 是 Person 的实例。
那 Person.prototype 为什么有 constructor 属性??同理, Person.prototype (你把它想象成 A) 也是Person 的实例。
也就是在 Person 创建的时候,创建了一个它的实例对象并赋值给它的 prototype,基本过程如下:

 var A = new Person();
 Person.prototype = A;

可以理解为:原型对象(Person.prototype)是 构造函数(Person)的一个实例。
结论:高程红宝书说,构造函数的原型对象并不是构造函数的一个实例。只是构造函数的一个属性,这个属性是自动获得的。

原型对象其实就是普通对象(但 Function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:

function Person(){};
 console.log(Person.prototype) //Person{}
 console.log(typeof Person.prototype) //Object
 console.log(typeof Function.prototype) // Function,这个特殊
 console.log(typeof Object.prototype) // Object
 console.log(typeof Function.prototype.prototype) //undefined

结论:所有函数对象的 proto 都指向 Function.prototype,它是一个javascript native函数

extend: function(Child, Parent) {
    function Ctor() {
      this.constructor = Child;
    }
    Ctor.prototype = Parent.prototype;
    Child.prototype = new Ctor();
    Child.super_ = Parent.prototype;
  },

DOM事件的绑定的几种方式 事件参考

  1. 在DOM元素中直接绑定
  2. 在JavaScript代码中绑定
document.getElementById("demo").onclick=function(){
    alert(this.getAttribute("type"))
}
  1. 绑定事件监听函数
elementObject.addEventListener(eventName,handle,useCapture)

target 和 currentTarget 参考

DOM hash

参考1
参考2

]]>
JavaScript
<![CDATA[谷歌浏览器]]>http://www.wingblog.top/archives/378/控制台

彩色log 参考

console.log("%c%s","color: green;font-size: 14px;","Hello World");
]]>
JavaScript
<![CDATA[Swiper]]>http://www.wingblog.top/archives/368/重新初始化

参考地址

observer:true,//修改swiper自己或子元素时,自动初始化swiper 
observeParents:false,//修改swiper的父元素时,自动初始化swiper 
onSlideChangeEnd: function(swiper){ 
   swiper.update();  
   mySwiper.startAutoplay();
     mySwiper.reLoop();  
}
]]>
JavaScript
<![CDATA[Mobile]]>http://www.wingblog.top/archives/363/

note some js code in mobile

scroll smooth

code

// scrollSmooth.js
module.exports = function (elem) {
    var startY, endY, startTime, endTime;
    var speedDecay = 0.02; //速度衰减量  
    var lastMoveTime, secondLastMoveTime; //最后次手指停止移动的时间和倒数第二次手指停止移动的时间(测试的时发现有时候最后一次移动时间不准确,故而选用倒数第二次停止移动的时间)  
    var stopMoveInterval; //手指停止滑动的时间  

    var stopInertiaMove = false; //停止惯性滚动的标识位  


    var oldPageY = null;
    var oldScrollTop = null;
    elem.addEventListener('touchstart', function (e) {
        oldScrollTop = elem.scrollTop
        stopInertiaMove = true; //当惯性滑动过程中再次触碰到屏幕的时候应该立即停止惯性滑动  
        startY = e.touches[0].pageY;
        startTime = Date.now();
    });



    elem.addEventListener('touchmove', function (e) {
        //这个事件主要用来记录最后一次停止滑动的时间,当停止滑动时间超过一定量就不执行惯性滑动  
        secondLastMoveTime = lastMoveTime;
        if (oldPageY) { //正常速度滚动
            let top = oldScrollTop + (oldPageY - e.touches[0].pageY)
            elem.scrollTop = top
        }
        if (!oldPageY) oldPageY = e.touches[0].pageY

        lastMoveTime = Date.now();
    });

    elem.addEventListener('touchend', function (e) {
        oldPageY = null
        endY = e.changedTouches[0].pageY;
        endTime = Date.now();
        if (secondLastMoveTime) {
            stopMoveInterval = endTime - secondLastMoveTime;
        } else {
            stopMoveInterval = endTime - lastMoveTime;
        }

        //计算速度,距离除以时间  
        var speed = (endY - startY) / (endTime - startTime);
        var speedAbs = Math.abs(speed);

        /** 
         * 惯性移动的递归方法 
         */
        function inertiaMove() {
            if (speedAbs < 0 || stopInertiaMove) {
                //如果速度绝对值小于0了,则结束惯性滚动  
                return;
            }


            //设置每次惯性滑动时间为20毫秒  
            var distance = speedAbs * 20;


            if (speed < 0) {
                //如果速度是负数,则是手指向上滑动。继续惯性滚动,则scrollTop的值会增加  
                elem.scrollTop += distance;
                //console.log('向上惯性滚动' + distance);  
            } else {
                //如果速度是正数,则是手指向下滑动。继续惯性滚动,则scrollTop的值会减少  
                elem.scrollTop -= distance;
                //console.log('向下惯性滚动' + distance);  
            }


            //速度衰减  
            speedAbs -= speedDecay;

            setTimeout(inertiaMove, 10);
        }

        if (stopMoveInterval < 100) {
            //手指停止滑动超过0.1秒的就不执行惯性滑动了  
            stopInertiaMove = false;
            inertiaMove();
        }
    });
}

usage

import MyScroll from './util/scrollSmooth'
let ele = document.getElelmetById('xxx')
MyScroll(ele)

ban wechat and browser body default scroll pull

code

document.addEventListener('touchmove', function (e) {
    e.preventDefault();
});
]]>
JavaScript
<![CDATA[CentOs常用]]>http://www.wingblog.top/archives/360/

CentOS下自己常用的命令配置等

CentOS 7

防火墙端口等设置

]]>
JavaScript
<![CDATA[Linux Node Install]]>http://www.wingblog.top/archives/358/

install node in linux.

下载安装包

直通车

1.解压

cd /download
wget https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz
xz -d node.tar.xz
tar -xvf node.tar

2.安装Node到Linux常规软件安装目录

mv /download/node /usr/local

3.配置环境变量

ln -s /usr/local/node/bin/node /usr/local/bin/node
ln -s /usr/local/node/bin/npm /usr/local/bin/npm
]]>
JavaScript
<![CDATA[SSH 免密连接 Linux]]>http://www.wingblog.top/archives/317/生成 SSH 公钥

此步骤仅在你电脑未生成公钥时使用

ssh-keygen  -t rsa -P

服务器配置

  • 拷贝本机 .ssh/id_rsa.pub 里的内容到服务器 .ssh/authorized_keys 文件中 (进入此用户的.ssh目录,将生成的公钥文件(默认为id_rsa.pub)内容添加到与sshd_config中AuthorizedKeysFile设置项一样的文件(authorized_keys)中,如果没有.ssh 建立 .ssh文件夹,赋权-R 700) 参考

本机配置服务器 IP 别名

  • 创建 .ssh/config 文件
cd .ssh/
touch config
vim config
  • 在 config 文件中加入类似如下配置:
Host               ali     //别名
HostName           106.15.199.100  //服务器 IP
Port               28    //ssh 端口
User               root   //登录用户
IdentityFile       ~/.ssh/id_rsa   //私钥

此时在本机就可以使用以下命令免密登录了。

ssh ali
]]>
Linux
<![CDATA[搭建 Git 私有服务器]]>http://www.wingblog.top/archives/311/

git -> gitlab 迁移

服务器端执行

cd your_project.git/
git remote add origin git@gitlab_host:admin/your_project.git
git push -u origin master

新建用户

groupadd git
adduser git -g git

新建 authorized_keys 文件

cd /home/git
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
cd /home
chown -R git:git git

客户端创建密钥并上传

之前创建过就不需要了

ssh-keygen -t rsa -C "your_email"

创建 git 仓库

cd gitrepo
git init --bare sample.git
chown -R git:git sample.git

禁止 git shell 登录

git:x:1001:1001:,,,:/home/git:/bin/bash
改为
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
]]>
工具git
<![CDATA[输入法双拼(自然码)]]>http://www.wingblog.top/archives/309/参考1
参考2

键位记忆口诀

  • 秋(花恰),空欢月, (怀罄)睡春多氲。
    Q W E R T Y U I O P
  • 空(胧琼)(浆晃), 闻曾沧燕涛白。
    A S D F G H J K L
  • 飞蝶飘[坠]眸冰涟
    Z X C V B N M

自然码辅助码

基本原理

汉语中同音字太多,用拼音打字重码率高,引入辅助码后,将汉字的偏旁部首发音的声母(比如:“像”的部首是“人”,“人”的声母是r)作为拼音之后的补充部分,所以输入”xdr”(xd是“像”的自然码双拼)就能自动筛选出符合声母是r的偏旁的字,“像”这个字也就自然出现在了候选词的第一个(前几个)。

部件拆分原理

独体字

一般是部首汉字,如:“金木水火土辶皿马皮日月目衣耳”等。独体字全部看成部首,不能进一步拆分出部件,只能由笔画构成。
自然码中的笔画码:
①以横竖起笔的在a键上: “一丨亅レ乛フㄥ”
②以点起笔的在 d 键上:“丶冫氵”【d就是点的意思啦】
③以撇起笔的在 p 键上:“丿彡”【p就是撇的意思啦】
举例:金【jnp,jn是金的自然码双拼,辅助码p是金的第一笔撇p】

有明显部首的汉字

如 “极、版、码、程、想、 福、袋、鳌、游、洪、递”,辅助码就是部首的声母。(注意:部首以新华字典上的为标准,不是以从上到下从左到右的顺序看部首的,比如“架”的部首是“木”)
举例:架【jwm,jw是架的自然码双拼,辅助码m是木的声母m】
说明:如果一个字有明显两个部首,比如“杏”的部首可以是“木”和“口”,所以随意哪个部首当作辅助码都行,也就是输入【xym】或【xyk】两者皆可。

不认识或不是整体字部件的汉字

如“录、芈、暨、 释、稽、躅、摭、谧、荔”,这类字的部首或部件可以用首笔画(尾部用末笔画)或能认识的汉字代替。 【比如 躅=足+虫 】

基础辅助形码表

【a】一 丨亅 レ 乛 フ ㄥ
【b】 八 丷 卜 冖 宀 匕 比 白 贝 疒 鼻
【c】 艹 卄 廾  廿 屮 卝 寸
【d】 丶 冫 氵刀刂 リ ㄍ ⺈ 丁 歹 癶
【e】 二 儿 阝耳 卩 
【f】 扌 丰 反 方 风 父 缶 巿
【g】 乚  ㄅ ㄋ 勹 弓 工 广 艮 戈 瓜 谷 革 骨 鬼 夬 罓
【h】 灬 火 禾 户 虍 黑 乊 厷
【i】 厂 川 巛 亍 车 虫 臣 辰 赤 齿 髟 豖
【j】 几 九 己 巾 斤 钅 金 见 臼  角
【k】 コ 凵 匚 冂 口 囗 丂
【l】 力 六 立 龙 耒 卤 鹿
【m】 木 门 毛 马 米 矛 母 皿 尨 麻 丏
【n】 女 牛 牜 ⺧ 鸟
【o】 日 曰 月 目
【p】 ノ 彡 片 皮 疋 ⺪ 攴
【q】 七 犭 犬 丌 欠 气 且
【r】 亻 人 入 肉
【s】 三 罒 巳 纟 糹 糸 厶 
【t】 土 田
【u】 水 手  食 飠饣示 礻山 石 尸 十 士 矢 殳 舌 身 豕 鼠
【v】 隹 ⺮ 爫 爪 豸 止 至 舟
【w】 文 亠 攵 夂 夊 ㄨ 王 韦 瓦
【x】 彳 小  心 忄  血 彐 夕 习 西 辛
【y】 乙 又 已 讠言 幺 尤 尢 冘 衣 衤羊 牙 业 由 用 页 酉 鱼 雨 羽 聿 乑 乂
【z】 辶 廴 子 自 走 足 ⻊卆

需要特殊记忆的部件

“日、月、曰、目”辅助码为圆圆的【o】
“扌”辅助码为扶手的【f】
“ 彳”辅助码为行人的【x】
“一、丨、亅、乛”横竖折都是【a】
“亠”文字头【d】
“灬”火的变体【h】
“艮”根【g】
“肀”聿yu【y】
“耒”垒【l】——比如耕的双拼+辅助码是【ggl】
“爿”片【p】
“豕”适【u】
“髟”長chang的ch【i】
“隹”锥zhui的zh也就是【v】
“リ”刀的变体【d】
“”艹的变体【c】
“尢”尤的变体【y】
“丌”齐的变体【q】
“弋”弋读yi所以是【y】
“厶”私si的【s】
“ㄨ”叉x的【x】或者勿的【w】

]]>
工具
<![CDATA[Linux 安装 redis]]>http://www.wingblog.top/archives/298/

Redis学习资料

下载编译安装

wget http://download.redis.io/releases/redis-4.0.1.tar.gz
tar -zxvf redis-4.0.1.tar.gz
cd redis-4.0.1.tar.gz
make
cd src
make install
redis-server –v //查看版本命令,检查是否安装成功

配置 redis

1.配置文件一般在 /etc/ 目录下,在此目录创建 redis 目录

cd /etc/
mkdir redis

2.dump file、进程 pid、log 目录等,一般放在 /var/ 目录下

cd /var/
mkdir redis
cd redis
mkdir data log run

3.拷贝解压包下的 redis.conf 文件至 /etc/redis/

cp redis-4.0.1.tar.gz/redis.conf /etc/redis/
vim /etc/redis/redis.conf
  • port 配置端口 (采用默认 6379)
  • dir 配置dump目录(修改为第2步创建的 /var/redis/data 目录)
  • logfile 配置日志目录 (修改 log 存储目录为第2步创建的 /var/redis/log/redis.log 目录)
  • daemonize 默认rdb,可选择是否开启aof(持久化 )
  • requirepass 设置密码,设置后无密码方式可登陆,但是不可进行数据操作

服务及开机自启动

1.拷贝解压包 utils 下 redis 启动脚本 至 /etc/init.d/

cp redis_init_script /etc/init.d/
cd /etc/init.d/
mv redis_init_script redis
chmod +x /etc/init.d/redis

至此,已经可以通过 service redis start/stop 命令启动和关闭 redis
2.设置自启动

chkconfig redis on
  • 如果运行报错,在启动脚本里加入redis启动优先级信息
vim redis
  • 在 #!/bin/sh 下边加入如下两行配置:

    • #chkconfig:2345 90 10
    • #description: Resid ...
chkconfig redis on

此文参考 http://blog.csdn.net/ludonqin/article/details/47211109

]]>
数据库
<![CDATA[未整理文章]]>http://www.wingblog.top/archives/297/接口管理
js !!变量的理解
CentOS7使用firewalld打开关闭防火墙与端口
在线制作 loading (png,svg,gif)
https://loading.io/
loding素材网
在线打字
Mac iTerm2配置
在线画图1 部分免费
在线画图2 免费
免费看板 及配合在线画图2 免费存储
阿里妈妈webfont
有字库 中文webfont支持
字蛛 webfont 开源项目 强力推荐
正则表达式学习
在线正则表达式测试
Http协议理解
URI和URL的区别
年纪越大,越没有人会原谅你的穷?
浏览器加载、解析、渲染的过程1
浏览器加载、解析、渲染的过程2
howBrowserWorks
Vue基础概念
前端工程师都有用哪些比较靠谱的小工具?
自动设计封面的网站
同色配色
浏览器自动刷新简便工具
常用Web工具包
贝塞尔曲线在线生成
非主流字符与表情
mootools
MooTools是一个简洁,模块化,面向对象的开源JavaScript web应用框架。
它为web开发者提供了一个跨浏览器js解决方案。在处理js、css、html时候。
它提供了一个比普通js更面向对象的documentAPI。
博客SEO优化
同步异步概念
ajax原理
自动刷新最快方式
包分析
FileUpload1
FileUpload2
FileUpload3
UI库 semantic
配色
http协议
http协议1

]]>
杂类
<![CDATA[typecho 搭建]]>http://www.wingblog.top/archives/173/

最近听朋友说 typecho 比 wordpress 轻量、好用。抱着试一试的心态开始搭建 typecho,一装就是3天,每天晚上弄在两点左右... (扶我起来,我还能继续配置这个伪静态 :sleepy:)

服务器信息

  • 阿里云镜像站 预装 lnmp 的 CentOs 7 系统镜像

开始安装

1.typecho官网下载 1.0正式版(开发版有坑,别问我为什么!!!):

wget https://github.com/typecho/typecho/releases/download/v1.0-14.10.10-release/1.0.14.10.10.-release.tar.gz

2.将typecho tar包解压后,移动到站点目录下并改名为typecho:

tar -zxvf 1.0.14.10.10.-release.tar.gz
mv 1.0.14.10.10.-release /home/wwwroot/typecho

配置 Nginx

1.创建虚拟主机

lnmp vhost add

2.按照提示信息配置虚拟主机

网站名:www.yoursitename.com
网站其他名称:回车(默认无)
网站目录:/home/wwwroot/typecho
开启重写:y
重写规则:typecho
日志记录: y
日志名称:回车(选默认)
创建 mysql 表: n
SSL(https)安全认证:n

3.开启php pathinfo(解决后台登录404)

vim /usr/local/nginx/conf/vhost/www.yoursitename.com

然后将文件中 enable-php.conf 改为 enable-php-pathinfo.conf

创建数据库表

1.登录 mysql:

mysql -uroot -p
create datatable typecho

配置 typecho

1.浏览器打开的网站 (http://www.yoursitename.com),会自动跳转到安装界面:
2.点击开始下一步,配置数据库信息

3.继续按照提示安装

配置网站

1.进入网站后台 在之前配置的域名后加/admin 如(http://www.yoursitename.com/admin)进入后台
2.点击 设置 -> 永久链接,开启重写(伪静态

End

至此,typecho 搭建成功,可以开启你的 typecho 之旅了。 :v: :v:

typecho 相关

插件

插件下载地址

1.将下载的插件解压放入 typecho plugins目录中

mv <解压后的插件目录> /home/wwwroot/typecho/usr/plugins/

2.赋插件目录权限

chmod -R 777 home/wwwroot/typecho/usr/plugins/

3.推荐插件 editor.md ( Markdown 编辑器,比 typecho 原生支持的丰富许多,如 tabel 的 Markdown 语法等)

主题

主题下载地址
使用方式同插件,但是在 typecho themes 目录,极力推荐一款主题 pinghsu

  • PinghSu

    • 文章缩略图

      文章设置缩略图方法有四种,自定义字段thumb,文章附件第一张图片,文章内图片,默认缩略图

      优先级顺序 :自定义字段 thumb -> 附件第一张图片 -> 文章图片 -> 默认缩略图 -> 随机图片 -> 无

      缩略图尺寸大小,高度至少有250px,宽度大于高度,推荐高度为400px的

    • 个性化标徽

      个性化标徽出现的地方有首页、分类页,标签页,作者页和相关文章

      设置方法是在文章编辑内填写自定义字段,支持的字段如下

      book 、 game 、 note 、 chat 、 code 、 image 、 web 、 link 、 design 、 lock

    • 个性化色块

      个性化色块需要到外观设置那开启才能激活使用,色块出现的地方有首页,分类页,标签页,独立搜索页等等

      设置方法是在文章编辑内填写自定义字段,支持的字段如下

      blue、purple、green、yellow、red

结语

还有一些小细节和一些想要推荐的插件没有写,以及 editor.md 这个 Markdown 编辑器刚安装有几个小小问题,如遇到问题,请我喝杯啤酒就帮你 :relieved:。

]]>
杂类typecho
<![CDATA[PostCSS]]>http://www.wingblog.top/archives/161/编写自己的插件

Vue 中使用

vue-loader
PostCss 安装常用插件

cnpm i -D postcss-import postcss-crip precss postcss-center postcss-cssnext css-mqpacker autoprefixer postcss-color-hex-alpha cssnano

postcss.config.js

module.exports = {
  plugins: [
    require('postcss-import')(),//将多个样式表合成为一个,提高请求速度  自动发现Bower Component和Node Module中样式文件
    require('postcss-crip'),//简写

    require('precss')(),//使用变量,mix宏等等   相当于Sass处理器
    require('postcss-center')(),//垂直居中和水平居中,父容器需要设置高度和position为relative才有效
    require('postcss-cssnext')({
      features: {
        customProperties: false
      }
    }),//下一代css标准
    require('css-mqpacker')(),//@media媒体查询插件,可以将多个媒体查询合并为一个
    require('autoprefixer')(),//自动加浏览器兼容性前缀
    require('postcss-color-hex-alpha')(),//颜色转换,可以通过#22223333设置颜色和透明度
    require('cssnano')()//优化代码插件

  ]
}
]]>
CSSpostcss
<![CDATA[AngularJS]]>http://www.wingblog.top/archives/147/判断页面是否渲染完成
angular.element(document).ready(function () {
        let items = document.getElementById($ctrl.itemData.id)
        console.log("【初始化---0】:获取拖拽对象", items);
});

Ng-repeat是否渲染完成指令

 tranMobile.directive('repeatFinish', function () {
        return {
            link: function (scope, element, attr) {
                console.log(scope.$index)
                if (scope.$last == true) {
                    scope.$eval(attr.repeatFinish);
                }
            }
        }
    })
]]>
JavaScriptangularjs
<![CDATA[React环境搭建]]>http://www.wingblog.top/archives/142/本地环境搭建
npm install -g create-react-app
create-react-app my-app
cd my-app
npm start
  • 如果遇到 Failed to load plugin import: 'eslint-plugin-import' 错误,解决方法如下:
npm install eslint-plugin-import eslint-plugin-flowtype eslint-plugin-jsx-a11y eslint-plugin-react
]]>
JavaScriptReact
<![CDATA[HTML&JS]]>http://www.wingblog.top/archives/129/监听浏览器history back
function pushHistory() {
            var state = {
                title: "pay",
                url: "#pay"
            }
            window.history.pushState(state, "pay", "#pay");
        }
        pushHistory()

        window.addEventListener("popstate", function () {
            history.go(-2)
        }, false)

clientWidth , offsetHeight 等属性详解 参考

获取元素最终CSS属性值

  • window.getComputedStyle("元素", "伪类");
    可以获取当前元素所有最终使用的CSS属性值。

示例:

let end_style = window.getComputedStyle(document.getElementByID('test'))
alert(end_style.marginTop)

通过 targetObj 寻找 className 为 xxx 的 EleObj

let find_ParentTarByClassName = (target, className) => {
            try {
                while (true) {
                    if (!!target.classList && target.classList.contains(className)) {
                        break;
                    } else {
                        target = target.parentNode;
                    }
                }
                return target;

            } catch (error) {

            }
        }

鼠标滚轮横向滚动

            let ScrollEle = document.querySelector('.scroll-task-main')

            function MouseWheel(e) {
                e = e || window.event;
                if (e.stopPropagation) {
                    e.stopPropagation();
                } else {
                    e.cancelBubble = true;
                }

                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                }

                if (e.wheelDelta > 0) {
                    ScrollEle.scrollLeft -= 60
                } else {
                    ScrollEle.scrollLeft += 60
                }

            }
            ScrollEle.onmousewheel = MouseWheel

textarea自动增高并隐藏滚动条

<textarea id="tValue" style="overflow-y:hidden; height:20px;" onpropertychange="this.style.height=this.scrollHeight + 'px'" oninput="this.style.height=this.scrollHeight + 'px'"></textarea>

父容器draggabel为true,子节点不管是否都能移动

scrollIntoView

textarea高度自适应 参考1参考2

input、textarea、div(contenteditable=true)光标定位到最后 参考1

触发点击事件

var e = document.createEvent("MouseEvents");
e.initEvent("click", true, true);
document.getElementById('container-add-task').dispatchEvent(e);
//Angularjs
angular.element(document.getElementById('detailTask').children[0].children[0]).triggerHandler('click');

手机端点击其他组件调起select

将select透明,然后通过定位将组件放到select位置

判断多个或者单个图片是否加载完成

在Google浏览器图片加载以后就不会调起onload方法,所以需要通过 complete 去判断

let btnPromises = []
        btnPromises.push(new Promise((res, rej) => {
            let ele = document.getElementById('down-ios-img')
            if (!ele.complete) {
                ele.onload = () => {
                    res()
                }
            } else {
                res()
            }

        }))
        btnPromises.push(new Promise((res, rej) => {
            let ele = document.getElementById('down-andriod-img')
            if (!ele.complete) {
                ele.onload = () => {
                    res()
                }
            } else {
                res()
            }
        }))
        Promise.all(btnPromises).then(() => {
            let ele = document.getElementById('btn-animate')
            ele.velocity({ left: '0px', opacity: 1 }, { duration: 1000 });
        })

微信支付浏览器url传参只能传一个

使用 encodeURIComponent 包装一层,使用 encodeURI只会对中文转码,&和/不会转码

encodeURI和encodeURIComponent的区别在于前者被设计来用于对完整URL进行URL Encode,于是URL中的功能字符,比如&, ?, /, =等等这些并不会被转义;而后者被设计来对一个URL中的值进行转义,会把这些功能字符也进行转义。

flex弹性盒子布局中,关于flex-grow布局问题设置

参考

]]>
HTMLHTML
<![CDATA[Git 常用命令]]>http://www.wingblog.top/archives/109/

Git 的一些常用命令和参考学习资料

常用命令参考1
常用命令参考2
学习 Git 阮一峰
学习 Git Bootstrap
远程操作参考

仓库

查看远程仓库信息

git remote -v

本地库关联远程库

git remote add origin git@github.com:nanfei9330/learngit.git

查看所有分支(本地加远程)

git branch -a

查看远程分支

git branch -r

拉取远程分支到本地分支

git checkout -b 本地分支名 origin/远程分支名

推送本地分支到远程分支

git push origin 本地分支名:远程分支名

删除远程分支

git push --delete origin [name]

版本

git checkout 234ab5
git reset --hard 534iu4

分支

创建

git chekout -b dev   // -b 创建并进入

切换分支

git chekout dev

合并分支

  • 正常合并
git merge dev    //当前分支合并 dev 分支
  • --no-ff合并
    --no-ff 禁用 Fast forward 模式在 merge 时生成一个新的commit,这样,从分支历史上就可以看出分支信息
git merge --no-ff -m "merge with no-ff" dev

删除分支

git branch -d dev   // -D 强制删除

push 本地分支到远程

git push origin dev

查看记录 log

git log --graph --pretty=oneline --abbrev-commit

修改状态管理

将当前分支的修改状态存储起来,存储后使得工作区是干净的,就可以 pull 最新代码。

存储

git stash

查看

git stash list

取出

  • 取出列表某个:
git stash drop  statsh@{2}
  • 取出最后一个:
    取出后会删除最后一个状态
git stash pop

标签 tag

创建

git tag <tagname> [ commit id ]  //默认为HEAD,也可以指定一个commit id
  • -m 指定标签信息
git tag -a <tagname> -m "blablabla..."
  • 推送某个标签到远程
git push origin <tagname>
  • 推送全部标签到远程
git push origin --tags

查看

  • 全部
git tag -l
  • tag 名称
git show <tagname>

删除

  • 本地
git tag -d v0.1
  • 远程
git tag -d v0.1
git push origin :refs/tags/v0.9

别名

git config —global alias.lg “log —color —graph —pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ —abbrev-commit”

pull push 配置项

要把当前分支 push 和 pull 的默认分支设置为 dev

git branch --set-upstream-to=origin/dev dev

未分类

丢弃工作区文件修改

git checkout -- b.txt

暂存区修改放回工作区

git reset HEAD b.txt

将文件从缓存中删除(非物理)

git rm --cached  "文件路径"
]]>
工具
<![CDATA[一个神奇的插件]]>http://www.wingblog.top/archives/103/360安全浏览器   360极速浏览器   UC浏览器   Chrome   百度浏览器   猎豹浏览器

]]>
<![CDATA[Webpack配置ES6语法(含webpack配置文件)]]>http://www.wingblog.top/archives/83/webpack 配置详解

使 webpack.config 文件可以使用ES6语法[ webpack3.4.1 ]

1.安装babel相关包
npm install babel-loader babel-core babel-preset-es2015 webpack --save-dev

2.在 webpack.config.js 的同目录下创建文件 .babelrc,内容如下

{
        "presets": ["es2015"]
}

3.在webpack.config.js里配置,babel6,具体如下:

{
        test: /.js$/,
        loader: 'babel-loader'
}

4.将webpack.config.js改名为webpack.config.babel.js。

5.webpack.config 的例子:

import path from 'path';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import CleanWebpackPlugin from 'clean-webpack-plugin';
import webpack from 'webpack';
export default {
    entry: {
        app: './src/index.js'
    },
    devtool: 'inline-source-map', //可以找到对应出错的文件的行数    在开发阶段使用
    devServer: {
        contentBase: './dist',
        compress: true,
        port: 9000,
        hot: true
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: 'Output Managemant',
            filename: 'index.html',
            template: 'assets/admin.html'
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [{
                test: /.js$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                query: {
                    presets: ['es2015']
                }

            },
            {
                test: /.html$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'html-loader'
            }
        ]
    }
};

6.package.json 示例:

"scripts": {
    "build": "webpack",
    "test": "echo "Error: no test specified" && exit 1",
    "test1": "a=1;b=2;echo ($a+$b)",
    "watch": "webpack --watch",
    "start": "webpack-dev-server --open"
  }

webpack-dev-server 热重载

  • contentBase: './dist'

    热重载在内存./dist目录生成打包的文件
  • contentBase: './'

    热重载在内存./目录生成打包的文件
    
    

webpack + vscode 热重载失效

关闭所有打开的vscode窗口,先用vscode外的终端启动项目,等彻底启动起来以后在打开vscode

]]>
JavaScriptwebpack,es6
<![CDATA[Mysql]]>http://www.wingblog.top/archives/76/

Mysql

常用命令

命令作用
create database abc;//创建数据库abc
use abc;//连接数据库abc
set names utf8;//设置数据库编码
source /home/abc/abc.sql;//导入.sql数据
mysqldump -u 用户名 -p 数据库名 > 导出的文件名导出.sql

mysql 杂项

deepin navicat 破解

whereis navicat 
rm -rf ~/.navicat64

mysql开启远程访问

use mysql
update user set host = '%' where user = 'root'; 
select host, user from user;
FLUSH PRIVILEGES 

  • ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

 大意就是你有一个用户名为空的账户,mysql会先匹配它,然后就一直提示你密码错误,删掉这个匿名用户,然后执行 FLUSH PRIVILEGES;

]]>
数据库
<![CDATA[Linux Command]]>http://www.wingblog.top/archives/55/通用 Command

搜索

命令作用
find .xargs ¦ grep -ri "strname"搜索当前目录所有文件是否包含某个字符串
netstat -tlnp查看端口
ln -s a/b /usr/local/bin添加 b 命令到环境变量
sudo passwd [ username ]修改 root 和普通用户密码

环境变量详解

Vim

  • 强制保存
:w !sudo tee %

Linux 守护进程(daemon【node可用PM2框架】参考1 参考2 阮一峰

由来:

启动一个基于 node 的简单 http服务器

  • 脚本代码
//server.js
var http = require('http');
http.createServer(function(req, res) {
 res.writeHead(200, {'Content-Type': 'text/plain'});
 res.end('Hello World');
}).listen(5000);

前台任务(foreground job)与后台任务(background job)

  • 执行以下命令启动脚本
node server.js

这样启动的脚本为 “前台任务”,独占命令窗口,运行完成或手动停止,才能执行其他命令。

node server.js &

这样启动的进程就会成为"后台任务"。如果要让正在运行的"前台任务"变为"后台任务",可以先按ctrl + z,然后执行bg命令(让最近一个暂停的"后台任务"继续执行)。

后台任务特点

  • 继承当前 session (对话)的标准输出(stdout)和标准错误(stderr)。因此,后台任务的所有输出依然会同步地在命令行下显示。
  • 不再继承当前 session 的标准输入(stdin)。你无法向这个任务输入指令了。如果它试图读取标准输入,就会暂停执行(halt)。

SIGHUP信号

变为"后台任务"后,一个进程是否就成为了守护进程呢?或者说,用户退出 session 以后,"后台任务"是否还会继续执行?
Linux系统是这样设计的:

  1. 用户准备退出 session
  2. 系统向该 session 发出SIGHUP信号
  3. session 将SIGHUP信号发给所有子进程
  4. 子进程收到SIGHUP信号后,自动退出

这就解释了为什么"前台任务"会随着 session 的退出而退出:因为它收到了SIGHUP信号。那么,"后台任务"是否也会收到SIGHUP信号?
这由 Shell 的huponexit参数决定的。

shopt | grep huponexit//查看huponexit参数的值。

大多数Linux系统,这个参数默认关闭(off)。因此,session 退出的时候,不会把SIGHUP信号发给"后台任务"。所以,一般来说,"后台任务"不会随着 session 一起退出。

disown 命令

通过"后台任务"启动"守护进程"并不保险,因为有的系统的huponexit参数可能是打开的(on)。
更保险的方法是使用disown命令。它可以将指定任务从"后台任务"列表(jobs命令的返回结果)之中移除。一个"后台任务"只要不在这个列表之中,session 就肯定不会向它发出SIGHUP信号。

node server.js &
disown //移出最近一个正在执行的后台任务 [-r|-a|-h][自行查阅]

FTP

参考
https://blog.csdn.net/hitabc141592/article/details/7573950

]]>
Linux