# refex **Repository Path**: so-better/refex ## Basic Information - **Project Name**: refex - **Description**: 一个基于Proxy的数据响应式轻量前端框架 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-10-30 - **Last Updated**: 2024-10-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### Refex是一个基于Proxy实现的轻量级MVVM框架 ##### 基本使用 ```
{{name}}
div>{{frames}}
``` ``` //引入Refex提供的方法,创建包含响应式数据对象的整个应用实例 const { proxy, useProxy, h } = Refex const app = proxy({ show:false, name:'refex', frames:['mvi-web','element-ui','iView','BootStrap'], obj:{ name:'vue', verison:3, type:'JavaScript' } }) ``` ``` //获取可操作的响应式数据对象,通过该对象可直接操作数据 const snap = useProxy(app) snap.name = 'refex是一款MVVM框架' ``` ##### 动态class ``` //class不同于其他的属性,支持动态绑定的值为对象和数组
``` ##### 数据监听 ``` //通过watch方法实现数据监听 app.watch('name',function(newValue,oldValue){ //监听name值变化,回调参数为改变后的新值和改变前的旧值 //在该方法内,this指向snap对象 }) ``` ``` //通过unwatch方法解除数据的监听 app.unwatch('name') ``` ##### 循环渲染 ``` ``` ``` ``` ``` ``` ##### 条件渲染 ```
``` ```
``` ##### 事件绑定 ``` ``` > 事件的绑定值是响应式数据,且该数据为函数,如下: ``` const app = proxy({ myEvent:function(e){ //函数内this指向snap对象 //第一个参数e永远是event对象,自带参数在后面 } }) ``` ``` ``` ``` ``` ``` ``` ##### 事件修饰符 > 事件的修饰符通过.来表示,可以多个一起使用 ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ##### show指令 ```
``` ##### 自定义指令 ``` ``` ``` //通过directive方法来自定义一个指令 app.directive('focus',{ mounted:function(el,value,modifier,exp,vnode){ el.focus() } }) ``` > directive方法第一个参数为指令名称,第二个参数是对象,表示指令的几个钩子函数,每个钩子函数中的this都指向snap对象,具体如下: ``` { beforeMount:function(value,modifier,exp,vnode){ //这里this指向snap对象 //指令所在元素渲染之前触发 }, mounted:function(el,value,modifier,exp,vnode){ //这里this指向snap对象 //指令所在元素渲染之后触发 }, beforeUpdate:function(el,value,modifier,exp,vnode){ //这里this指向snap对象 //指令所在元素更新之前触发 }, updated:function(el,value,modifier,exp,vnode){ //这里this指向snap对象 //指令所在元素更新后触发 }, beforeUnmount:function(el,value,modifier,exp,vnode){ //这里this指向snap对象 //指令所在元素移除之前触发 }, unmounted:function(value,modifier,exp,vnode){ //这里this指向snap对象 //指令所在元素移除后触发 } } ``` > 回调参数el表示指令所在元素,value表示指令表达式的值,modifier表示指令修饰符,exp表示指令表达式字符串,vnode表示指令所在虚拟节点 ``` ``` ``` //获取指令,通常用来判断指令是否存在 const d = app.directive('focus') if(d){ //存在@focus指令 } ``` ##### 自定义组件 ``` ``` ``` //通过component方法来注册一个组件 app.component('my-component',{ props:['key'], render:function(props){ //这里this指向snap对象 //props的值为{key:'refex'} //这里key属性不会直接渲染到div上,而id="el"会渲染到div上 return '
这是我的自定义组件
' } }) ``` > component方法的第一个参数表示组件名称,第二个参数表示组件参数,组件参数主要包含props和render,其中props是一个属性名称数组,表示在应用该组件时,直接写在组件上的属性是否作为render函数回调参数来使用,而不是直接渲染到实际元素上。第二个参数表示渲染函数,支持模板渲染和函数渲染,具体如下: ``` //模板渲染 render:function(props){ return `
自定义组件
` } //模板渲染就等同于在HTML中的用法,比如 render:function(props){ return `
{{name}}
` } ``` ``` //函数渲染 render:function(props){ return h('div',{ attrs:{ id:'el' }, classes:{ 'my-component':true } }) } ``` ``` //函数渲染方式必须通过返回h函数的执行结果 //h函数的第一个参数表示创建的节点名称 //h函数的第二个参数是一个对象,包含以下属性 { attrs:节点属性,如{id:'el',style:'display:block;'} classes:节点的class,支持数组、对象和字符串,如['btn','btn-primary']或者{'btn':true,'btn-primary':true}或者'btn btn-primary' directives:节点上应用的指令,是一个对象,对象的每个键名表示指令名称,键值表示指令参数(指令参数包含value和modifier两个值),如{ focus:{ value:2,modifier:'value' } } events:节点的事件集合,是一个对象,对象的每个键表示事件名称,键值表示事件处理函数,如{ click:function(){} } text:节点文本值,如果该值存在,则slots参数失效 slots:节点子元素,数组类型,里面每个元素都是h函数执行结果 if:该节点是否渲染,布尔类型 } ``` > 获取组件仍然使用component方法,如下: ``` const cmp = app.component('my-component') if(cmp){ //组件存在 } ``` > h函数中的slots参数可以使用获取到的组件来作为子元素 ``` const cmp = app.componet('my-component') app.component('my-component-container',{ props:[], render:function(props){ return h('div',{ slots:[ //通过render函数来渲染该组件,作为my-component-container组件的子组件,可以把props作为参数传递进去 cmp.render(props), cmp.render(props), cmp.render(props) ] }) } }) ``` ##### 内置component组件 > refex内置了一个名为component的组件,可以通过name的取值来转换成任意已经定义的组件 ``` ``` > 组件的props属性是一个对象,会作为render函数参数传递给具体实现的组件,如下: ``` const state = proxy({ props:{ primary:false } }) //以上component组件会转换为 ``` ##### 内置slot组件 > refex内置的slot组件用于展示组件原本内容 ``` 222 ``` ``` app.component('my-component',{ render:function(props){ return '
' } }) ``` 最终会渲染成如下: ```
222
``` > slot组件不能直接用于render函数的返回值 ``` //如下会报错 app.component('my-component',{ render:function(props){ return '' } }) ``` > slot组件也不能直接写在自定义组件之外,比如直接写在页面上 ``` //html页面上直接写,会导致报错 ``` ### 详情请参阅[refex文档](https://www.mvi-web.cn/library/30)