vue-directive.js 6.54 KB
/*
 * @Author: Targaryen
 * @Date:   2016-08-02 17:29:52
 * @Last Modified by:   Targaryen
 * @Last Modified time: 2016-08-02 17:42:26
 */
import yoho from 'yoho';
import util from 'common/util';

function ImgSrcBinding(el, binding) {
    if (binding.value === binding.oldValue) {
        return;
    }
    if (typeof binding.value === 'string') {
        el.src = binding.value;
    } else if (typeof binding.value === 'object') {
        let {src, width, height, mode} = binding.value;

        el.src = util.getImgUrl(src, width, height, mode);
    }
}
function BrandHrefBinding(el, binding) {
    if (binding.value === binding.oldValue) {
        return;
    }
    if (binding.modifiers.shop) {
        let href = `/product/shop/${binding.value.domain || binding.value.name}`;
        let shopId = binding.value.shopId;

        if (yoho.isYohoBuy && shopId) {
            let { shopName, shopTemplateType, isRedShop } = binding.value;

            let goParams = {
                action: 'go.shop',
                params: {
                    shop_id: shopId + '',
                    shop_name: shopName,
                    is_red_shop: isRedShop,
                    shop_template_type: shopTemplateType
                }
            };

            href += `?openby:yohobuy=${JSON.stringify(goParams)}`;
            el.href = href;
            return;
        }

        if (yoho.isYohoBuy && !shopId) {
            yoho.ready(function () {
                yoho.getAppVersion({}, (version) => {
                    if (version >= '6.5.5') {
                        let { name } = binding.value;
                        let goParams = {
                            action: 'go.searchlist',
                            params: {
                                keyword: name
                            }
                        };

                        href += `?openby:yohobuy=${JSON.stringify(goParams)}`;
                        el.href = href;
                    } else {
                        el.href = href;
                    }
                });
            });
            return;
        }

        el.href = href;
    } else {
        el.href = `/product/shop/${binding.value}`;
    }
}
function GoodHrefBinding(el, binding) {
    if (binding.value === binding.oldValue) {
        return;
    }
    let {product_id, goods_id, cn_alphabet, product_skn} = binding.value;

    if (!binding.modifiers.collect) {
        goods_id = binding.value.goods_list.length ? binding.value.goods_list[0].goods_id : '';
    }
    let href = `/product/pro_${product_id}_${goods_id}/${cn_alphabet || 'item'}.html`;

    if (yoho.isYohoBuy) {
        let goParams = {
            action: 'go.productDetail',
            params: {
                product_skn: product_skn
            }
        };

        href += `?openby:yohobuy=${JSON.stringify(goParams)}`;
    }
    el.href = href;
}
function BlkHrefBinding(el, binding) {
    let value = binding.value;
    let protocol = value.match(/^(https?:)?\/\//);

    protocol = protocol && protocol.length ? protocol[0] : '';
    value = value.replace(protocol, '');

    // 新品抢先看
    let query = value.match(/^m\.yohobuy\.com\/product\/blknew(\?.*)?/);

    if (query) {
        query = query[1] || '';
        return el.href = `${protocol}m.yohoblk.com/new${query}`;
    }

    // 全部品类
    if (value === 'm.yohobuy.com/cate') {
        return el.href = `${protocol}m.yohoblk.com/cate-all`;
    }

    // 全部品牌
    if (value === 'm.yohobuy.com/brand' || value === 'm.yohobuy.com/brands') {
        return el.href = `${protocol}m.yohoblk.com/brand`;
    }

    // 部分品牌
    query = value.match(/^m\.yohobuy\.com\/product\/index\/brand\?(.*)?/);
    query = query && query[1] || '';
    if (query && query.indexOf('domain=') > -1) {
        let domain = query.match(/domain=([^&]*)&?.*?/);

        domain = domain[1] || '';
        return el.href = `${protocol}m.yohoblk.com/product/shop/${domain}?${query}`;
    }

    let subDomain = value.match(/(.+)\.m\.yohobuy\.com/);

    subDomain = subDomain ? subDomain[1] : '';
    if (subDomain) {
        if (subDomain === 'guang') {
            // 逛
            let editorialId = value.match(/guang\.m\.yohobuy\.com\/info\/index\?id=(\d{1,})/);

            if (editorialId) {
                editorialId = editorialId[1];
                return el.href = `${protocol}m.yohoblk.com/editorial/${editorialId}.html`;
            }
        } else if (subDomain === 'list') {
            // 品类
            query = value.match(/\?.*/);
            query = query ? query[0] : '';
            return el.href = `${protocol}m.yohoblk.com/product/list${query}`;
        } else {
            // 品牌
            query = value.match(/\?.*/);
            query = query ? query[0] : '';
            return el.href = `${protocol}m.yohoblk.com/product/shop/${subDomain}${query}`;
        }
    }


    el.href = `${protocol}${value}`;
}

function lazyHtmlReplace(html, lazy) {
    let renderImgIndex = 5;

    return html
        .replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (imgHtml, src) => {
            if (src.indexOf('?') < 0) {
                src += '?imageMogr2/thumbnail/750x/quality/60/interlace/1';
            }
            if (lazy) {
                renderImgIndex--;
            }
            src = util.replaceHttp(src);
            return (lazy && renderImgIndex < 0) ? `<img v-lazy.imgLazyContainer="'${src}'" />` : `<img src="${src}" />`;
        });
}

export default (Vue) => {
    Vue.directive('lazy-html', {
        bind(el, binding) {
            // TODO 首屏幕不使用
            setTimeout(() => {
                let html = lazyHtmlReplace(binding.value, true);

                try {
                    let res = Vue.compile(`<div>${html}</div>`);
                    let component = new Vue({
                        render: res.render,
                        staticRenderFns: res.staticRenderFns
                    });

                    Vue.nextTick(() => {
                        component.$mount(el);
                    });

                } catch (e) {
                    html = lazyHtmlReplace(binding.value);
                    el.innerHTML = html;
                }
            }, 500);
        }
    });
    Vue.directive('img-src', {
        bind: ImgSrcBinding,
        update: ImgSrcBinding
    });
    Vue.directive('brand-href', {
        bind: BrandHrefBinding,
        update: BrandHrefBinding
    });
    Vue.directive('good-href', {
        bind: GoodHrefBinding,
        update: GoodHrefBinding
    });
    Vue.directive('blk-href', {
        bind: BlkHrefBinding,
        update: BlkHrefBinding
    });
};