Skip to content

Commit

Permalink
Merge pull request #38 from ecomfe/feature/html
Browse files Browse the repository at this point in the history
Feature/html
  • Loading branch information
wuhy authored Feb 25, 2019
2 parents 6b43d6f + 750e29b commit 071554d
Show file tree
Hide file tree
Showing 20 changed files with 354 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

* [v-model 支持](template/v-model.md)

* [v-html 支持](template/v-html.md)

* 组件

* [开发模式](component/sfc.md)
Expand Down
3 changes: 2 additions & 1 deletion docs/build/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

* `data`: 支持 `vue` 数据操作方式 及 `computed`
* `model`: 提供 `v-model` 支持 (要求:`okam-build: 0.4.11`, `okam-core: 0.4.8`)
* `vhtml`: 提供 `v-html` 支持 (要求:`okam-build: 0.4.22`)
* `watch`: 提供 `watch` 属性 和 `$watch` API 支持,依赖 `data`
* `broadcast`: 支持广播事件
* `ref`: 允许模板指定 `ref` 属性,组件实例 `$refs` 获取引用,类似 Vue
Expand All @@ -46,7 +47,7 @@

```javascript
{
framework: ['data', 'watch', 'model', 'broadcast', 'ref', 'redux', 'behavior', 'filter']
framework: ['data', 'watch', 'model', 'vhtml', 'broadcast', 'ref', 'redux', 'behavior', 'filter']
}
```

Expand Down
102 changes: 102 additions & 0 deletions docs/template/v-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# v-html

> `okam``okam-core: 0.4.22` 版本开始支持
默认不开启,需在配置项中,配置 `v-html` 支持


``` base.config.js
{
framework: [
// ...
'vhtml'
// ...
]
}
```

## 支持项

|平台|百度|微信|支付宝|头条|快应用|
|---|---|---|---|---|
|---|||||x|
|---|nodes/string|nodes/string|nodes|nodes/string|x|

> 1.指令为 `v-html`,而不是像基础指令一样为 `html`,这样是以防止与原生或用户属性冲突;<br>
2.想要 让所有指令保证统一 推荐开启 `v-` 指令支持, [详见](template/vueSyntax.md);


## v-html 实现原理

原生 `rich-text` 的封装,`v-html` 是其的一个语法糖,其对应的取值依赖原生, 因此对于的标签、属性及事件限制都与原生对齐

!> 原生 `rich-text` 受限的 `v-html` 同样受限
!> 支付宝 `rich-text` 不支持 `string` 类型
!> nodes 不推荐使用 String 类型,性能会有所下降
!> 其他更多限制请查看 原生 `rich-text`限制

## 多平台 v-html 使用
* 第一步:在 `base.config.js` 配置了 `vhtml` 支持;

``` base.config.js
{
framework: [
// ...
'vhtml'
// ...
]
}
```

* 第二步:如果需要支持支付宝平台, `npm install mini-html-parser2 --save`
``` ant.config.js
{
api: {
htmlToNodes: 'mini-html-parser2'
}
}
```

* 第三步:多平台支持

``` pages/index.vue
<view class="sub-title">v-html 多平台 arrayData 支持</view>
<div v-html="arrayNodes"></div>
<view class="sub-title">v-html 多平台 string 支持</view>
<div v-html="stringNodes"></div>
let str = '<div class="desc">div 标签</div>';
let arr = [{
name: 'div',
attrs: {
class: 'test_div_class',
style: 'color: green;'
},
children: [{
type: 'text',
text: 'Hello&nbsp;World! This is a text node.'
}]
}];
export default {
data: {
arrayNodes: arr,
stringNodes: process.env.APP_TYPE === 'ant' ? [] : str
},
onLoad() {
if (process.env.APP_TYPE === 'ant') {
// 对应 api 配置项
this.$api.htmlToNodes(str, (err, nodes) => {
if (!err) {
this.stringNodes = nodes;
}
});
}
}
}
```

* 注意:
此处支付宝小程序提供的 `mini-html-parser2` 部分情况可支持跨平台的 `nodes` 转换,酌情选择,如果想多平台在`rich-text``nodes` 类型 则将 第二步的配置项加在 `base.config.js` 配置项中,将第三步的环境判断去掉
1 change: 1 addition & 0 deletions packages/okam-build/example/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"license": "ISC",
"dependencies": {
"lodash": "^4.17.10",
"mini-html-parser2": "^0.1.0",
"moment": "^2.22.2",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
Expand Down
4 changes: 4 additions & 0 deletions packages/okam-build/example/base/scripts/ant.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ module.exports = merge({}, require('./base.config'), {
}
},

api: {
htmlToNodes: 'mini-html-parser2'
},

dev: {
// processors: {
// postcss: {
Expand Down
1 change: 1 addition & 0 deletions packages/okam-build/example/base/scripts/base.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ module.exports = {
'data',
'watch',
'model',
'vhtml',
['behavior', '{useNativeBehavior: true}'],
'broadcast',
'redux',
Expand Down
1 change: 1 addition & 0 deletions packages/okam-build/example/base/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default {
'pages/data/array',
'pages/data/watch',
'pages/data/model',
'pages/data/vhtml',
'pages/todos/todoList',
'pages/todos/counter',
'pages/behavior/index',
Expand Down
4 changes: 2 additions & 2 deletions packages/okam-build/example/base/src/pages/data/model.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<view class="data-watch-wrap">
<view class="data-model-wrap">
<view class="example-item">
<view class="sub-title">不支持内容</view>
<view>不支持 mode 指令, inputVal: {{inputVal}}</view>
Expand Down Expand Up @@ -207,7 +207,7 @@ export default {
</script>

<style lang="stylus">
.data-watch-wrap
.data-model-wrap
position: relative
padding: 20px
box-sizing: border-box
Expand Down
123 changes: 123 additions & 0 deletions packages/okam-build/example/base/src/pages/data/vhtml.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<template>
<view class="data-html-wrap">
<view class="example-item">
<view class="sub-title">原生 rich-text 支持</view>
<rich-text :nodes="divTag">inner</rich-text>
<rich-text :nodes="aTag" @click="handle"></rich-text>
<rich-text :nodes="viewTag"></rich-text>
<rich-text :nodes="imgTag" @click="handle"></rich-text>
<rich-text :nodes="text"></rich-text>
<ant-env>
<view>支付宝不支持 string 类型</view>
</ant-env>
</view>
<view class="example-item">
<view class="sub-title">v-html 支持</view>
<div v-html="divTag">inner</div>
<view v-html="divTag"></view>
<view v-html="aTag" @click="handle"></view>
<view v-html="viewTag"></view>
<view v-html="imgTag" @click="handle"></view>
<view v-html="text"></view>
<ant-env>
<view>支付宝不支持 string 类型</view>
</ant-env>
</view>
<view class="example-item">
<view class="sub-title">v-html 多平台 arrayData 支持</view>
<div v-html="arrayTag"></div>

<view class="sub-title">v-html 多平台 string 支持</view>
<div v-html="nodes"></div>
</view>
</view>
</template>

<script>
import ModelComponent from '../../components/ModelComponent';
import SpModelComponent from '../../components/SpModelComponent';
let htmlData = {
divTag: '<div class="desc">div 标签</div>',
aTag: '<a class="link" href="www.baidu.com">a 百度</a><div>div 标签</div>',
viewTag: '<view class="desc">view 标签</view>',
imgTag: '<img class="desc" src="https://b.bdstatic.com/searchbox/icms/other/img/ico-share.png" /> img 标签',
text: '文本'
};
export default {
config: {
title: 'v-html支持'
},
components: {
},
data: {
divTag: htmlData.divTag,
aTag: htmlData.aTag,
viewTag: htmlData.viewTag,
imgTag: htmlData.imgTag,
text: htmlData.text,
arrayTag: [{
name: 'div',
attrs: {
class: 'test_div_class',
style: 'color: green;'
},
children: [{
type: 'text',
text: 'Hello&nbsp;World! This is a text node.'
}]
}],
nodes: process.env.APP_TYPE === 'ant' ? [] : htmlData.divTag
},
onLoad() {
if (process.env.APP_TYPE === 'ant') {
this.$api.htmlToNodes(htmlData.divTag, (err, nodes) => {
if (!err) {
this.setData({nodes});
// this.nodes = nodes;
}
});
}
},
methods: {
handle(evt) {
console.log(evt);
}
}
}
</script>

<style lang="stylus">
.data-html-wrap
position: relative
padding: 20px
box-sizing: border-box
background: #ccc
.sub-title
font-size: 28px
text-align: center
background: #e0dede
margin-bottom: 10px
.example-item
padding: 10px 15px
margin: 20px 0
background: #fff
.disabled
color: #ccc
.desc
color: #ff4949
.link
color: #3c76ff
.div
color: #277524
</style>
4 changes: 4 additions & 0 deletions packages/okam-build/example/base/src/pages/home/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export default {
{
subName: 'v-model属性',
path: 'data/model',
},
{
subName: 'v-html 支持',
path: 'data/vhtml'
}
]
},
Expand Down
4 changes: 4 additions & 0 deletions packages/okam-build/lib/build/BuildManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,10 @@ class BuildManager extends EventEmitter {
return this.isEnableFrameworkExtension('model');
}

isEnableVHtmlSupport() {
return this.isEnableFrameworkExtension('vhtml');
}

getProcessFileCount() {
return this.files ? this.files.length : 0;
}
Expand Down
3 changes: 3 additions & 0 deletions packages/okam-build/lib/framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ const FRAMEWORK_EXTEND_PATH = {
'ant': 'extend/ref/ant/index',
'quick': 'extend/ref/quick/index'
},
vhtml: {
'default': true
},
filter: {
wx: true,
tt: true,
Expand Down
5 changes: 5 additions & 0 deletions packages/okam-build/lib/processor/helper/init-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const BUILTIN_PLUGINS = {
model: getModelSyntaxPlugin,
tagTransform: path.join(PLUGIN_BASE_NAME, 'tag-transform-plugin'),
vuePrefix: path.join(PLUGIN_BASE_NAME, 'vue-prefix-plugin'),
vhtml: path.join(PLUGIN_BASE_NAME, 'v-html-plugin'),
ref: {
'quick': [
REF_PLUGIN_PATH, {useId: true}
Expand Down Expand Up @@ -217,6 +218,10 @@ function initViewTransformOptions(file, processOpts, buildManager, isNativeView)
plugins = normalizeViewPlugins(plugins, appType);
let isSupportRef = buildManager.isEnableRefSupport();
isSupportRef && addBuiltinPlugin('ref', appType, plugins);

let isSupportVHtml = buildManager.isEnableVHtmlSupport();
isSupportVHtml && addBuiltinPlugin('vhtml', appType, plugins);

addBuiltinPlugin('resource', appType, plugins, true);

processOpts.plugins = plugins;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @file v-html
* @author [email protected]
*/

'use strict';

const {createSyntaxPlugin} = require('./helper');

const propName = 'nodes';

function transfromVHtml(attrs, name, tplOpts, opts, element) {
const {logger, file, appType} = tplOpts;

if (appType === 'quick') {
logger.warn('not support v-html in quick env');
return;
}

let vhtmlValue = attrs['v-html'];
if (!vhtmlValue) {
return;
}

if (attrs[propName]) {
logger.warn(
`${file.path} template attribute 「v-html="${attrs[name]}"」`,
`is conflicted with 「${propName}」on element <${element.name}>`
);
}

attrs[propName] = `{{${vhtmlValue}}}`;
element.name = 'rich-text';
delete attrs['v-html'];
}

module.exports = createSyntaxPlugin({
attribute: {
html: {
match: 'v-html',
transform: transfromVHtml
}
}
});
Loading

0 comments on commit 071554d

Please sign in to comment.