DoAsVue-基于LXL的js插件开发框架【全网首发:支持注解编程】【因为LXL已经支持nodejs,该项目停止维护】

LLSE DoAsVue-基于LXL的js插件开发框架【全网首发:支持注解编程】【因为LXL已经支持nodejs,该项目停止维护】 1.15.52

Source of resources
Original
Copyright link
#
Language
Chinese(Simplified)
Supported version
  1. The latest version
开源万岁(允许魔改与商用,但必须注明出处:<首发平台minebbs,作者KING>)

写在前面的话:
1、咳咳,毫不低调的说,这是LXL第一款JS开发框架:呵呵:
2、
设计这个框架时一开始仿造了 Vue2 的风格,后面又融入了 Java 的一些风格,他本身是基于面向对象的方式。它支持【继承】【接口式编程】【全局引用】【切面编程】【插件互调】【注解式开发】
3、它的核心思想是把你的插件交它给进行管理,他会对你的插件进行整理。它相当于是一个容器。因此它可以实现原版js无法实现的一些功能。同时如果你 Js 功底和 Java 功底很强,你甚至可以设计出基于反射的插件。(所有的功能都是牺牲了一定性能实现,特别是面向切面编程,也不用担心,没牺牲多少)
3、在 LiteXLoader(简称LXL)的 0.5.12 版本之后,LXL嵌入LiteLoader(简称LL)内,并且改名为LiteLoaderBDS(简称LLBDS),因此如果你不懂什么是 LXL,请先了解什么是 LXL 之后在着手 DoAsVue。 LXL架构url:LXL架构 (某些地区可能无法访问)

DoAsVue与LXL关系.png


======================
下面这里是写给我自己看的,,,,
待解决:
(3)加载辅助插件的方法优化,辅助插件更多的指令
(5)尽量添加对真指令的支持,简化真指令的创建(技术有限)
(6)Math的时间间隔计算有bug,不允许出现 0000-00..格式
======================

【需求描述】
当开发复杂的插件系统时,通常会面临这样的问题:
1、要么将所有功能写入同一个插件,使得插件极其庞大复杂,少则数百行,多则上千行
2、要么将插件拆分为模块,但是非常麻烦,并且插件之间无法共享变量与配置文件
3、后期代码过多不易维护,并且还可能涉及到修改源码,破坏原本的插件
4、很多代码都是重复的,没法复用
5、LXL原版错误信息不准确
6、原版的开发方式低效不易阅读与维护

【DoAsVue优点】
1、插件整合:支持将所编写插件整合到DoAsVue.lxl.js主运行插件内,意味着你可以将大型插件系统拆分为模块进行解耦
2、支持插件之间相互调用,共享变量以及配置文件共享,意味着多个插件之间可以实现数据共享,配置文件共享,方法共享等
3、提供切面编程:支持执行前插入,执行时插入,执行返回前插入,意味着在不修改其他插件情况下对其他插件的method进行非入侵式修改,即:执行前触发执行,执行时修改参数,执行返回前修改执行结果
4、支持继承,因此可以用它实现模板式开发与插件复用,甚至还可以实现接口式开发
5、完全运行于LXL,不使用第三方库与包
6、内部封装了独有的错误栈追踪,可以很精确找到插件错误位置(除了LXL自身引发的错误外)
7、支持注解与反射使得开发更加高效与易维护,可以理解为DoAsVue就是LXL中的低配版Java
8、由于高度的封装,DoAsVue实现了统一接口管理,再结合注解与反射,可以对此轻易实现模板化开发、高低版本兼容开发。


【DoAsVue插件开发前提】

1、掌握LXL(js)插件开发
2、扎实的js基础,最好是掌握 js
3、了解切面编程、了解代理模式
4、熟悉封装与继承
5、熟悉面向对象编程
【DoAsVue执行逻辑】

1、整体执行逻辑:
* a、LXL加载DoAsVue.lxl.js
* b、DoAsVue.lxl.js递归扫描配置文件config.json指定的plugins目录下所有davue插件
* c、DoAsVue.lxl.js加载按照DoAsVue规范编写的js插件
2、DoAsVue的js插件被加载流程:

Code:
执行流程:
    0、初始化子插件,进行必要的数据搜集与整理
    1、初始化全局域,添加全局变量
    2、初始化继承
    3、创建data数据域
    4、建立require引用
    5、建立methods方法域
    6、注入注解,执行注解逻辑
    7、创建aspect切面,并插入切面
    8、建立listen监听事件
    9、注册命令
    10、执行入口main
【DoAsVue说明】
DoAsVue结构简述
JavaScript:
var plugin = {
    data(){
        return{ //数据域、属性域
 
        }
    },
    global:{
        testkey:"testvalue", //所有DoAsVue插件可访问该变量,直接使用,例如log(testkey)
    },
    extends:null, //继承,可以继承其他DoAsVue插件,只能继承一个   extends:"插件名称"
    require:{ //引用域,可以用其他DoAsVue插件
 
    },
    methods:{ //方法域,可以定义方法(函数),这里的方法可以被切面修改,带有 _ 前缀的算作私有方法
              //这里的方法可以写到methods外边,但是不会被继承,即,写到外边的也算是私有方法
              //如果外边的方法与methods内的方法名重复,会被methods内的覆盖
 
    },
    MCListen:{ //监听域,就和mc.listen一样
 
    },
    MCPlayerCmd:{ //注册玩家命令

    },
    MCConsoleCmd:{ //注册控制台命令

    },
    aspect:{ //切面域,可以对引用的插件methods进行切面修改(会影响到被切面的插件的methods正常执行)
 
    },
    main(){ //主动执行入口,一般用来初始化
          //当main返回一个函数时,例如return ()=>{ /*todo*/ } 它表示是在所有插件执行完毕main之后执行该返回函数;
         //有时候会有这种需求,比如在main调用其他插件时,但是其他插件可能这个时候并未初始化完毕,直接调用会出现数据不存在引发的undefined错误,因此需要等待他们都初始化完毕之后再执行。
    }
 
}

module.exports={
    name:"template_plugin1", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}
除了data()数据域是必要的,其他的可以不必要
当然,在1.10.22版本之后新增了对class的支持,结构也可以如下定义:
需要注意的是,框架使用的是无参构造进行对象创建,因此最好就是不要创建有参构造函数

JavaScript:
//LiteXLoader Dev Helper
/// <reference path="c:\Users\KING\.vscode\extensions\moxicat.lxldevhelper-0.1.4/Library/JS/Api.js" />
//新增对 class 的支持,目的就是为了更好的使用继承。因此你可以在这里使用 require导入其他的class,然后继承
//就像平常一样使用class
//例如 let yourclass = require (你的class路径),然后继承你的class即可

var plugin = class Plugin{
    data(){
        return{
 
        }
    };
    global={
        testkey:"testvalue",
    };
    extends=null;
    require={
 
    };
    methods={
 
    };
    MCListen={
 
    };
    MCPlayerCmd={

    };
    MCConsoleCmd={

    };
    aspect={
 
    };
    main(){
        this.print("DoAsVue启动  \\ \\ \\\\q( 'ω' )p// / /")
    }
}

//导出规范
module.exports={
    name : "classtemp", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin : plugin //导出当前的class
}

1、DoAsVue结构插件模板如下:
"template_plugin1.DAVue.js"举例

JavaScript:
//LiteXLoader Dev Helper
/// <reference path="c:\Users\KING\.vscode\extensions\moxicat.lxldevhelper-0.1.4/Library/JS/Api.js" />

/**
 执行流程:
    1、初始化全局域
    2、执行继承初始化
    3、创建data数据域
    4、建立require引用
    5、建立methods方法域
    6、创建aspect切面,并插入切面
    7、建立listen监听事件
    8、注册命令
    9、执行入口main
 */
var plugin = {
    data(){
        return{
            name:"template plugin 1",//任意的数据
        }
        //定义数据域
        //用法,直接在以下的每个区域this.XXX即可使用,例如 this.name
    },
    require:{
        //引用域
        //引用别的模块
        // plugin1:plugin1,
        // plugin2:plugin2,
        // plugin3:plugin3,
        // ....
        //用法,直接在以下的每个区域this.plugin1即可使用另一个插件
    },
    methods:{
        //自定义方法域
        //fun:(paramater){}
        //用法,直接在以下的每个区域this.fun(xxx)即可使用,例如this.add(123,456)
 
        show:function(){
            log("这里是 "+this.name+" 的函数show()")
        },
        add(num1,num2){
            return num1+num2;
        }
    },
    MCListen:{
        //监听域
        //监听事件区,即mc.listen()
        //用法:例如:onMove:(player){}
    },
    MCPlayerCmd:{ //注册玩家命令,详情请查看template_plugin2.DAVue.js
 
    },
    MCConsoleCmd:{ //注册控制台命令,详情请查看template_plugin2.DAVue.js
 
    },
    aspect:{
        //切面域
        //如何“切开”其他的plugin请查看template_plugin2.js
        //支持:执行前,执行时,执行完毕返回前
        // 插件名称:{ //详情查看template_plugin2.DAVue.js
        //     before:{
        //         //todo
        //     },
        //     beforeRun:{
        //         //todo
        //     },
        //     beforeReturn:{
        //         //todo
        //     }
        // }
    },
    main(){
        //主动执行的入口,即在当前插件一切准备就绪之后主动执行
        //只能执行methods内的方法
        log("\n--------"+this.name+" main--------")
        this.show()
        var result = this.add(1000,2000);
        log("1000+2000结果是:"+result);//这里结果是6000,因为被template_plugin2切面修改了
        log("--------"+this.name+" main--------\n")
    }
 
}
//导出规范
module.exports={
    name:"template_plugin1", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}
//++++++++++++++++++++++++++++++++//
//插件模块之间协调与调用请查看template_plugin2.js
//++++++++++++++++++++++++++++++++//

"template_plugin2.DAVue.js"举例,它将引用上面的"template_plugin1.DAVue.js"
JavaScript:
//LiteXLoader Dev Helper
/// <reference path="c:\Users\KING\.vscode\extensions\moxicat.lxldevhelper-0.1.4/Library/JS/Api.js" />
var plugin = {
    data(){
        return{
            name:"template plugin 2",//自定义数据data
        }
    },
    require:{
        plugins1:"template_plugin1" //引用template_plugin1插件
    },
    methods:{
        fun:function(){
            log("这里是:"+this.name)
            log("在template_plugin 2里执行template_plugin 1的函数")
            this.plugins1.show();//使用别的plugins方法
            log("获取到 "+this.require.plugins1+" 的data数据:"+this.plugins1.name);//使用别的plugins数据
        }
    },
    MCListen:{
        onJump:function(player){
            log("当前执行监听跳跃事件的插件是:"+this.name)
            log(player.realName+" 跳了一下")
        }
    },
    MCPlayerCmd:{ //注册玩家命令
        hello:{ //名称
            cmd:"hello",//注册的命令
            permission:0, //权限等级
            description:"说hello", //命令说明
            event:function(player,args){ //执行的函数
                player.tell("玩家你好你好")
            }
        }
    },
    MCConsoleCmd:{ //注册控制台命令
        consoleHello:{
            cmd:"console hello",
            description:"你好",
            event:function(args){
                log("控制台你好")
            }
        }
    },
    aspect:{
        /**
            所谓切面,即在不直接修改其他插件的method源码前提下修改这个method
         */

        //注:只能对其他插件的methods进行切入与修改
        //支持多重切入
        //但是至于同一个插件被多个插件进行切面的优先等级,理论上是取决于被DoAsVue.lxl.js加载的顺序(File.getFilesList)
        plugins1:{
            before:{
                //这个表示在plugins1插件模块执行add()方法之前先执行当前方法
                add:function(){
                    log(this.require.plugins1+" 执行add前插入了一个函数")
                }
            },
            beforeRun:{
                //这个表示在plugins插件模块执行add()时,拦截他的传入参数,并允许修改
                add:function(...args){ //这里也可以换成  add:function(num1,num2),返回时需要返回数组[num1,num2]
                    //args:传入show的数据
                    log(this.require.plugins1+" 执行add时,接收到的参数:"+args)
                    args[1]=5000;
                    log("现在修改为: "+args)
                    return args;
                    //切记要返回参数,否则被切面的函数会得不到参数
                }
            },
            beforeReturn:{
                //这个表示在plugins插件模块执行add()完毕之后,即将要返回结果之前,拦截他的返回结果,通过修改result,可以修改返回结果
                add:function(result){
                    //result:执行完毕之后的结果
                    log(this.require.plugins1+" 执行add返回前,结果应该是"+result+",但是现在修改为6666")
                    result=6666;
 
                    //add返回的数据
                    return result;
                }
            }
        }
    },
    main(){
        log("\n--------"+this.name+" main--------")
        this.fun()
        log("--------"+this.name+" main--------\n")
    },
}
//导出规范
module.exports={
    name:"template_plugin2",
    plugin:plugin
}

以上两个插件运行结果:
DuasVue插件运行结果.png


上面这个样例使用的是【aspect】实现,但是由于篇幅原因,这里不详细展开说


################################################
详细说明:

【继承功能】
extends:DoAsVue规范插件允许继承功能,即插件 A 可以继承插件 B 的 date属性 与 methods方法,可以达到继承与复用的逻辑
例如 A.DoAsVue.js 继承了 B.DoAsVue.js ,则 B 会拷贝 data 与 methods 给 A,这是副本拷贝,A 改变不会影响到 B,请放心。
说明:
. 1、如果子插件 A 继承父插件 B,但是又重写了父插件 B 的方法或者属性值,那么不会影响到父插件 B,只会影响到自己,例如 A 继承了 B,B有一个m方法,因此A也会有一个m方法,和B的m方法一模一样。但是如果你重写了该方法,那么只会影响到 A 的 m ,不会影响 B 的 m。
. 2、如果 B 的方法被其他插件切面修改,不会影响到子插件 A 进行继承原版功能。即切面不影响继承。
. 3、如果 B 的 m 方法使用了一个在 B 之外定义的全局变量,会影响到 A 继承的 m 方法,即当 B 的 m 方法修改了这个全局变量,也会影响到 A 的 m 方法内的全局变量数值。
4、私有属性与方法:凡是以"_"开头的属性或方法都属于私有的,不会继承给子插件
5、访问控制(详情查看底下的修饰符前缀)
用法:直接 extends:"父插件名称" 即可

JavaScript:
var plugin = {
    data(){
        return{
           obj:{
              a:1,
              b:2
           }
        }
    },
    extends:null,
    methods:{
        m(){
            log("这里是父类")
        }
    },
    main(){
        this.m();
    }
}

//导出规范
module.exports={
    name:"B", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}

//-------------------------------------------------------------------------------


var plugin = {
    data(){
        return{
 
        }
    },
    extends:"B",
    methods:{
 
    },
    main(){
        log("继承B的obj:")
        log(this.obj)
        log("执行继承于父插件的m方法:")
        this.m();
    }
}

//导出规范
module.exports={
    name:"A", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}

【全局域】
global:
1、DoAsVue规范插件允许定义全局变量,在所有DoAsVue插件内均可直接调用,由于它相当于全局静态变量(也可以是function),因此它不支持将和this相关的变量赋予他,仅允许使用常量或者其他变量;
2、它可以定义全局变量,因为利用的是全局this进行添加,因此它甚至可以重写全局已经存在的,例如log,mc,logger等
3、用法:

JavaScript:
global:{
    key1:value1,
    key2:value2,
    ....
}
然后在任何DAVue插件内直接使用 key1或key2 直接使用该变量

【引用域】
require:
在插件内的require里可以填写引用的其他DAVue插件,例如
JavaScript:
require:{
      otherPlugin : "otherPlugin"
}
之后可以通过this.otherPlugin.xxx来调用被引用对象的methods。
在最新版本中(1.12.25之后)已经屏蔽了直接访问data内的属性值,但是DAVue插件会自动对data内的所有属性值添加set与get方法,例如otherPlugin中如果data里有一个叫做value的属性值,则require使用这个value的方法为:
JavaScript:
      this.otherPlugin.getValue();
      this.otherPlugin.setValue(newValue);
      //需要注意的是,如果otherPlugin本身就存在set与get方法,则不会自动添加

【修饰符前缀】

修饰符前缀:即在data的属性值或methods方法前面添加前缀可以设置控制访问权限
private__:仅插件自身可直接调用,其他不能调用
protection__:插件自身、继承的子类直接调用,其他不能调用
无前缀:插件自身、继承的子类、其他插件引用均可直接调用

注:
1、在旧版本里有一个规定," _ " 前缀的方法用法与 private__ 一致,但是为了兼容旧版本保留了该规定,但是未来会逐渐删除该规定。
2、注意 private__ 与 protection__ 是两个下划线
JavaScript:
var plugin = {
    data(){
        return{
           private__value1:"abc", //仅自身可以访问
           protection__value1:"abc", //仅自身和子插件可以访问
        }
    },
    extends:null,
    methods:{
        private__Fun(){
 
        },
        protection__Fun(){
 
        },
    },
    main(){
 
    }
}

//导出规范
module.exports={
    name:"Temp", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}


【注解annotation与反射reflect】
在1.15.43版本之后,DoAsVue支持注解与反射开发,就像Java的效果一样(只能针对method进行注解)
之后在1.15.48之后支持了元注解,旧版本的注解方式已经被隐藏,感兴趣的小伙伴可以去【plugins\DoAsVue_LXL\KING\DoAsVue\plugins\_Demos\_reflectAndAnnotationDemo】下查看
现在完全采取元注解的方式来实现自定义注解。
由于”自定义注解“功能强大,(与aspect一样,也是采用了代理的方式实现的),因此它可以完全代替aspect与旧版的注解的开发方式了(但是为了兼容旧版本,依旧保留了旧版本的规范,同时需要注意,aspect的优先级大于注解)
如代码:
如何自定义注解一个注解
步骤1、继承“BaseAnnotationOperator”
步骤2、使用 @annotation 对一个 fun(method,methodName,annotationInfo,module,...args) 格式的方法进行标注
步骤3、编写方法内容
步骤4、@fun注解完成

JavaScript:
var plugin = {
    data(){
        return{}
    },
    global:{},
    extends:"BaseAnnotationOperator",
    require:{},
    methods:{
        //参数必须为整数的注解
        //用法 @argMustBeInteger(argsIndex)
        //argsIndex:参数下标,如果不填,默认所有参数都必须是整数
        argMustBeInteger(method,methodName,annotationInfo,module,argIndex){
            /**
             * @annotation
             */
 
            //使用元注解将 argMustBeInteger 标记为一个注解
            /**
             * 参数前面 method,methodName,annotationInfo,module 这几个是固定的
             * method:是被注解标注的 函数 本身
             * methodName:函数 的真实名称
             * annotationInfo:函数的所有注解信息
             * module:这个函数所在的子插件本身
             *
             *
             * argIndex:这个是注解传入的参数
             * 例如 @argMustBeInteger (1) 表示下标为 1 的参数必须是整数
             * 注:注解可以传入多个参数,我这里只是传入一个举例而已,
             * 它的原型是 (method,methodName,annotationInfo,module,...args)
             */


            //返回一个代理方法
            return function(...args){
                //当不填写参数下标时,默认检查所有参数
                if(argIndex == null){
                    //遍历所有参数
                    for(let index in args){
                        if(args[index] == null ||
                            typeof(args[index]) != "number" ||
                            Math.round(args[index])!= args[index]){
      
                                throw Error(annotationInfo["argsName"][index]+" must be an integer")
                        }
                    }
                }else if(args!=null && args.length > argIndex){
                    //如果填写了参数下标,就只检查特定参数
                    if(args[argIndex] == null ||
                        typeof(args[argIndex]) != "number" ||
                        Math.round(args[argIndex])!= args[argIndex]){
  
                            throw Error(annotationInfo["argsName"][argIndex]+" must be an integer")
                    }
                }
                //执行
                return method(...args);
            }
        }
    },
    MCListen:{},
    MCPlayerCmd:{},
    MCConsoleCmd:{},
    aspect:{},
    main(){}
}

//导出规范
module.exports={
    name:"AnnotationLib", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}


如何使用自定义注解:在任意一个method内使用即可
JavaScript:
add(num1,num2,num3){
    /**
     * @argMustBeInteger (1)
     */

     return num1+ num2 + num3;
},

JavaScript:
this.print(this.add(1.2, 2.2 ,5.8)) //会报错,因为注解要求了第二个(下标为1)的参数必须是整数

this.print(this.add(1.2, 2 ,5.8)) //不报错,会正常打印 9

@argMustBeInteger 注解已经添加到了注解库,现在可以直接使用了,在不久之后,我会逐步完善这个注解库,有兴趣的小伙伴也可以提出建议
当参数不是整数时会直接报错(当然,你也可以根据demo,写一个不一定非得报错的注解,我这里只是举例)
注:
1、所有自定义注解的子插件的必须继承 ” BaseAnnotationOperator
2、注解格式为:
JavaScript:
        fun(){
            /**
             * @annotation1
             * @annotation2()
             * @annotation3 ()
             * @annotation4("value1",123,new Date())
             * @annotation5 ("value1",123,new Date())
             * @annotation6 ("value1",null)
             */

            //todo 你的代码在必须注解之后
        }
//1、注解必须在函数内部的头部
//2、与上面的格式相仿
//3、不支持在注解后面添加解释,例如    * @annotation1 //这是注解1


【@Bean与@Autowired】
这个是我自己仿造 Spring IOC 做的一个小案例,利用注解实现的自动注入bean
源码在 DoAsVue源码附件
JavaScript:
// MyBeanFactory.DAVue.js
var plugin = {
    data(){
        return{}
    },
    extends:null,
    methods:{
        setNumBean(){
            /**
             * @Bean ("myNum")
             */
            return 123;
        },
        setObjBean(){
            /**
             * @Bean ("myObj")
             */
            return {
                a:999,
                b:"自动注入"
            };
        },
    },
    main(){}
}

//导出规范
module.exports={
    name:"MyBeanFactory", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}

JavaScript:
// temp.DAVue.js
var plugin = {
    data(){
        return{
            num : null,
            obj : null
        }
    },
    extends:null,
    methods:{
        setValue(num,obj){
            /**
             * @Autowired (["myNum","myObj"],true)
             */

            this.num = num;
            this.obj = obj;
        }
    },
    main(){
        this.print(this.value);
        this.printObject(this.obj)
    }
}

//导出规范
module.exports={
    name:"temp", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}

执行结果:

注入.png





【自动对外暴露接口与davue指令】
DoAsVue会自动对子插件添加对外暴露接口,方便其他非davue的第三方插件进行调用
JavaScript:
var plugin = {
    data(){
        return{}
    },
    extends:null,
    methods:{
        fun(arg1,arg2){
 
        },
    },
    main(){}
}

//导出规范
module.exports={
    name:"Temp", //表示这个插件的名字,用于被其他插件引用时的名字
    plugin:plugin//当前导出的创建对象
}
JavaScript:
      在其他插件需要调用该子插件的fun(args),只需要执行:
      mc.runcmdEx("davue execute Temp fun arg1 arg2")
该暴露接口规则遵循require规则,即被修饰符前缀限制的依旧无法访问,依旧可以通过get、set来访问子插件的data属性
需要注意的是,这些接口仅允许调用,由于LXL与bds的运行机制原因,暂时无法返回调用结果


关于davue命令:
Q1Y8REHS1T2}O4P~KX1I702.png

最新指令详情请前往控制台输入 davue

【其他说明】
1、DoAsVue插件内直接使用this.logger(msg,type)即可使用日志;type: info/warning/error/debug/fatal
2、对于 A 继承 C,B 继承 C,则C可以通过this.children获取继承的子类列表,而 A 和 B 可以通过this.super拿到父类。
3、DoAsVue不会扫描带有 _ 开头的文件夹,以及js文件,因为以 _ 开头的 js 文件或者文件夹都表示废弃(可以用来装垃圾。。。。)
4、由于所有插件继承BaseObject,因此可以快速打印信息,使用 this.print(msg) 即可,强烈建议不要使用 log 。另外还提供了 this.printObject(obj)可以打印 object 对象(都会记录到日志文件,供维护查看)
5、所有的DoAsVue子插件均可以通过this.self拿到自身的属性,比如自身文件路径,插件名称,被其他插件require的情况。详情使用this.printObject(this.self)查看




【用法】
1、解压到plugins下,解压之后会得有一个DoAsVue.lxl.js的主运行插件,他是负责整合与运行符合DoAsVue规范的插件,把它放在plugins目录下(解压之后有 DoAsVue.lxl.js文件 以及 KING文件夹)
2、在他被第一次运行时会在/plugins/KING/DoAsVue/下生成config.json,里面默认在/plugins/KING/DoAsVue/plugins/下存放所有的DoAsVue规范插件,因为是递归扫描该文件夹,所以你可以在这个目录下进行插件分类存放,便于后期维护。例如你的库相关插件可以放在该目录下的 lib 下
3、开发符合DoAsVue规范的插件,并放到配置文件所指定的目录下这个目录不能是/plugins下,切记,因为他不是一个LXL插件),这个目录默认是/plugins/KING/DoAsVue/plugins/
4、开服


简而言之:
1、下载之后解压到plugins下
2、编写好你自己的DoAsVue插件(规范都在上面有说明,不会的可以找我)
3、把你的DoAsVue插件放到 /plugins/KING/DoAsVue/plugins/ 下
4、开服



【附赠的插件说明】
在./plugins/KING/DoAsVue/plugins/lib/内,DoAsVue子插件可以直接调用
1、【Lib_MathCal】
这是一个带有数学公式的库,目前还在扩充
2、【DataBuffer】
这是一个全局数据缓存池,用于运行时存储缓存数据,相当于Map全局变量
3、【ObjectHelper】
这是一个用于js的object操作的常用辅助库插件
4、【StringHelper】
这是一个用于 js 的字符串操作的常用辅助库插件
5、【Nbt_PlayerAbilities】
这是一个操作玩家权限的辅助库插件,相当于修改游戏暂停键内那些权限:1建造权 、2破坏权、3使用开关、4打开容器 、5攻击玩家 、6攻击生物(不支持修改 传送权 与 命令使用权);不同于事件拦截,它基于修改nbt实现的
6、【SidebarHelper】
这是一个可以很方便快且捷定制侧边栏的辅助插件,用法在插件底部有说明
7、【NBTHelper】
这是一个可以快速将nbt/snbt转jsobj并且还能自动还原为nbt/snbt的nbt助手,详情用法在该插件底部
JavaScript:
        //快速修改玩家血量举例:
        let playerNbt_jsObjNbt = this.NBTHelper.getJsObjNbt(players[0].getNbt())
        let Attributes = playerNbt_jsObjNbt.Attributes;
        for(let i in Attributes){
            let attribute = Attributes[i];
            if(attribute.Name=="minecraft:health"){
                playerNbt_jsObjNbt.Attributes[i].Current = 19; //修改血量
                players[0].setNbt(playerNbt_jsObjNbt.getNbt()); //写入数据
                break;
            }
        }

        //--------------------------------------------//
            // 快速制作 锋利32k 钻石剑
            let ItemSNBT  = `{"Count":1b,"Damage":0s,"Name":"minecraft:diamond_sword","WasPickedUp":0b,"tag":{"Damage":0,"RepairCost":3,"display":{"Name":"钻石剑-自定义名字"},"ench":[{"id":17s,"lvl":3s},{"id":9s,"lvl":5s}]}}`;
            let item_jsObjNbt = this.NBTHelper.getJsObjNbt(ItemSNBT)
            let item = mc.newItem(item_jsObjNbt.Name,item_jsObjNbt.Count);
            item_jsObjNbt.tag.ench[1].lvl=32767; //直接修改为32k
            item.setNbt(item_jsObjNbt.getNbt());

        //如此便捷的nbt操作,心动了吗?
8、【EnchantHelper】
这是一个用于附魔辅助的插件库,具备标准附魔查询,违规附魔检测等功能。详情查看lib下的EnchantHelper.DAVue.js
9、【AnnotationLib】
这是一个注解库,你直接拿来即用,从而减少无用代码的编写。开发就是把你的有限的精力放在重要的业务上,而不是写代码本身。这个注解库在逐步完善中


【写在后面的话】
问:这个到底是什么?
答:这个是一个提供将大型插件拆分为模块的插件框架,即运行插件的插件
问:我为什么非得用他开发插件,之前的开发不好吗?
答:如果是简单的功能性插件,您可以按照自己的开发习惯,但是如果您开发的插件系统功能比较多而杂乱,我推荐您使用它(DoAsVue),我只是提供了另一种开发规范与思路
问:他和一般的插件开发有什么区别?
答:区别就是他提供了插件分割思路,与一般的单个的插件不一样,它仿造VueJs与Java的风格与方式,把各个功能和数据进行拆分与整合,按照LXL提供的接口正常开发,它允许每个被加载的插件相互调用,数据共享,以及配置文件共享(有效保证多个插件的对同一个变量或者配置文件进行正确读写操作)。


设计不易,请多多支持,给自己点个赞
:点赞:
Author
KING
Price
999,999金粒
Downloads
54
Views
4,397
First release
Last update
Rating
5.00 star(s) 4 ratings

More resources from KING

Share this resource

Latest updates

  1. 1.19bug修复

    【1】适配1.19潜行疾性附魔检测 {1.15.52}
  2. 修复算法与逻辑bug

    1、修复aspect与annotation对require引用的method代理失效 {1.15.49} 2、新增 "@argsNotNull" 注解...
  3. 修复3个bug,新增元注解【主要】

    【1】obj字符串打印问题 {1.15.45} 【2】Math排序算法问题 {1.15.46} 【3】注解解析算法错误问题 {1.15.47} 【4】新增元注解,支持快速搭建以注解为核心的插件...

Latest reviews

爱了???
KING
KING
嘿嘿嘿,由于工作太忙了,对于框架新特性更新可能没那么及时了,如果发现什么bug啥的一定要告诉我,这个框架我还在维护。另外,LXL支持nodejs,其实你还可以通过nodejs写插件,也很方便
怎么安装框架哇?
KING
KING
你是要做插件开发吗,LL很快就支持nodejs了,这个框架对新手不是很友好,你还想要安装再告诉我
当我正苦恼于这一些复用功能问题的时候,我幸运的碰到了这个插件!
KING
KING
哈哈哈,如果有任何bug,麻烦也告诉我,目前还在编写阶段,还有很多不完美的地方
前端开发已经内卷到这里了吗啊哈哈哈
KING
KING
哈哈哈哈,使劲卷,在未开发的领域使劲卷