网页便签(一)

198 阅读2分钟

这是一个基于网页的简易便签APP,提供增加,删除,修改,移动,缩放等功能,操作便签实时保存数据到浏览器本地存储, 本文记录了其组件化开发的实现流程。

演示地址

介绍

blackboard.js是一个新的轻量级JavaScript MVVM项目,采用ES6 Proxy对象侦测属性变化并更新视图, 提供命名空间,组件,指令,过滤器 服务及服务注入特性。

项目地址

创建便签服务

创建便签数据模型及业务逻辑

blackboard.namespace(noteApp).service('noteService', {
    props: {
        zIndex: 0,
        notes: []
    },
    methods: {
        nextZIndex: function() {
            return ++this.zIndex;
        },
        isMaxZIndex: function(zIndex) {
            return zIndex >= this.zIndex;
        },
        create: function(notes) {
            var newNote = {
                // 内容
                content: 'new note',
                // 平面位置
                position: {
                    x: 20,
                    y: 20
                },
                // 大小
                size: {
                    width: 180,
                    height: 180
                },
                // 深度位置
                zIndex: this.nextZIndex()
            };

            notes.push(newNote);

            return newNote;
        },
        getList: function() {
            return this.notes;
        },
        load: function() {
            var self = this,
                json = localStorage.getItem('notes');
            if (json) {
                this.notes = JSON.parse(json);
                this.notes.forEach(function(note) {
                    if (note.zIndex > self.zIndex) {
                        self.zIndex = note.zIndex;
                    }
                });
            }
        },
        save: function() {
            // 保存便签
            localStorage.setItem('notes', JSON.stringify(this.getList()));
        },
        removeAll: function(notes) {
            notes.length = 0;
        },
        remove: function(notes, note) {
            var index = this.notes.indexOf(note);

            if (index !== -1) {
                notes.splice(index, 1);
            }
        }
    }
});

创建便签容器

添加容器模板

<div id="app" class="full-size flex-box flex-column">
    <!--顶部工具栏,新建,保存,清空按钮-->
    <div class="toolbar flex-box">
        <span class="title">Note</span>
        <div class="flex-box flex-element btns">
            <button class="fa fa-plus-circle btn" @click="createNote()" title="Create"></button>
            <button class="fa fa-save btn" @click="saveNote()" title="Save"></button>
            <button class="fa fa-remove btn" @click="clearNote()" title="Clear"></button>
        </div>
    </div>

    <!--便签视图,使用b-repeat指令显示多个便签-->
    <div class="flex-element relative-container">
        <note :model="note" *b-repeat="note in notes" @destroy="removeNote(note)"></note>
    </div>
</div>

创建容器模型

(function(global) {
    'use strict';
    
    global.onload = function() {
        var scope = {
            // 注入便签服务
            inject: {
                noteService: 'noteService'
            },
            props: {
                notes: []
            },
            methods: {
                // 创建便签
                createNote: function() {
                    // this.proxy.notes, 使用组件代理对象以监听属性变化
                    this.noteService.create(this.proxy.notes);
                    this.noteService.save();
                },
                // 保存便签
                saveNote: function() {
                    this.noteService.save();
                },
                // 清空便签
                clearNote: function() {
                    this.noteService.removeAll(this.proxy.notes);
                    this.noteService.save();
                },
                // 删除便签
                removeNote: function(note) {
                    this.noteService.remove(this.proxy.notes, note);
                    this.noteService.save();
                }
            },
            onInit: function() {
                // 组件初始化钩子,加载已经存在的便签
                this.noteService.load();
                this.notes = this.noteService.getList();
            }
        };

        blackboard.bootstrap('app', scope);
    };

})(window);