We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
访问 https://bowencodes.com 以获得最佳体验
Chameleon(变色龙)是滴滴最近开源的一个跨端解决方案,趁着寒假,我花了些时间学习并使用了Chameleon,本文主要是探究它强大的多态协议
当下的跨端框架层出不穷,但基本都是在框架提供的跨端能力基础上进行开发,而业务逻辑不可能跟着框架走,有时候开发者需要突破框架的限制;同时,web、小程序、native存在端上的差异,它们的需求在某些业务上可能不同,需要我们人为地做环境判断,逻辑一旦复杂,跨端数量一旦很多,代码就会变得可读性低,难以维护,这并不是我们跨端的本意
变色龙基于统一多态协议,开发者可以自由扩展api和组件,使用各端众多的开源库,不再拘囿于框架。同时,将特有代码进行隔离,避免各端互相影响,并保持逻辑连续性(优雅的跨端实现)
多态协议提供了跨端时各端底层组件与接口统一的解决方案,用户可以自己开发跨端api和组件,也可以根据需求轻松变换各端的表现,变色龙会在编译时拆分各端代码,保证各端代码的纯正性,这也是我使用变色龙感觉到最舒服的一个地方
我们可以执行cml init component,选择多态组件,输入文件名,即可快速生成多态组件模版,结构如下:
cml init component
./src/components └── xxx ├── xxx.interface ├── xxx.web.cml ├── xxx.weex.cml └── xxx.wx.cml
变色龙会提供一个最简单的多态组件模版,你可以自由填充。xxx.interface描述组件的属性和方法,剩下的文件是各端的具体实现,在多态组件中,我们可以在cml文件里任意使用对应端的功能、标签,还可以引入当前端的成熟开源库,甚至还能直接引入web端、小程序端的组件,并且变色龙会帮你检查和隔离代码,不会出现A端的代码一不小心去了B端的情况
假设现在有这样一个需求,我们需要跨端展示markdown格式的文章,首先,我们需要把markdown格式的文章转换为html:
const prism = require("prismjs"); const md = require("markdown-it")({ highlight: function(str, lang) { try { return ( prism.highlight(str, prism.languages[lang], lang) ); } catch (__) { console.log(__); } return ""; } });
很简单,在引入两个包和执行上面的代码之后,我们传入mdText执行md.render(mdText)就可以获得带代码格式的html字符串,那我们如何跨端渲染html呢?h5端似乎可以直接用v-html,但小程序端不支持这么多的标签,只能把它放在rich-text里,weex端的rich-text功能太弱,只能放span、a、img三种标签,不能承载markdown转html后的标签数量,这三端需要同时兼容,各种代码交织在一起,想想就头疼,别提更多端数了
md.render(mdText)
rich-text
span
a
img
那我们如何去实现这个功能呢,我们先查阅文档,发现变色龙还没有可以直接用的解决方案,没关系,我们可以自己写一个多态组件:
首先,创建多态组件,我命名为rich-text,它接受一个属性html,为需要渲染的html字符串
rich-text.interface文件如下:
rich-text.interface
<script cml-type="interface"> interface RichTextInterface { html: String } </script>
先看微信端,微信提供了rich-text组件,可以通过给标签加上前缀origin-拿到该端的原生标签, 我们用origin-rich-text在rich-text.wx.cml中拿到微信小程序原生的rich-text(以下代码可能有省略):
origin-
origin-rich-text
rich-text.wx.cml
<template> <origin-rich-text nodes="{{_html}}"> </origin-rich-text> </template> <script> class RichText implements RichTextInterface { props = { html: { type: String, default: '' } } computed = { _html(){ return this.html .replace(/\n/g,'<br/>') .replace(/<pre>|<\/pre>/g,''); } } } export default new RichText(); </script> <style > @import "./prism.css"; </style>
需要注意,微信的rich-text不支持pre标签,所以我们需要过滤pre标签并人为加上换行(这里只是一个示例demo,还有可能有其他不支持的标签我没注意)
pre
web端可以直接使用v-html,我这里为了演示引入web端组件,所以单独创建了一个rich-text-vue.vue文件,如下
rich-text-vue.vue
<template> <div v-html="html"> </div> </template> <script> class Index { props = { html:{ type: String, default: '' } } }; export default new Index(); </script> <style> @import "./prism.css"; </style>
这是一个纯正的vue组件,后缀也是纯正的.vue,我们可以在rich-text.web.cml中直接引用它,如下:
rich-text.web.cml
<template> <rich-text-vue html="{{html}}"> </rich-text-vue> </template> <script> class RichText implements RichTextInterface { props = { html: { type: String, default: '' } } } export default new RichText(); </script> <style > </style> <script cml-type="json"> { "base": { "usingComponents": { "rich-text-vue": "./rich-text-vue" } } } </script>
当然,我们还可以在其他端引入小程序组件等等,导入与导出,这里就不多示范了
最后是weex端,weex的rich-text接受的标签是在太少,我最后决定使用weex的web组件实现,创建rich-text-weex.vue,写入代码:
rich-text-weex.vue
<template> <div class="wrapper"> <web style="width: 730px; height: 500px" src="http://192.168.0.102:8000/cml/h5/index"> </web> </div> </template> <style scoped> .wrapper { flex-direction: column; padding: 10px; } </style> <script> module.exports = { data: { } } </script>
其中http://192.168.0.102:8000/cml/h5/index是我本机跑着的地址
http://192.168.0.102:8000/cml/h5/index
至此,h5,小程序,weex的工作都已完成,只需要引入该组件,并在页面插入一行代码:
<rich-text html="{{html}}"></rich-text>
传入html字符串,我们就能看到效果了
下图是我最后的效果图,分别是h5,小程序,weex端
这只是一个简单的例子,官网还有关于如何跨端使用echarts的例子
多态接口与多态组件类似,不过是把组件的形式换成了接口,同样,输入cml init component,选择多态接口,输入文件名xxx,会生成以下结构文件:
├── components └──xxx └── xxx.interface
为了方便说明,我写了一个跨端的storage接口,当然,变色龙有更强大的内置storage方法
新建多态接口,命名为storage,向storage.interface文件写入以下代码:
storage.interface
<script cml-type="interface"> interface StorageInterface { get(key: string): Promise; set(key: string, value: string): Promise; } </script> <script cml-type="web"> class Method implements StorageInterface { get(key) { return Promise.resolve(localStorage.getItem(key)); } set(key, value){ localStorage.setItem(key,value); return Promise.resolve(); } } export default new Method(); </script> <script cml-type="weex"> const storage = weex.requireModule('storage'); class Method implements StorageInterface { get(key) { return new Promise((resolve)=>{ storage.getItem(key, event => resolve(event.data)); }) } set(key, value){ return new Promise((resolve)=>{ storage.setItem(key, value, resolve); }) } } export default new Method(); </script> <script cml-type="wx"> class Method implements StorageInterface { get(key) { return Promise.resolve(wx.getStorageSync(key)); } set(key, value){ wx.setStorageSync(key, value); return Promise.resolve(); } } export default new Method(); </script>
我简单地实现了storage的get和set方法,因为weex端的storage是异步的,为了统一,所以我规定get和set方法的返回值为Promise,后面的具体实现就很简单了,查查文档就能写出来了
storage
get
set
Promise
然后,只用import storage from "../../components/storage/storage.interface";引入接口,就可以调用storage.get()和storage.set()来达到跨端的storage操作了
import storage from "../../components/storage/storage.interface";
storage.get()
storage.set()
多态样式则比较简单,cml文件中的style如下即可实现样式多态:
<style> .common { } @media cml-type (web) { .class1 { color: red; } } @media cml-type (weex) { .class1 { color: green; } } @media cml-type (wx,alipay,baidu) { .class1 { color: blue; } } </style>
Chameleon的统一多态协议让开发者有了更多的施展空间,我们可以在框架的基础上自由开发api和组件,在遇到个别不同端差异化实现的情况也能优雅保持代码逻辑的连续性,并有效隔绝各端代码
整个项目,可能跨端框架的功能能涵盖95%的工作,但剩下的5%才是关键,基于多态协议,我们可以优雅轻松地完成这5%的工作
当然,Chameleon还有其他强大之处,比如强大的基础库、跨多端语法检查功能、导入导出原生组件、Chameleon iOS SDK、Chameleon Android SDK等等
chameleon使用体验
官网
github
The text was updated successfully, but these errors were encountered:
No branches or pull requests
访问 https://bowencodes.com 以获得最佳体验
Chameleon(变色龙)是滴滴最近开源的一个跨端解决方案,趁着寒假,我花了些时间学习并使用了Chameleon,本文主要是探究它强大的多态协议
优势
当下的跨端框架层出不穷,但基本都是在框架提供的跨端能力基础上进行开发,而业务逻辑不可能跟着框架走,有时候开发者需要突破框架的限制;同时,web、小程序、native存在端上的差异,它们的需求在某些业务上可能不同,需要我们人为地做环境判断,逻辑一旦复杂,跨端数量一旦很多,代码就会变得可读性低,难以维护,这并不是我们跨端的本意
变色龙基于统一多态协议,开发者可以自由扩展api和组件,使用各端众多的开源库,不再拘囿于框架。同时,将特有代码进行隔离,避免各端互相影响,并保持逻辑连续性(优雅的跨端实现)
多态协议
多态协议提供了跨端时各端底层组件与接口统一的解决方案,用户可以自己开发跨端api和组件,也可以根据需求轻松变换各端的表现,变色龙会在编译时拆分各端代码,保证各端代码的纯正性,这也是我使用变色龙感觉到最舒服的一个地方
多态组件
我们可以执行
cml init component
,选择多态组件,输入文件名,即可快速生成多态组件模版,结构如下:变色龙会提供一个最简单的多态组件模版,你可以自由填充。xxx.interface描述组件的属性和方法,剩下的文件是各端的具体实现,在多态组件中,我们可以在cml文件里任意使用对应端的功能、标签,还可以引入当前端的成熟开源库,甚至还能直接引入web端、小程序端的组件,并且变色龙会帮你检查和隔离代码,不会出现A端的代码一不小心去了B端的情况
假设现在有这样一个需求,我们需要跨端展示markdown格式的文章,首先,我们需要把markdown格式的文章转换为html:
很简单,在引入两个包和执行上面的代码之后,我们传入mdText执行
md.render(mdText)
就可以获得带代码格式的html字符串,那我们如何跨端渲染html呢?h5端似乎可以直接用v-html,但小程序端不支持这么多的标签,只能把它放在rich-text
里,weex端的rich-text
功能太弱,只能放span
、a
、img
三种标签,不能承载markdown转html后的标签数量,这三端需要同时兼容,各种代码交织在一起,想想就头疼,别提更多端数了那我们如何去实现这个功能呢,我们先查阅文档,发现变色龙还没有可以直接用的解决方案,没关系,我们可以自己写一个多态组件:
首先,创建多态组件,我命名为rich-text,它接受一个属性html,为需要渲染的html字符串
rich-text.interface
文件如下:先看微信端,微信提供了rich-text组件,可以通过给标签加上前缀
origin-
拿到该端的原生标签, 我们用origin-rich-text
在rich-text.wx.cml
中拿到微信小程序原生的rich-text(以下代码可能有省略):需要注意,微信的rich-text不支持
pre
标签,所以我们需要过滤pre
标签并人为加上换行(这里只是一个示例demo,还有可能有其他不支持的标签我没注意)web端可以直接使用v-html,我这里为了演示引入web端组件,所以单独创建了一个
rich-text-vue.vue
文件,如下这是一个纯正的vue组件,后缀也是纯正的.vue,我们可以在
rich-text.web.cml
中直接引用它,如下:当然,我们还可以在其他端引入小程序组件等等,导入与导出,这里就不多示范了
最后是weex端,weex的rich-text接受的标签是在太少,我最后决定使用weex的web组件实现,创建
rich-text-weex.vue
,写入代码:其中
http://192.168.0.102:8000/cml/h5/index
是我本机跑着的地址至此,h5,小程序,weex的工作都已完成,只需要引入该组件,并在页面插入一行代码:
传入html字符串,我们就能看到效果了
下图是我最后的效果图,分别是h5,小程序,weex端
这只是一个简单的例子,官网还有关于如何跨端使用echarts的例子
多态接口
多态接口与多态组件类似,不过是把组件的形式换成了接口,同样,输入
cml init component
,选择多态接口,输入文件名xxx,会生成以下结构文件:为了方便说明,我写了一个跨端的storage接口,当然,变色龙有更强大的内置storage方法
新建多态接口,命名为storage,向
storage.interface
文件写入以下代码:我简单地实现了
storage
的get
和set
方法,因为weex端的storage是异步的,为了统一,所以我规定get
和set
方法的返回值为Promise
,后面的具体实现就很简单了,查查文档就能写出来了然后,只用
import storage from "../../components/storage/storage.interface";
引入接口,就可以调用storage.get()
和storage.set()
来达到跨端的storage操作了多态样式
多态样式则比较简单,cml文件中的style如下即可实现样式多态:
总结
Chameleon的统一多态协议让开发者有了更多的施展空间,我们可以在框架的基础上自由开发api和组件,在遇到个别不同端差异化实现的情况也能优雅保持代码逻辑的连续性,并有效隔绝各端代码
整个项目,可能跨端框架的功能能涵盖95%的工作,但剩下的5%才是关键,基于多态协议,我们可以优雅轻松地完成这5%的工作
当然,Chameleon还有其他强大之处,比如强大的基础库、跨多端语法检查功能、导入导出原生组件、Chameleon iOS SDK、Chameleon Android SDK等等
chameleon使用体验
官网
github
The text was updated successfully, but these errors were encountered: