对 我又挖坑了 不过其实也不算挖坑 因为ui构建中就会有填坑的文章 之前一直在写《编写大型web页面 结合现有前端形势思考未来前端》这是一篇巨难写的文章 估计要到年中才能写好了 写作的过程中 发生了国内前端大撕逼 2015的尾声大战 是否可以宣告前端是否开始新的时代 2016年 国内前端可能还会依旧艰难 国外前端也不是很好 微软正式不再支持ie11以下的浏览器 估计今年内 国外框架就要完全提高至ie10兼容水平了

zhilizhili-ui

自己从有这个想法到现在zhilizhili-ui发展到1.24版本已经快一年了 这一年里自己收集和编写了sassstd scss-zhilizhili-mei 这些一直在用sass库 sass可能不再是很新鲜的样式预编译语言了 的确受到一些压力 不过自己也在积极改进样式构建的流程 自己加入了postcss支持 2016年 打算开始和css4无缝对接

写个样例站吧

我选用前端框架angular2 后端laravel

本文不会特地放出demo

要想找到源码 请到我的github项目上

tde.blade.php

<!doctype html>
<!--[if IE 8 ]><html class="ie8" lang="zh-cn"><![endif]-->
<!--[if IE 9 ]><html class="ie9" lang="zh-cn"><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="" lang="zh-cn"><!--<![endif]-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
    <meta name="viewport"
          content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Mobile Component</title>

    <!-- 1. Load libraries -->
    <script src="/assets/static/node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="/assets/static/node_modules/systemjs/dist/system.src.js"></script>
    <script src="/assets/static/node_modules/rxjs/bundles/Rx.js"></script>
    <script src="/assets/static/node_modules/angular2/bundles/angular2.dev.js"></script>


    <!-- 2. Configure SystemJS -->
    <script>
        System.defaultJSExtensions = true;
        System.config({
            map: {
                angular2: '/assets/static/node_modules/angular2',
                rxjs: '/assets/static/node_modules/rxjs'
            }
        });
        System.import('/assets/mobile/controller/ui/tde')
                .then(null, console.error.bind(console));
    </script>

    <link rel="stylesheet" href="/assets/static/css/normalize.css">
    <link rel="stylesheet" href="/assets/mobile/css/ui/tde.css?v=<% rand(0, 1000) %>">
    <script src="/assets/static/js/dom4.min.js"></script>
    <!--[if lte IE 10]>
    <script src="/assets/static/js/placeholders.min.js"></script>
    <![endif]-->
</head>
<body class="ui-tde dark-style">
    <my-app>Loading...</my-app>
</body>
</html>

说到angular2 大家可能对她还不是很感兴趣 但是在浏览器依旧要面对ie的时代 这个时代可能还要5年 angular2的确是给了一个大型应用的解决方案 的确 还是脏检查 不过使用的是worker zone.js提供了支持

2014年的ngconf大会 angular团队介绍了zone.js zone 就像java thread ok 好吧用进程模拟线程 也是可以的 dart有zones

zone is a execution context

通常我们写异步js

a();
setTimeout(b, 0);
setTimeout(c, 0);    
d();

她的执行顺序

a
d
b
c

如果我们改改

start();
a();
setTimeout(b, 0);
setTimeout(c, 0);    
d();
stop();

b c是不会被影响的

zone希望去使代码可预测

zone.run(function() {
    a();
    setTimeout(b, 0);
    setTimeout(c, 0);    
    d();    
));

function onZoneEnter() {
}

function onZoneLeave() {
}

tde.ts

import {AppComponent}     from './tde/app.component';
import {bootstrap}        from 'angular2/platform/browser';
import {provide}          from 'angular2/core';
import {
    APP_BASE_HREF,
    ROUTER_PROVIDERS
} from 'angular2/router';
bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    provide(APP_BASE_HREF, {useValue: '/wex/mtc'})
]);

zone可以捕捉甚至异步操作 用过angular2的都知道她的debug非常好 就是使用的是zone.js
angular之前的$scope.apply没有了 没了 不要担心了

rxjs

响应式编程 rxjava很牛对吧 这个也不错

RxJS 是使用可观察序列和 LINQ 风格查询操作符来编写异步和基于事件程序的类库。 使用 RxJS, 开发者用 Observables 来 表示 异步数据流,通过 LINQ 操作符来 查询 异步数据量,并使用 Schedules 来参数化异步数据流中的并发。 简单地讲, Rx = Observables + LINQ + Schedulers。

在 RxJS 中,你可以表述多个异步数据流,并且使用 Observer 对象订阅事件流。 Observable 对象会在事件发生时通知已订阅的 Observer。

因为 Observable 序列是数据流,你可以使用由 Observable 扩展方法实现的标准查询操作符 来查询它们。这样你可以通过这些查询操作符很容易地在多个事件上进行过滤、投射、聚合、 组合和执行基于时间的操作。除此之外还有很多其他反应式流特定的操作符使得可以书写强大的查询。 取消、异常和同步都可以通过由 Rx 提供的扩展方法优雅地处理。

由 Rx 实现的 Push 模型表现为 Observable/Observer 的观察者模式。 Observable 会自动在任何状态改变时通知所有的 Observers。 要通过订阅注册一个关注,你要使用 Observable 上的 subscribe 方法, 它接收一个 Observer 并返回一个 Disposable 对象。 它让你能够跟踪你的订阅并能够取消该订阅。 本质上你可以将可观察序列看做一个常规的集合。

开始最初的页面设计

图片描述

大概就是desktop端需要一个框架样的东西 pad端 mobile端 就隐藏两边边栏

未来组团开发的时候 很多情况样式并非一个人开发 可能架构组会将页面元素定下来 register-hook 然后业务实现组 要通过 use-hook 来开发 这样上层设计改变 代码也可以有效维护

tde.scss
首先我们需要一些生成media query的sass方法 这样不错

@import "../../../../../node_modules/sass-mediaqueries/media-queries";

@function mq($args...) {
    $media-type: 'only screen';
    $media-type-key: 'media-type';
    $args: keywords($args);
    $expr: '';

    @if map-has-key($args, $media-type-key) {
        $media-type: map-get($args, $media-type-key);
        $args: map-remove($args, $media-type-key);
    }

    @each $key, $value in $args {
        @if $value {
            $expr: "#{$expr} and (#{$key}: #{$value})";
        }
    }

    @return #{$media-type} #{$expr};
}

@function screen($min, $max, $orientation: false) {
    @return mq($min-width: $min, $max-width: $max, $orientation: $orientation);
}

我们需要一些全局变量保存

$custom-deivces: (
    "mobile": 320,
    "pad": 768,
    "desktop": 1280,
) !global;

$custom-deivces-media: () !global;
$custom-deivces-hook: () !global;

这样的话 我们需要一个初始化sass实现的方法

@mixin initlize-media-hooks($custom-deivces) {
    $custom-deivces-indicators: map-keys($custom-deivces);
    $custom-deivces-indicatorslength: length($custom-deivces-indicators);

    @for $i from 1 through $custom-deivces-indicatorslength {
        $currentDeviceIndicator: nth($custom-deivces-indicators, $i);
        $currentDevice: map-deep-get($custom-deivces, $currentDeviceIndicator);
        $currentMedia: $currentDevice + 0px;
        $nextDeviceIndicator: if($i < $custom-deivces-indicatorslength, nth($custom-deivces-indicators, ($i + 1)), null);
        $nextDevice: if($nextDeviceIndicator !=null, map-deep-get($custom-deivces, $nextDeviceIndicator), 2881);
        $nextMedia: $nextDevice + 0px - 1;
        @include screen($currentMedia, $nextMedia) {
            $custom-deivces-media: map-deep-set($custom-deivces-media, $currentDeviceIndicator, screen($currentMedia, $nextMedia)) !global;
            $custom-deivces-hook: map-deep-set($custom-deivces-hook, $currentDeviceIndicator, "device #{$currentDeviceIndicator}") !global;
        }
    }
}

@mixin use-media-hook($device) {
    @media #{map-deep-get($custom-deivces-media, $device)} {
        @at-root {
            @content;
        }
    }
}

每个页面可能有不同兼容情况 然后只需要自定义设备 在初始化一下

$custom-deivces: map-extend($customo-device, (...));
@include initlize-media-hooks($custom-deivces);

然后我们就可以使用自己定义好的设备查询

@include use-media-hook("pad") {
    @include use-hook(".main-inner .layout__item.layout__item--prefix") {
        position: absolute;
        left: 0;
        top: 0;
    }
    @include use-hook(".main-inner .layout__item.layout__item--suffix") {
        position: absolute;
        right: 0;
        top: 0;
    }
}

@include use-media-hook("mobile") {
    @include use-hook(".main-inner .layout__item.layout__item--prefix") {
        position: absolute;
        left: 0;
        top: 0;
        opacity: 0;
        z-index: -1;
    }
    @include use-hook(".main-inner .layout__item.layout__item--suffix") {
        position: absolute;
        right: 0;
        top: 0;
        opacity: 0;
        z-index: -1;
    }
}

然后一个操作视频

bilibili链接

happy fte


andypinet
1.2k 声望41 粉丝

求一个常州 无锡 镇江的前端工作