diff --git a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js
index 1ee21c560a42d63837d40e118fad9006f94dd506..0cbb251167de77fea5d444930ffed4231d55d592 100644
--- a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js
+++ b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js
@@ -79,10 +79,10 @@ describe('codegen', () => {
assertCodegen(
`
A{{ d | e | f }}B{{text}}C
`,
`with(this){return _c('div',{attrs:{"id":_$s(0,'a-id','a'+b),"_i":0}},[_v((_$s(0,'t0-0',_s(_f("f")(_f("e")(d)))))+(_$s(0,'t0-1',_s(text))))])}`
- )
- assertCodegen(
- `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`,
- `with(this){return _c('view',[_v((_$s(0,'t0-0',_s(obj.param1)))+(_$s(0,'t0-1',_s(obj.param1)))+(_$s(0,'t0-2',_s(obj.param1)))),_c('text',[_v((_$s(1,'t0-0',_s(obj.param3)))+(_$s(1,'t0-1',_s(obj.param3))))]),_v((_$s(0,'t2-0',_s(obj.param2)))+(_$s(0,'t2-1',_s(obj.param2)))+(_$s(0,'t2-2',_s(obj.param2))))])}`
+ )
+ assertCodegen(
+ `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`,
+ `with(this){return _c('view',[_v((_$s(0,'t0-0',_s(obj.param1)))+(_$s(0,'t0-1',_s(obj.param1)))+(_$s(0,'t0-2',_s(obj.param1)))),_c('text',[_v((_$s(1,'t0-0',_s(obj.param3)))+(_$s(1,'t0-1',_s(obj.param3))))]),_v((_$s(0,'t2-0',_s(obj.param2)))+(_$s(0,'t2-1',_s(obj.param2)))+(_$s(0,'t2-2',_s(obj.param2))))])}`
)
})
@@ -140,25 +140,48 @@ describe('codegen', () => {
'',
`with(this){return _c('view',{attrs:{"data-b":_$s(0,'a-data-b',b),"_i":0}})}`
)
- })
- it('generate v-if directive', () => {
- assertCodegen(
- '123d',
- `with(this){return (_$s(0,'i',a))?_c('text'):(_$s(1,'e',b))?_c('text'):(_$s(2,'e',c))?_c('text'):_c('text')}`
- )
- })
- it('generate dynamic slot', () => {
- assertCodegen(
- '',
- `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$s(1,'st',dynamicSlotName),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}`
- )
- })
-
- it('generate ref', () => {
- assertCodegen(
- '',
- `with(this){return _c('p',{ref:_$s(0,'ref',component1)})}`
- )
- })
+ })
+ it('generate v-if directive', () => {
+ assertCodegen(
+ '123d',
+ `with(this){return (_$s(0,'i',a))?_c('text'):(_$s(1,'e',b))?_c('text'):(_$s(2,'e',c))?_c('text'):_c('text')}`
+ )
+ })
+ it('generate dynamic slot', () => {
+ assertCodegen(
+ '',
+ `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$s(1,'st',dynamicSlotName),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}`
+ )
+ })
+
+ it('generate ref', () => {
+ assertCodegen(
+ '',
+ `with(this){return _c('p',{ref:_$s(0,'ref',component1)})}`
+ )
+ })
+
+ it('generate image', () => {
+ assertCodegen(
+ '',
+ `with(this){return _c('image',{attrs:{"src":_$s(0,'a-src',src),"_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('image',{attrs:{"_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('image',{attrs:{"src":_$s(0,'a-src',"/"+require("../static/logo.png")),"_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('image',{attrs:{"_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('image',{attrs:{"_i":0}})}`
+ )
+ })
})
/* eslint-enable quotes */
diff --git a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js
index 8ffd4da7a788fd280e07397f181ce5b5faf532f9..261a67392a6f3afe385f4c9d2cd3d5d18ae71074 100644
--- a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js
+++ b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js
@@ -40,12 +40,12 @@ describe('codegen', () => {
'',
`with(this){return _c('div',{attrs:{"_i":0}},[_t("default",[_c('div',{attrs:{"_i":2}},[_v((_$g(2,'t0-0')))])],{"_i":1})],2)}`
)
- })
- it('generate text with multiple statements', () => {
- assertCodegen(
- `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`,
- `with(this){return _c('v-uni-view',{attrs:{"_i":0}},[_v((_$g(0,'t0-0'))+"123123"+(_$g(0,'t0-1'))+"123123"+(_$g(0,'t0-2'))),_c('v-uni-text',{attrs:{"_i":1}},[_v("-"+(_$g(1,'t0-0'))+"---"+(_$g(1,'t0-1')))]),_v((_$g(0,'t2-0'))+"aaaa"+(_$g(0,'t2-1'))+"aaaa"+(_$g(0,'t2-2')))],1)}`
- )
+ })
+ it('generate text with multiple statements', () => {
+ assertCodegen(
+ `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`,
+ `with(this){return _c('v-uni-view',{attrs:{"_i":0}},[_v((_$g(0,'t0-0'))+"123123"+(_$g(0,'t0-1'))+"123123"+(_$g(0,'t0-2'))),_c('v-uni-text',{attrs:{"_i":1}},[_v("-"+(_$g(1,'t0-0'))+"---"+(_$g(1,'t0-1')))]),_v((_$g(0,'t2-0'))+"aaaa"+(_$g(0,'t2-1'))+"aaaa"+(_$g(0,'t2-2')))],1)}`
+ )
})
it('generate v-slot', () => {
assertCodegen(
@@ -81,24 +81,46 @@ describe('codegen', () => {
'',
`with(this){return _c('v-uni-view',{attrs:{"data-a":"1","data-b":_$g(0,'a-data-b'),"_i":0}})}`
)
- })
- it('generate v-if directive', () => {
- assertCodegen(
- '123d',
- `with(this){return (_$g(0,'i'))?_c('v-uni-text',{attrs:{"_i":0}},[_v("1")]):(_$g(1,'e'))?_c('v-uni-text',{attrs:{"_i":1}},[_v("2")]):(_$g(2,'e'))?_c('v-uni-text',{attrs:{"_i":2}},[_v("3")]):_c('v-uni-text',{attrs:{"_i":3}},[_v("d")])}`
- )
- })
- it('generate dynamic slot', () => {
- assertCodegen(
- '',
- `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$g(1,'st'),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}`
- )
- })
- it('generate ref', () => {
- assertCodegen(
- '',
- `with(this){return _c('p',{ref:_$g(0,'ref'),attrs:{"_i":0}})}`
- )
+ })
+ it('generate v-if directive', () => {
+ assertCodegen(
+ '123d',
+ `with(this){return (_$g(0,'i'))?_c('v-uni-text',{attrs:{"_i":0}},[_v("1")]):(_$g(1,'e'))?_c('v-uni-text',{attrs:{"_i":1}},[_v("2")]):(_$g(2,'e'))?_c('v-uni-text',{attrs:{"_i":2}},[_v("3")]):_c('v-uni-text',{attrs:{"_i":3}},[_v("d")])}`
+ )
+ })
+ it('generate dynamic slot', () => {
+ assertCodegen(
+ '',
+ `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$g(1,'st'),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}`
+ )
+ })
+ it('generate ref', () => {
+ assertCodegen(
+ '',
+ `with(this){return _c('p',{ref:_$g(0,'ref'),attrs:{"_i":0}})}`
+ )
+ })
+ it('generate image', () => {
+ assertCodegen(
+ '',
+ `with(this){return _c('v-uni-image',{attrs:{"src":_$g(0,'a-src'),"_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('v-uni-image',{attrs:{"src":"/static/logo.png","_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('v-uni-image',{attrs:{"src":_$g(0,'a-src'),"_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('v-uni-image',{attrs:{"src":"/static/logo.png","_i":0}})}`
+ )
+ assertCodegen(
+ '',
+ `with(this){return _c('v-uni-image',{attrs:{"src":"/static/logo.png","_i":0}})}`
+ )
})
})
/* eslint-enable quotes */
diff --git a/packages/uni-template-compiler/lib/asset-url.js b/packages/uni-template-compiler/lib/asset-url.js
index 4e7232bfad52ea9444f3784278f1d9686cd7b1ba..d6b28096732b9322f09bb983905368719ac4413f 100644
--- a/packages/uni-template-compiler/lib/asset-url.js
+++ b/packages/uni-template-compiler/lib/asset-url.js
@@ -1,3 +1,5 @@
+const url = require('url')
+
const transformAssetUrls = {
'audio': 'src',
'video': ['src', 'poster'],
@@ -14,7 +16,47 @@ const transformAssetUrls = {
'u-video': ['src', 'poster']
}
-function rewrite (attr, name) {
+function urlToRequire (url) {
+ const returnValue = `"${url}"`
+ // same logic as in transform-require.js
+ const firstChar = url.charAt(0)
+ if (firstChar === '.' || firstChar === '~' || firstChar === '@') {
+ if (firstChar === '~') {
+ const secondChar = url.charAt(1)
+ url = url.slice(secondChar === '/' ? 2 : 1)
+ }
+ const uriParts = parseUriParts(url)
+ if (!uriParts.hash) { // fixed by xxxxxx (v3 template中需要加/)
+ return `"/"+require("${url}")`
+ } else { // fixed by xxxxxx (v3 template中需要加/)
+ // support uri fragment case by excluding it from
+ // the require and instead appending it as string;
+ // assuming that the path part is sufficient according to
+ // the above caseing(t.i. no protocol-auth-host parts expected)
+ return `"/"+require("${uriParts.path}") + "${uriParts.hash}"`
+ }
+ }
+ return returnValue
+}
+/**
+ * vuejs/component-compiler-utils#22 Support uri fragment in transformed require
+ * @param urlString an url as a string
+ */
+function parseUriParts (urlString) {
+ // initialize return value
+ const returnValue = url.parse('')
+ if (urlString) {
+ // A TypeError is thrown if urlString is not a string
+ // @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost
+ if (typeof urlString === 'string') {
+ // check is an uri
+ return url.parse(urlString) // take apart the uri
+ }
+ }
+ return returnValue
+}
+
+function rewrite (attr, name, options) {
if (attr.name === name) {
const value = attr.value
// only transform static URLs
@@ -22,13 +64,17 @@ function rewrite (attr, name) {
attr.value = attr.value
.replace('"@/', '"/')
.replace('"~@/', '"/')
+ if (options.service || options.view) { // v3
+ attr.value = urlToRequire(attr.value.slice(1, -1))
+ }
return true
}
}
return false
}
+
module.exports = {
- postTransformNode: (node) => {
+ postTransformNode: (node, options) => {
if (!node.attrs) {
return
}
@@ -37,9 +83,19 @@ module.exports = {
return
}
if (typeof attributes === 'string') {
- node.attrs.some(attr => rewrite(attr, attributes))
+ if (node.attrs.some(attr => rewrite(attr, attributes, options))) {
+ if (options.service || options.view) {
+ node.hasBindings = true
+ }
+ }
} else if (Array.isArray(attributes)) {
- attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item)))
+ attributes.forEach(item => {
+ if (node.attrs.some(attr => rewrite(attr, item, options))) {
+ if (options.service || options.view) {
+ node.hasBindings = true
+ }
+ }
+ })
}
}
}
diff --git a/packages/uni-template-compiler/lib/auto-components.js b/packages/uni-template-compiler/lib/auto-components.js
index da2a74f4f5dbb2e472141f3517e4141faab2a5e4..313db0326ed01ad4d32040b2750cc00659c030fe 100644
--- a/packages/uni-template-compiler/lib/auto-components.js
+++ b/packages/uni-template-compiler/lib/auto-components.js
@@ -61,7 +61,7 @@ function generateAutoComponentsCode (autoComponents, dynamic = false) {
source
}) => {
if (dynamic) {
- components.push(`'${name}': ()=>import(/* webpackChunkName: "${getWebpackChunkName(source)}" */'${source}')`)
+ components.push(`'${name}': function(){return import(/* webpackChunkName: "${getWebpackChunkName(source)}" */'${source}')}`)
} else {
components.push(`'${name}': require('${source}').default`)
}
diff --git a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js
index a23913e9dda6c007cc547ee38f99d1af3216362a..b7389b1b714993c29d42d1e848b05980275d918d 100644
--- a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js
+++ b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js
@@ -154,7 +154,7 @@ const rules = [{
}
].concat(cssLoaders)
-if (process.env.UNI_USING_NVUE_COMPILER) {
+if (process.env.UNI_USING_NVUE_COMPILER || process.env.UNI_USING_V3_NATIVE) {
rules.unshift({
resourceQuery: function (query) {
return query.indexOf('vue&type=template') !== -1 && query.indexOf('mpType=page') !== -1
diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js
index 0ed3fbbcca24107fcadf9f5f633e6d664a633139..20d3b9de5a012f9edf571361726fc7a0680b26be 100644
--- a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js
+++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js
@@ -48,11 +48,18 @@ module.exports = function(content) {
}
// 暂时实时读取配置信息,查找是否 disableScroll
const appJson = getPagesJson()
- if (!appJson.nvue || !appJson.nvue.pages) {
- return content
+
+ let pageJson
+ if (appJson.nvue) { //旧版本
+ if (!appJson.nvue || !appJson.nvue.pages) {
+ return content
+ }
+ const pagePath = resourcePath + '.html'
+ pageJson = appJson.nvue.pages.find(page => page.path === pagePath)
+ } else {
+ pageJson = appJson.pages.find(page => page.path === resourcePath)
}
- const pagePath = resourcePath + '.html'
- const pageJson = appJson.nvue.pages.find(page => page.path === pagePath)
+
if (!pageJson) {
return content
}
diff --git a/src/core/helpers/promise.js b/src/core/helpers/promise.js
index 3f77edee2a896886c19ffe08262a65f306d83e0e..f36f5a54cc76ac172e88a1c32fea59b248420d08 100644
--- a/src/core/helpers/promise.js
+++ b/src/core/helpers/promise.js
@@ -16,7 +16,7 @@ const TASK_APIS = ['request', 'downloadFile', 'uploadFile', 'connectSocket']
const ASYNC_API = ['createBLEConnection']
-const CALLBACK_API_RE = /^on/
+const CALLBACK_API_RE = /^on|^off/
export function isContextApi (name) {
return CONTEXT_API_RE.test(name)
diff --git a/src/platforms/quickapp/README.md b/src/platforms/quickapp/README.md
index 29b26004c9e95e99eb7bce72a422d31babf4414c..2f098e8772f4a7db95ddd36a0b4ed58d1958d2b1 100644
--- a/src/platforms/quickapp/README.md
+++ b/src/platforms/quickapp/README.md
@@ -7,13 +7,19 @@
2.打开快应用调试器,下载平台(快应用预览版:版本号1060)
+3.安装 openssl(windows系统)
+
#### 搭建
-1.创建 `hello uni-app` 工程
+1.创建 `hello uni-app` 测试工程
```
vue create -p dcloudio/uni-preset-vue#alpha my-qa-project -n
```
+目前手动安装依赖库: 根目录执行
+```
+yarn add @dcloudio/uni-quickapp@alpha -D
+```
2.生成证书 `certificate.pem` 和 `private.pem`:到目录 `src/sign/debug/`
```
@@ -37,32 +43,55 @@ npm run serve:quickapp
#### 开发调试代码
-1.仓库 `uni-app(quickapp branch)` [https://github.com/dcloudio/uni-app/tree/quickapp](https://github.com/dcloudio/uni-app/tree/quickapp)
+1.Fork 仓库 `uni-app` [https://github.com/dcloudio/uni-app](https://github.com/dcloudio/uni-app),切换到 dev 分支
+
+2.编译 (输出目录`packages/uni-quickapp`)
-2.目录说明:
```
-`src/platforms/quickapp/service/api` 平台的接口实现(方案同h5,app-plus)
-`src/platforms/quickapp/view/components` 平台的组件实现(easycom格式,目录名与文件名一致)
-`packages/uni-quickapp/lib/compiler-module` 编译阶段标签转换之类逻辑
-`packages/uni-quickapp/lib/polyfill.css` 全局样式差异代码
-`packages/uni-quickapp/lib/manifest` manifest.json的生成逻辑
+npm run build:quickapp
```
-3.编译 (输出目录`packages/uni-quickapp`)
+3.手动替换编译输出目录 `packages/uni-quickapp` 到测试工程 `node_modules/@dcloudio/uni-quickapp`,也可以考虑自己npm link本地`uni-quickapp`包(需要考虑三方依赖)
+
+4.使用 pull request 提交代码
+
+
+#### `uni-app` 目录说明
+
```
-npm run build:quickapp
+packages
+ ├─uni-quickapp
+ │ └─lib
+ │ ├─compiler-module (编译阶段标签转换之类逻辑)
+ │ ├─polyfill.css (全局样式差异代码)
+ │ └─manifest (manifest.json的生成逻辑)
+src
+ ├─platforms
+ │ └─quickapp
+ │ ├─...
+ │ ├─service
+ │ │ └─api 平台的接口实现(方案同h5,app-plus)
+ │ └─view
+ │ └─components 平台的组件实现(easycom格式,目录名与文件名一致)
+ │ └─button
```
-4.可以选择手动替换到自己测试工程的`@dcloudio/uni-quickapp`里边,也可以考虑自己npm link本地`uni-quickapp`包(需要考虑三方依赖)
+
+#### 开发示例
+- button 组件 [https://github.com/dcloudio/uni-app/tree/master/src/platforms/quickapp/view/components/button](https://github.com/dcloudio/uni-app/tree/master/src/platforms/quickapp/view/components/button)
+
#### 包名配置
```
项目 manifest.json
{
- "quickapp" : {
- "package": "com.example.demo"
+ "quickapp" : {
+ "config": {
+ "package": "com.example.demo",
+ "designWidth": 360
}
+ }
}
```
diff --git a/src/platforms/quickapp/view/components/button/button.vue b/src/platforms/quickapp/view/components/button/button.vue
index 1c88399143d910d5502fd7ab10a8c0325536973c..72d5138a70b8c9a819d5cf2520078086494662b0 100644
--- a/src/platforms/quickapp/view/components/button/button.vue
+++ b/src/platforms/quickapp/view/components/button/button.vue
@@ -1,14 +1,293 @@
-