前端FISH框架学习笔记

Fish

0. 学习路线

前期自学

fish基础组件(写简单demo) -> 模块化开发(写简单demo) -> 实际项目代码阅读

实际开发

看组件示例
看fish API
看代码示例
百度

1. 环境搭载

下载fihs发布包
工具的安装和使用:git、node、fish-cli
前端编辑器:vs code、hbuilder、sublime…

2. 前端基础入门

2.1 css

  1. position
    定义和用法
    position 属性把元素放置到一个静态的、相对的、绝对的、或固定的位置中。

  2. aria-hidden:
    Accessible Rich Internet Applications (ARIA) 规定了能够让 Web 内容和 Web 应用(特别是那些由 Ajax 和 JavaScript 开发的)对于残障人士更易使用的各种机制。例如,ARIA 提供了易用的导航地标、JavaScript 组件、表单提示以及错误信息、实时内容更新等。

  3. display属性:display 属性规定元素应该生成的框的类型

  4. HTML标签的for属性:规定label与哪个表单元素绑定。
  5. ajax
  6. 实现左侧导航栏高度自适应右边内容:js实现,css也可以。

2.2 js/jQuery

  1. fish封装js函数

  2. js函数语法

indexView.index(function(result){
        if(result){
            indexView.render();//渲染首页,
        }
        fish.history.start();//启动路由
    });

index: function (callback) {
            Http.isLogin({callback:function(result){
                    callback.call(this,result);

                }})
        },

isLogin: function(json) {
                //判断是否有用户变量数据
                var userData = Http.getCacheMap("userData");
                if (userData) { //存在用户数据
                    json.callback.call(this, true);
                } else {
                    //请求用户数据
                    Http.ajax({
                        url: apiJson.login.getUserData,
                        success: function(result, status, response) {
                            var isLogin = false;
                            if (result && result.result) { //拿到用户数据
                                Http.setCacheMap("userData", result.result);
                                isLogin = true;
                            }
                            json.callback.call(this, isLogin);
                        }
                    });
                }
            },

a. index()
从函数对象开始,IndexView对象定义了index方法,而该方法定义了一个函数,
并作为对象的属性存储。对象方法就可以通过添加()来作为一个函数来调用,调用其定义的函数。

以上的index()即调用的为index定义的函数。

一般定义的函数都有返回值

b. index(function(){})
函数作为参数传递

c. index(function(result){...})
result是index()的返回结果

d. callback.call(this, result)

callback:

在JS中,函数就是一种对象.它有对象应该有的所有操作:

  • 存在变量名中
  • 当作参数传到另一个函数中
  • 在函数中被创建
  • 在函数中被返回
    所以,我们可以把函数当作变量传到另一个函数里,传进去之后执行甚至返回等待之后的执行。这就是callback函数的本质。
    参考博客链接
    callback函数就是被当作参数传入另一个函数的函数,并且传入之后在另一个函数中被执行。他们在jQuery和JS中随处可见。
    //click函数中的参数不是普通的参数,而是一个函数
    //那个函数就是callback函数
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});

* callback.all(this, result):*
通过call 可以改变this的指向。
为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。
在这里即把this指向result
this的用法:
this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁
3. ajax

AJAX 是一种用于创建快速动态网页的技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

jQuery ajax

2.3 jQuery

* jQuery HTML/CSS方法

  1. height() (可以用来通过计算右侧内容的高度,设置左侧导航的高度)

返回高度:

$(selector).height()

设置高度:

$(selector).height(value)

3. fish-cli脚手架 模块化开发

3.1 脚手架执行流程

1. index.html引入 fish-desktop-require.js 文件,用于处理模块文件加载开发
2. 入口文件main.js,加载主视图IndexView,进行页面渲染初始化
require(['demo/main/views/IndexView'], function(IndexView) {

    var indexView = new IndexView();
    indexView.render();

});
3. 主视图IndexView又定义两个子视图的依赖,框架会分析依赖关系,自动加载依赖模块文件 modules/module-a/view/AlphaView.js 和 modules/modue-b/views/BetaView.js,如果这两个模块也有依赖,重复刚才分析操作加载
define([
    'hbs!../templates/indexView',
    'demo/test/views/TestView', 
    'demo/test/views/Test1View', 
    'demo/test/views/Test2View'
], function(mainHtml, TestView, Test1View, Test2View){

    var IndexView = fish.View.extend({
        // 视图 Dom 元素
        el: 'body',
        // 视图模板函数
        template: mainHtml,
        // 填充模板数据
        /*serialize: {
            ""
        },*/
        // 视图事件处理
        events: {
            'click #test1': 'onClick'
        },

        // 视图初始化
        initialize: function () {
            console.log('enter initialize...');
            this.insertView('#test1', new Test1View());
            this.insertView('#test', new TestView());
            this.insertView('#test2', new Test2View());

        },
        /* 
        * 视图渲染结束处理:
        *   视图初始化之后,子视图已经插入到主视图,可以通过选择器来对渲染结束后的页面进行处理
        */
        afterRender: function() {
            // do something
            console.log('enter afterRender...');
        },


        // 视图移除处理
        cleanup: function() {
            // do something
            console.log('enter cleanup...');
        },


        onClick: function() {
            alert('click');
        }
    });

    return IndexView;
});
4. 子视图js,类似于主视图,一般会加载一些模块插件(hbs/css/i18n/text)

使用插件时,需要加上 插件名!,然后跟上模块路径。

上面主视图也插入了hbs插件,主视图hbs中定义了页面的整体框架,然后插入含有实际内容的子视图。

比如:

define(['hbs!../templates/testView.hbs'], function (template) {

  var TestView = fish.View.extend({

    manage: true,
    template: template,

  });

  return TestView;
});
5. 模块插件:

hbs/css/i18n/text

3.2 一般项目结构

    XXX ----业务代码
        XXX ---业务
            XX---具体的模块名称
                actions---请求后台
                templates---模板html
                views----视图文件
        common---公共的模块
        iamges---业务图表
        less----业务css,less样式
    frm
        fish-desktop----fish依赖
        portal---fish依赖
    i18n----国际化文件
    image----框架级图片
    LESS----用于打包后的less
    mock----模拟数据文件
        mock.js----依赖
        rules.js----模拟数据文件
    styles-----字体文件
    .gitignore----忽略文件
    index.html----主入口
    main.js----主入口js

3.3 模块语法

3.3.1 视图
  1. fish.desktop.fish.View

创建视图,例如:

var userView = fish.View.extend({
    el: false
    templace: template,

    events: {
        "click .btn": "onNew",
    },

    initialize: function() {
        //...
    },

    render: function() {
        //...
    },

    afterRender: function() {
        //...
    },

    onNew: function() {
        //...
    }
});

基本属性(参数)Config options有:

  • attributes(保留属性,视图Dom元素属性,如果 el 属性有值时,忽略该属性,下同)
  • className(保留属性)
  • tagName(保留属性)
  • id(保留属性)

  • manage

  • el 视图 Dom
  • events 视图 Dom 事件监听处理定义
  • template 视图模板函数
  • serialize 填充数据

例:

直接插入模板:

define(['hbs!../templates/test1View.hbs'], function (template) {

    var Test1View = fish.View.extend({
        template: template

    });

    return Test1View;
});

不对模板做其他处理,单纯引入hbs模块插件

数据渲染:

简单插入数据:

var AppView1 = fish.View.extend({
    manage: true,
    el: '#app-1',
    template: fish.compile('

{{message}}

'
), serialize: { message: 'Hello World' } }); new AppView1().render();

serialize 数据会填充到 template 模版里,然后渲染到 #app1 节点上, 以此来实现数据渲染

扩展有判断、循环渲染……

DOM交互:

var AppView4 = fish.View.extend({
    manage: true,
    el: '#app-4',
    template: fish.compile('<form>\
        <div class="form-group">\
            <label>Usernamelabel>\
            <input type="text" class="form-control js-username">\
        div>\
        <div class="form-group">\
            <button type="button" class="btn btn-primary">Clickbutton>\
        div>\
    form>'),

    events: {
        'click .btn': 'onClick'
    },

    onClick: function () {
        this.$('.js-username').val('Li Lei');
    }
});

对DOM元素进行处理, 点击按钮,改变输入框中的值

widget控件定义:就是之前写过的一些常用组件

Web Widget,中文译名被称作是微件,是一小块可以在任意一个基于HTML的Web页面上执行的代码,它的表现形式可能是视频,地图,新闻,小游戏等等。它的根本思想来源于代码复用,通常情况下,Widget的代码形式包含了DHTML,JavaScript以及Adobe Flash。当widget和js和在一起的时候,就需要js能控制本地的一些东西,比如说打开某个文件,修改系统时间。这就需要对js功能进行扩展。其实普通的浏览器也有这个需求,通过增加插件来支持更多的东西。

控件定义样放置在 afterRender 函数里

  • Combobox:下拉列表
  • DataPicker: 日期
  • accordion: 页签
    HTML需要按照fish规定的格式,使用panel等。

  • -
数据模型

模型提供数据变化监听


数据集合
前端路由

博客链接

  1. 当用户使用 http://10.0.0.1/about 来访问该页面时,Web 服务会接收到这个请求,然后会解析 URL 中的路径 /about,在 Web 服务的程序中,该路径对应着相应的处理逻辑,程序会把请求交给路径所对应的处理逻辑,这样就完成了一次「路由分发」,这个分发就是通过「路由」来完成的。
    路由分发,把以前后台做的事情,拿到前端来做。
    前端路由比较适合页面中只有一部分发生变化的页面, 也就是单应用, 这样可以避免每次都要向服务器获取整个页面的东西,用户体验会好些. 如果多个页面一点关系都没有,没有任何重复的地方, 完全没有必要使用路由的. 但是目前大多数网站都可以看成是单应用, 一般网页的头部尾部还有导航条都是不变的, 只是切换中间的内容,从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
  2. 在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题。

路由定义:fish 封装的前端路由

fish.Router.extend({
    routes: {
        "help": "help",    // #help
        "search/:query": "search",  // #search/kiwis
        "search/:query/p:page": "search"   // #search/kiwis/p7
    },

    help: function() {
        ...
    },

    search: function(query, page) {
        ...
    }
});

映射规则:

  • :param 它在斜线之间匹配 URL 信息
  • *splat 支持通配符配置
  • (/:optional) 可选匹配,把可选部分放到小括号里

路由使用:
当路由定义完后,需要调用 fish.history.start() 或者 fish.history.start({pushState: true}) 启动驱动 URL 路由

3.4 实际项目源码阅读

3.5 实际项目开发

你可能感兴趣的:(前端开发)