提交 5f1a1e70 编写于 作者: Q qiang

Merge branch 'dev' into alpha

# Conflicts:
#	packages/uni-h5/dist/index.umd.min.js
......@@ -1670,15 +1670,30 @@ var serviceContext = (function () {
// 参数格式化
params.url = encodeQueryString(url);
// 主要拦截目标为用户快速点击时触发的多次跳转,该情况,通常前后 url 是一样的
if (navigatorLock === url) {
return `${navigatorLock} locked`
}
// 至少 onLaunch 之后,再启用lock逻辑(onLaunch之前可能开发者手动调用路由API,来提前跳转)
// enableNavigatorLock 临时开关(不对外开放),避免该功能上线后,有部分情况异常,可以让开发者临时关闭 lock 功能
if (__uniConfig.ready && __uniConfig.enableNavigatorLock !== false) {
navigatorLock = url;
}
}
}
let navigatorLock;
function createProtocol (type, extras = {}) {
return Object.assign({
url: {
type: String,
required: true,
validator: createValidator(type)
},
beforeAll () {
navigatorLock = '';
}
}, extras)
}
......@@ -2305,7 +2320,9 @@ var serviceContext = (function () {
function invokeCallbackHandlerFail (err, apiName, callbackId) {
const errMsg = `${apiName}:fail ${err}`;
console.error(errMsg);
if (process.env.NODE_ENV !== 'production') {
console.error(errMsg);
}
if (callbackId === -1) {
throw new Error(errMsg)
}
......@@ -2323,6 +2340,23 @@ var serviceContext = (function () {
required: true
}];
// 目前已用到的仅这三个
// 完整的可能包含:
// beforeValidate,
// beforeSuccess,
// afterSuccess,
// beforeFail,
// afterFail,
// beforeCancel,
// afterCancel,
// beforeAll,
// afterAll
const IGNORE_KEYS = [
'beforeValidate',
'beforeAll',
'beforeSuccess'
];
function validateParams (apiName, paramsData, callbackId) {
let paramTypes = protocol[apiName];
if (!paramTypes && isCallbackApi(apiName)) {
......@@ -2352,7 +2386,7 @@ var serviceContext = (function () {
const keys = Object.keys(paramTypes);
for (let i = 0; i < keys.length; i++) {
if (keys[i] === 'beforeValidate') {
if (IGNORE_KEYS.indexOf(keys[i]) !== -1) {
continue
}
const err = validateParam(keys[i], paramTypes, paramsData);
......@@ -2434,6 +2468,7 @@ var serviceContext = (function () {
afterFail,
beforeCancel,
afterCancel,
beforeAll,
afterAll
} = wrapperCallbacks;
......@@ -2457,6 +2492,8 @@ var serviceContext = (function () {
res.errMsg = apiName + ':fail' + errDetail;
}
isFn(beforeAll) && beforeAll(res);
const errMsg = res.errMsg;
if (errMsg.indexOf(apiName + ':ok') === 0) {
......@@ -2540,6 +2577,7 @@ var serviceContext = (function () {
function wrapperExtras (name, extras) {
const protocolOptions = protocol[name];
if (protocolOptions) {
isFn(protocolOptions.beforeAll) && (extras.beforeAll = protocolOptions.beforeAll);
isFn(protocolOptions.beforeSuccess) && (extras.beforeSuccess = protocolOptions.beforeSuccess);
}
}
......@@ -8313,10 +8351,10 @@ var serviceContext = (function () {
$remove () {
const index = pages.findIndex(page => page === this);
if (index !== -1) {
pages.splice(index, 1);
if (!webview.nvue) {
this.$vm.$destroy();
}
pages.splice(index, 1);
if (process.env.NODE_ENV !== 'production') {
console.log('[uni-app] removePage', path, webview.id);
}
......@@ -12565,8 +12603,6 @@ var serviceContext = (function () {
handlers.forEach(handler => {
handler(data);
});
} else {
console.error(`vdSync[${pageId}] not found`);
}
}
......
......@@ -1420,7 +1420,7 @@ function handleLink (event) {
vueOptions.parent = parentVm;
}
const mocks = ['nodeId', 'componentName', '_componentId'];
const mocks = ['nodeId', 'componentName', '_componentId', 'uniquePrefix'];
function isPage () {
return !this.ownerId
......
......@@ -1211,7 +1211,7 @@ function parseBaseApp (vm, {
return appOptions
}
const mocks = ['nodeId', 'componentName', '_componentId'];
const mocks = ['nodeId', 'componentName', '_componentId', 'uniquePrefix'];
function isPage () {
return !this.ownerId
......
......@@ -250,6 +250,16 @@ describe('codegen', () => {
'<view> {{text}} text text {{text}} </view>',
`with(this){return _c('view',[_v((_$s(0,'t0-0',_s(text)))+(_$s(0,'t0-1',_s(text))))])}`
)
})
it('generate bool attr', () => {
assertCodegen(
'<video controls/>',
`with(this){return _c('video',{attrs:{"_i":0}})}`
)
assertCodegen(
'<video controls=""/>',
`with(this){return _c('video',{})}`
)
})
})
/* eslint-enable quotes */
......@@ -189,6 +189,16 @@ describe('codegen', () => {
'<view> {{text}} text text {{text}} </view>',
`with(this){return _c('v-uni-view',{attrs:{"_i":0}},[_v((_$g(0,'t0-0'))+" text text "+(_$g(0,'t0-1')))])}`
)
})
it('generate bool attr', () => {
assertCodegen(
'<video controls/>',
`with(this){return _c('v-uni-video',{attrs:{"controls":true,"_i":0}})}`
)
assertCodegen(
'<video controls=""/>',
`with(this){return _c('v-uni-video',{attrs:{"controls":"","_i":0}})}`
)
})
})
/* eslint-enable quotes */
......@@ -646,5 +646,15 @@ describe('mp:compiler-extra', () => {
'<view v-for="item in list" @click="test(item)">{{ item }}</view>',
'<block wx:for="{{list}}" wx:for-item="item" wx:for-index="__i0__"><view data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\'],[[[\'list\',\'\',__i0__]]]]]]]}}" bindtap="__e">{{item}}</view></block>'
)
})
it('generate bool attr', () => {
assertCodegen(
'<video controls/>',
'<video controls="{{true}}"></video>'
)
assertCodegen(
'<video controls=""/>',
'<video controls></video>'
)
})
})
......@@ -19,7 +19,7 @@ const scopedPath = path.resolve(__dirname, '../../')
const compiler = require('../lib')
const res = compiler.compile(
`
<view> {{text}} text text {{text}} </view>
<video controls=""/>
`, {
miniprogram: true,
resourcePath: '/User/fxy/Documents/test.wxml',
......@@ -32,9 +32,9 @@ const res = compiler.compile(
mp: {
platform: 'mp-weixin'
},
filterModules: ['swipe'],
filterModules: ['swipe']
// service: true,
view: true
// view: true
})
console.log(require('util').inspect(res, {
......
......@@ -4,32 +4,10 @@ const {
addRawAttr
} = require('./util')
const dirRE = /^v-|^@|^:|^#/
/**
* 兼容小程序Boolean属性的怪异行为(<custom loading/>为true,<custom loading=""/>为false)
* @param {Object} el
*/
function fixBooleanAttribute (el) {
if (!el.attrsList) {
return
}
el.attrsList.forEach(attr => {
if (attr.bool) { // <custom loading/> => <custom :loading="true"/>
if (!dirRE.test(attr.name) && attr.name !== 'inline-template') {
delete el.attrsMap[attr.name]
attr.name = ':' + attr.name
attr.value = 'true'
el.attrsMap[attr.name] = attr.value
}
}
})
}
module.exports = function preTransformNode (el, options) {
if (!hasOwn(options, 'nid')) {
options.nid = 0
}
fixBooleanAttribute(el)
addRawAttr(el, ID, options.nid++)
if (el.attrsMap['v-for']) {
el.forId = el.attrsMap[ID]
......
......@@ -60,6 +60,8 @@ function generateAutoComponentsCode (autoComponents, dynamic = false) {
name,
source
}) => {
// 统一转换为驼峰命名
name = name.replace(/-(\w)/g, (_, str) => str.toUpperCase())
if (dynamic) {
components.push(`'${name}': function(){return import(/* webpackChunkName: "${getWebpackChunkName(source)}" */'${source}')}`)
} else {
......@@ -98,4 +100,4 @@ const compilerModule = {
module.exports = {
compileTemplate,
module: compilerModule
}
}
const dirRE = /^v-|^@|^:|^#/
module.exports = {
preTransformNode (el) {
if (!el.attrsList) {
return
}
el.attrsList.forEach(attr => {
if (attr.bool) {
if (!dirRE.test(attr.name) && attr.name !== 'inline-template') {
delete el.attrsMap[attr.name]
attr.name = ':' + attr.name
attr.value = 'true'
el.attrsMap[attr.name] = attr.value
}
}
})
}
}
......@@ -44,9 +44,12 @@ module.exports = {
) {
(options.modules || (options.modules = [])).push(autoComponentsModule)
}
if (!options.modules) {
options.modules = []
}
// transformAssetUrls
(options.modules || (options.modules = [])).push(require('./asset-url'))
options.modules.push(require('./asset-url'))
options.modules.push(require('./bool-attr'))
options.isUnaryTag = isUnaryTag
// 将 autoComponents 挂在 isUnaryTag 上边
......@@ -54,7 +57,7 @@ module.exports = {
options.preserveWhitespace = false
if (options.service) {
(options.modules || (options.modules = [])).push(require('./app/service'))
options.modules.push(require('./app/service'))
options.optimize = false // 启用 staticRenderFns
// domProps => attrs
options.mustUseProp = () => false
......@@ -68,7 +71,7 @@ module.exports = {
throw e
}
} else if (options.view) {
(options.modules || (options.modules = [])).push(require('./app/view'))
options.modules.push(require('./app/view'))
options.optimize = false // 暂不启用 staticRenderFns
options.isUnaryTag = isUnaryTag
options.isReservedTag = (tagName) => false // 均为组件
......@@ -80,14 +83,14 @@ module.exports = {
}
} else if (options['quickapp-native']) {
// 后续改版,应统一由具体包实现
(options.modules || (options.modules = [])).push(require('@dcloudio/uni-quickapp-native/lib/compiler-module'))
options.modules.push(require('@dcloudio/uni-quickapp-native/lib/compiler-module'))
}
if (!options.mp) { // h5,quickapp-native
return compileTemplate(source, options, compile)
}
(options.modules || (options.modules = [])).push(compilerModule)
options.modules.push(compilerModule)
if (options.mp.platform === 'mp-alipay') {
options.modules.push(compilerAlipayModule)
......@@ -147,7 +150,7 @@ module.exports = {
delete state.files
// resolve scoped slots
res.generic = state.generic || []
res.generic = state.generic || []
delete state.generic
// define scoped slots
......
......@@ -105,7 +105,8 @@ const oldCompile = compiler.compile
compiler.compile = function (source, options = {}) {
(options.modules || (options.modules = [])).push(autoComponentsModule)
options.modules.push(require('@dcloudio/uni-template-compiler/lib/asset-url'))
options.modules.push(require('@dcloudio/uni-template-compiler/lib/asset-url'))
options.modules.push(require('@dcloudio/uni-template-compiler/lib/bool-attr'))
options.isUnaryTag = isUnaryTag
// 将 autoComponents 挂在 isUnaryTag 上边
......
......@@ -479,7 +479,9 @@ function parseHTML (html, options) {
: options.shouldDecodeNewlines;
attrs[i] = {
name: args[1],
value: decodeAttr(value, shouldDecodeNewlines)
value: decodeAttr(value, shouldDecodeNewlines),
// fixed by xxxxxx 标记 Boolean Attribute
bool: args[3] === undefined && args[4] === undefined && args[5] === undefined
};
if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) {
attrs[i].start = args.start + args[0].match(/^\s*/).length;
......
......@@ -104,9 +104,23 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) {
if (runByHBuilderX) { // 由 HBuilderX 运行时,移除进度,错误
webpackConfig.plugins.delete('progress')
webpackConfig.plugins.delete('friendly-errors')
} else {
webpackConfig.plugin('friendly-errors')
.tap(args => {
if (global.__error_reporting__) {
args[0].onErrors = function (severity, errors) {
if (severity !== 'error') {
return
}
const error = errors[0]
global.__error_reporting__ && global.__error_reporting__(error.name, error.message || '')
}
}
return args
})
}
if (process.env.BUILD_ENV === 'ali-ide') {
webpackConfig.plugins.delete('progress')
}
}
}
}
......@@ -2,6 +2,8 @@ const fs = require('fs')
const path = require('path')
const mkdirp = require('mkdirp')
const loaderUtils = require('loader-utils')
require('./error-reporting')
const hasOwnProperty = Object.prototype.hasOwnProperty
......
function shouldReport (err = '') {
try {
const errMsg = err.toString()
// 目前简单的上报逻辑为:错误信息中包含@dcloudio包名
if (
errMsg.includes('@dcloudio') &&
!errMsg.includes('Errors compiling template')
) {
return true
}
} catch (e) {}
return false
}
// err:string|Error
function report (type, err) {
if (shouldReport(err)) {
console.log('Error Reporting...')
// const https = require('https')
// const data = ...
// const req = https.request({
// hostname: '',
// port: 8080,
// path: '/todos',
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'Content-Length': data.length
// }
// })
// req.write(data)
// req.end()
}
}
global.__error_reporting__ = report
process
.on('unhandledRejection', (reason, p) => {
global.__error_reporting__ && global.__error_reporting__('unhandledRejection', reason)
})
.on('uncaughtException', err => {
global.__error_reporting__ && global.__error_reporting__('uncaughtException', err)
})
......@@ -40,32 +40,10 @@ function addTag (tag) {
process.UNI_TAGS.add(tag)
}
const dirRE = /^v-|^@|^:/
/**
* 兼容小程序Boolean属性的怪异行为(<custom loading/>为true,<custom loading=""/>为false)
* @param {Object} el
*/
function fixBooleanAttribute (el) {
if (!el.attrsList) {
return
}
el.attrsList.forEach(attr => {
if (attr.bool) { // <custom loading/> => <custom :loading="true"/>
if (!dirRE.test(attr.name) && attr.name !== 'inline-template') {
delete el.attrsMap[attr.name]
attr.name = ':' + attr.name
attr.value = 'true'
el.attrsMap[attr.name] = attr.value
}
}
})
}
module.exports = {
h5: true,
modules: [require('../format-text'), {
preTransformNode (el, options) {
fixBooleanAttribute(el)
if (el.tag.indexOf('v-uni-') === 0) {
addTag(el.tag.replace('v-uni-', ''))
} else if (hasOwn(tags, el.tag)) {
......
......@@ -2282,14 +2282,9 @@ var HTML5History = (function (History$$1) {
HTML5History.prototype.ensureURL = function ensureURL (push ) {
if (getLocation(this.base) !== this.current.fullPath) {
var current = cleanPath(this.base + this.current.fullPath);
// fixed by xxxxxx
var location = {
path: current,
params: {
__id__: this.current.params.__id__
}
};
push ? pushState(location, location.params.__id__) : replaceState(location, location.params.__id__);
// fixed by xxxxxx
var id = this.current.params.__id__;
push ? pushState(current, id) : replaceState(current, id);
}
};
......
......@@ -2280,14 +2280,9 @@ var HTML5History = (function (History$$1) {
HTML5History.prototype.ensureURL = function ensureURL (push ) {
if (getLocation(this.base) !== this.current.fullPath) {
var current = cleanPath(this.base + this.current.fullPath);
// fixed by xxxxxx
var location = {
path: current,
params: {
__id__: this.current.params.__id__
}
};
push ? pushState(location, location.params.__id__) : replaceState(location, location.params.__id__);
// fixed by xxxxxx
var id = this.current.params.__id__;
push ? pushState(current, id) : replaceState(current, id);
}
};
......
......@@ -2286,14 +2286,9 @@ var HTML5History = (function (History$$1) {
HTML5History.prototype.ensureURL = function ensureURL (push ) {
if (getLocation(this.base) !== this.current.fullPath) {
var current = cleanPath(this.base + this.current.fullPath);
// fixed by xxxxxx
var location = {
path: current,
params: {
__id__: this.current.params.__id__
}
};
push ? pushState(location, location.params.__id__) : replaceState(location, location.params.__id__);
// fixed by xxxxxx
var id = this.current.params.__id__;
push ? pushState(current, id) : replaceState(current, id);
}
};
......
const stringify = require('./stringify')
module.exports = function (errors) {
console.error(stringify(errors))
const errMsg = stringify(errors, 'error')
if (typeof errMsg !== 'string') {
global.__error_reporting__ && global.__error_reporting__(errMsg.type, errMsg.msg)
console.error(errMsg.msg)
} else {
console.error(errMsg)
}
}
......@@ -2,16 +2,17 @@ const path = require('path')
const formatErrors = require('./format-errors')
module.exports = function stringify (errors) {
return (Array.from(
module.exports = function stringify (errors, type) {
let hasUnknownErr = false
const msg = Array.from(
new Set(
errors.map(err => {
const formatError = formatErrors[err.name]
if (formatError) {
const result = formatError(err)
if (result) {
if (typeof result === 'string') {
hasUnknownErr = true
return result
} else {
if (err.module.resource) {
......@@ -26,11 +27,20 @@ module.exports = function stringify (errors) {
} else if (result === false) {
return '' // skip
}
} else {
hasUnknownErr = true
}
return err.message
})
)
)
.filter(msg => !!msg)
.join('\n'))
).filter(msg => !!msg).join('\n')
if (type === 'error' && hasUnknownErr) {
return {
type: 'onErrors',
msg
}
}
return msg
}
......@@ -327,6 +327,34 @@ meta:{
]
}
function filterPages (pagesJson, includes) {
const pages = []
let subPackages = pagesJson.subPackages || []
if (!Array.isArray(subPackages)) {
subPackages = []
}
includes.forEach(includePagePath => {
let page = pagesJson.pages.find(page => page.path === includePagePath)
if (!page) {
for (let i = 0; i < subPackages.length; i++) {
const {
root,
pages: subPages
} = subPackages[i]
page = subPages.find(subPage => normalizePath(path.join(root, subPage.path)) === includePagePath)
if (page) {
break
}
}
}
if (!page) {
console.error(`${includePagePath} is not found`)
}
pages.push(page)
})
pagesJson.pages = pages
}
module.exports = function (pagesJson, manifestJson, loader) {
const inputDir = process.env.UNI_INPUT_DIR
......@@ -334,6 +362,17 @@ module.exports = function (pagesJson, manifestJson, loader) {
configurePages(pagesJson, manifestJson, loader)
})
const loaderUtils = require('loader-utils')
const params = loaderUtils.parseQuery(loader.resourceQuery)
if (params.pages) {
try {
const pages = JSON.parse(params.pages)
if (Array.isArray(pages)) {
filterPages(pagesJson, pages)
}
} catch (e) {}
}
const pageComponents = getPageComponents(inputDir, pagesJson)
pagesJson.globalStyle = process.UNI_H5_PAGES_JSON.globalStyle
......
......@@ -14,6 +14,7 @@
"libVersion": "",
"appid": "touristappid",
"projectname": "",
"quickappRoot": "",
"condition": {
"search": {
"current": -1,
......
......@@ -20,7 +20,9 @@ import validateParam from './params'
function invokeCallbackHandlerFail (err, apiName, callbackId) {
const errMsg = `${apiName}:fail ${err}`
console.error(errMsg)
if (process.env.NODE_ENV !== 'production') {
console.error(errMsg)
}
if (callbackId === -1) {
throw new Error(errMsg)
}
......@@ -38,6 +40,23 @@ const callbackApiParamTypes = [{
required: true
}]
// 目前已用到的仅这三个
// 完整的可能包含:
// beforeValidate,
// beforeSuccess,
// afterSuccess,
// beforeFail,
// afterFail,
// beforeCancel,
// afterCancel,
// beforeAll,
// afterAll
const IGNORE_KEYS = [
'beforeValidate',
'beforeAll',
'beforeSuccess'
]
function validateParams (apiName, paramsData, callbackId) {
let paramTypes = protocol[apiName]
if (!paramTypes && isCallbackApi(apiName)) {
......@@ -67,7 +86,7 @@ function validateParams (apiName, paramsData, callbackId) {
const keys = Object.keys(paramTypes)
for (let i = 0; i < keys.length; i++) {
if (keys[i] === 'beforeValidate') {
if (IGNORE_KEYS.indexOf(keys[i]) !== -1) {
continue
}
const err = validateParam(keys[i], paramTypes, paramsData)
......@@ -149,6 +168,7 @@ function createApiCallback (apiName, params = {}, extras = {}) {
afterFail,
beforeCancel,
afterCancel,
beforeAll,
afterAll
} = wrapperCallbacks
......@@ -172,6 +192,8 @@ function createApiCallback (apiName, params = {}, extras = {}) {
res.errMsg = apiName + ':fail' + errDetail
}
isFn(beforeAll) && beforeAll(res)
const errMsg = res.errMsg
if (errMsg.indexOf(apiName + ':ok') === 0) {
......@@ -255,6 +277,7 @@ export function wrapperUnimplemented (name) {
function wrapperExtras (name, extras) {
const protocolOptions = protocol[name]
if (protocolOptions) {
isFn(protocolOptions.beforeAll) && (extras.beforeAll = protocolOptions.beforeAll)
isFn(protocolOptions.beforeSuccess) && (extras.beforeSuccess = protocolOptions.beforeSuccess)
}
}
......
......@@ -72,15 +72,30 @@ function createValidator (type) {
// 参数格式化
params.url = encodeQueryString(url)
// 主要拦截目标为用户快速点击时触发的多次跳转,该情况,通常前后 url 是一样的
if (navigatorLock === url) {
return `${navigatorLock} locked`
}
// 至少 onLaunch 之后,再启用lock逻辑(onLaunch之前可能开发者手动调用路由API,来提前跳转)
// enableNavigatorLock 临时开关(不对外开放),避免该功能上线后,有部分情况异常,可以让开发者临时关闭 lock 功能
if (__uniConfig.ready && __uniConfig.enableNavigatorLock !== false) {
navigatorLock = url
}
}
}
let navigatorLock
function createProtocol (type, extras = {}) {
return Object.assign({
url: {
type: String,
required: true,
validator: createValidator(type)
},
beforeAll () {
navigatorLock = ''
}
}, extras)
}
......
......@@ -104,13 +104,14 @@ function beforeEach (to, from, next, routes) {
if (from.meta.isQuit) { // 如果 redirectTo 的前一个页面是 quit 类型,则新打开的页面也是 quit
to.meta.isQuit = true
to.meta.isEntry = !!from.meta.isEntry
}
if (from.meta.isTabBar) { // 如果是 tabBar,需要更新系统组件 tabBar 内的 list 数据
to.meta.isTabBar = true
to.meta.tabBarIndex = from.meta.tabBarIndex
const appVm = getApp().$children[0]
appVm.$set(appVm.tabBar.list[to.meta.tabBarIndex], 'pagePath', to.meta.pagePath)
}
}
// 小程序没有这个逻辑,当时为何加了保留并更新 tabBar 的逻辑?
// if (from.meta.isTabBar) { // 如果是 tabBar,需要更新系统组件 tabBar 内的 list 数据
// to.meta.isTabBar = true
// to.meta.tabBarIndex = from.meta.tabBarIndex
// const appVm = getApp().$children[0]
// appVm.$set(appVm.tabBar.list[to.meta.tabBarIndex], 'pagePath', to.meta.pagePath)
// }
}
break
......
......@@ -76,7 +76,8 @@ export function destroyComponentObserver ({
}) {
const intersectionObserver = intersectionObservers[reqId]
if (intersectionObserver) {
intersectionObserver.disconnect()
intersectionObserver.disconnect()
delete intersectionObservers[reqId]
UniViewJSBridge.publishHandler('onRequestComponentObserver', {
reqId,
reqEnd: true
......
......@@ -301,7 +301,7 @@ export default {
}
},
html2delta (html) {
const tags = ['span', 'strong', 'b', 'ins', 'em', 'i', 'u', 'a', 'del', 's', 'sub', 'sup', 'img', 'div', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'ol', 'ul', 'li']
const tags = ['span', 'strong', 'b', 'ins', 'em', 'i', 'u', 'a', 'del', 's', 'sub', 'sup', 'img', 'div', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'ol', 'ul', 'li', 'br']
let content = ''
let disable
HTMLParser(html, {
......
......@@ -23,17 +23,13 @@ export default {
valueSync: this._getValueString(this.value)
}
},
watch: {
valueSync (value) {
this.$emit('update:value', value)
}
},
created () {
const valueChange = this.__valueChange = debounce((val, oldVal) => {
const valueChange = this.__valueChange = debounce((val) => {
this.valueSync = this._getValueString(val)
}, 100)
this.$watch('value', valueChange)
this.__triggerInput = throttle(($event, detail) => {
this.$emit('update:value', detail.value)
this.$trigger('input', $event, detail)
}, 100)
this.$triggerInput = ($event, detail) => {
......
......@@ -32,36 +32,19 @@ export function setTabBarItem ({
}
}
export function setTabBarStyle ({
color,
selectedColor,
backgroundColor,
borderStyle
}) {
export function setTabBarStyle (style = {}) {
if (!isTabBarPage()) {
return {
errMsg: 'setTabBarStyle:fail not TabBar page'
}
}
const style = {}
const borderStyles = {
black: 'rgba(0,0,0,0.4)',
white: 'rgba(255,255,255,0.4)'
}
if (color) {
style.color = color
}
if (selectedColor) {
style.selectedColor = selectedColor
}
if (backgroundColor) {
style.backgroundColor = backgroundColor
}
const borderStyle = style.borderStyle
if (borderStyle in borderStyles) {
borderStyle = borderStyles[borderStyle]
}
if (borderStyle) {
style.borderStyle = borderStyle
style.borderStyle = borderStyles[borderStyle]
}
tabBar.setTabBarStyle(style)
return {
......
......@@ -88,10 +88,10 @@ export function registerPage ({
$remove () {
const index = pages.findIndex(page => page === this)
if (index !== -1) {
pages.splice(index, 1)
if (!webview.nvue) {
this.$vm.$destroy()
}
pages.splice(index, 1)
if (process.env.NODE_ENV !== 'production') {
console.log('[uni-app] removePage', path, webview.id)
}
......@@ -134,4 +134,4 @@ export function registerPage ({
}
return webview
}
}
......@@ -17,7 +17,8 @@ export default function onVdSync ({
handlers.forEach(handler => {
handler(data)
})
} else {
console.error(`vdSync[${pageId}] not found`)
} else {
// 页面关闭时可能会赶上触发同步,此时页面已销毁
// console.error(`vdSync[${pageId}] not found`)
}
}
export const mocks = ['nodeId', 'componentName', '_componentId']
export const mocks = ['nodeId', 'componentName', '_componentId', 'uniquePrefix']
export function isPage () {
return !this.ownerId
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册