提交 77b43388 编写于 作者: fxy060608's avatar fxy060608

Merge branch 'dev' of https://github.com/dcloudio/uni-app into alpha

...@@ -100,7 +100,7 @@ const rules = [{ ...@@ -100,7 +100,7 @@ const rules = [{
{ {
test: /\.nvue(\?[^?]+)?$/, test: /\.nvue(\?[^?]+)?$/,
use: [{ use: [{
loader: 'vue-loader', loader: path.resolve(__dirname, '../packages/vue-loader'),
options: vueLoaderOptions options: vueLoaderOptions
}], }],
exclude: excludeModuleReg exclude: excludeModuleReg
...@@ -108,7 +108,7 @@ const rules = [{ ...@@ -108,7 +108,7 @@ const rules = [{
{ {
test: /\.vue(\?[^?]+)?$/, test: /\.vue(\?[^?]+)?$/,
use: [{ use: [{
loader: 'vue-loader', loader: path.resolve(__dirname, '../packages/vue-loader'),
options: vueLoaderOptions options: vueLoaderOptions
}], }],
exclude: excludeModuleReg exclude: excludeModuleReg
...@@ -146,6 +146,15 @@ if (process.env.UNI_USING_NVUE_COMPILER) { ...@@ -146,6 +146,15 @@ if (process.env.UNI_USING_NVUE_COMPILER) {
}] }]
}) })
} }
rules.unshift({
resourceQuery: function (query) {
return query.indexOf('vue&type=template') !== -1 && query.indexOf('mpType=page') === -1
},
use: [{
loader: '@dcloudio/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.recycle'
}]
})
if (process.env.UNI_USING_NATIVE) { if (process.env.UNI_USING_NATIVE) {
plugins.push(new WebpackUniMPPlugin()) plugins.push(new WebpackUniMPPlugin())
plugins.push(new CopyWebpackPlugin([{ plugins.push(new CopyWebpackPlugin([{
...@@ -198,6 +207,9 @@ module.exports = function () { ...@@ -198,6 +207,9 @@ module.exports = function () {
'@': process.env.UNI_INPUT_DIR, '@': process.env.UNI_INPUT_DIR,
'uni-pages': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'), 'uni-pages': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'),
'@dcloudio/uni-stat': require.resolve('@dcloudio/uni-stat'), '@dcloudio/uni-stat': require.resolve('@dcloudio/uni-stat'),
'uni-app-style': path.resolve(process.env.UNI_INPUT_DIR, getNVueMainEntry()) + '?' + JSON.stringify({
type: 'appStyle'
}),
'uni-stat-config': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json') + 'uni-stat-config': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json') +
'?' + '?' +
JSON.stringify({ JSON.stringify({
......
...@@ -9,9 +9,16 @@ const { ...@@ -9,9 +9,16 @@ const {
// override // override
moduleAlias.addAlias('weex-styler', path.resolve(__dirname, 'packages/weex-styler')) moduleAlias.addAlias('weex-styler', path.resolve(__dirname, 'packages/weex-styler'))
moduleAlias.addAlias('weex-template-compiler', path.resolve(__dirname, 'packages/weex-template-compiler')) moduleAlias.addAlias('weex-template-compiler', path.resolve(__dirname, 'packages/weex-template-compiler'))
moduleAlias.addAlias('./compileTemplate', path.resolve(__dirname,
'packages/webpack-uni-nvue-loader/lib/compileTemplate'))
moduleAlias.addAlias('./codegen/styleInjection', path.resolve(__dirname, moduleAlias.addAlias('./codegen/styleInjection', path.resolve(__dirname,
'packages/webpack-uni-nvue-loader/lib/styleInjection')) 'packages/webpack-uni-nvue-loader/lib/styleInjection'))
moduleAlias.addAlias('./templateLoader', (fromPath, request, alias) => {
if (fromPath.indexOf('vue-loader') !== -1) {
return path.resolve(__dirname, 'packages/webpack-uni-nvue-loader/lib/templateLoader')
}
return request
})
if (isInHBuilderX) { if (isInHBuilderX) {
moduleAlias.addAlias('typescript', path.resolve(process.env.UNI_HBUILDERX_PLUGINS, moduleAlias.addAlias('typescript', path.resolve(process.env.UNI_HBUILDERX_PLUGINS,
'compile-typescript/node_modules/typescript')) 'compile-typescript/node_modules/typescript'))
......
const path = require('path')
const hash = require('hash-sum')
const qs = require('querystring')
const plugin = require('vue-loader/lib/plugin')
const selectBlock = require('vue-loader/lib/select')
const loaderUtils = require('loader-utils')
const { attrsToQuery } = require('vue-loader/lib/codegen/utils')
const { parse } = require('@vue/component-compiler-utils')
const genStylesCode = require('../webpack-uni-nvue-loader/lib/styleInjection')
const { genHotReloadCode } = require('vue-loader/lib/codegen/hotReload')
const genCustomBlocksCode = require('vue-loader/lib/codegen/customBlocks')
const componentNormalizerPath = require.resolve('vue-loader/lib/runtime/componentNormalizer')
const { NS } = require('vue-loader/lib/plugin')
let errorEmitted = false
function loadTemplateCompiler (loaderContext) {
try {
return require('vue-template-compiler')
} catch (e) {
if (/version mismatch/.test(e.toString())) {
loaderContext.emitError(e)
} else {
loaderContext.emitError(new Error(
`[vue-loader] vue-template-compiler must be installed as a peer dependency, ` +
`or a compatible compiler implementation must be passed via options.`
))
}
}
}
function hasRecyclable (template) {
return !!(template && template.attrs && template.attrs.recyclable)
}
module.exports = function (source) {
const loaderContext = this
if (!errorEmitted && !loaderContext['thread-loader'] && !loaderContext[NS]) {
loaderContext.emitError(new Error(
`vue-loader was used without the corresponding plugin. ` +
`Make sure to include VueLoaderPlugin in your webpack config.`
))
errorEmitted = true
}
const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
const {
target,
request,
minimize,
sourceMap,
rootContext,
resourcePath,
resourceQuery
} = loaderContext
const rawQuery = resourceQuery.slice(1)
const inheritQuery = `&${rawQuery}`
const incomingQuery = qs.parse(rawQuery)
const options = loaderUtils.getOptions(loaderContext) || {}
const isServer = target === 'node'
const isShadow = !!options.shadowMode
const isProduction = options.productionMode || minimize || process.env.NODE_ENV === 'production'
const filename = path.basename(resourcePath)
const context = rootContext || process.cwd()
const sourceRoot = path.dirname(path.relative(context, resourcePath))
const descriptor = parse({
source,
compiler: options.compiler || loadTemplateCompiler(loaderContext),
filename,
sourceRoot,
needMap: sourceMap
})
// if the query has a type field, this is a language block request
// e.g. foo.vue?type=template&id=xxxxx
// and we will return early
if (incomingQuery.type) {
return selectBlock(
descriptor,
loaderContext,
incomingQuery,
!!options.appendExtension
)
}
// module id for scoped CSS & hot-reload
const rawShortFilePath = path
.relative(context, resourcePath)
.replace(/^(\.\.[\/\\])+/, '')
const shortFilePath = rawShortFilePath.replace(/\\/g, '/') + resourceQuery
const id = hash(
isProduction
? (shortFilePath + '\n' + source)
: shortFilePath
)
// feature information
const hasScoped = descriptor.styles.some(s => s.scoped)
const hasFunctional = descriptor.template && descriptor.template.attrs.functional
const needsHotReload = (
!isServer &&
!isProduction &&
(descriptor.script || descriptor.template) &&
options.hotReload !== false
)
// template
let templateImport = `var render, staticRenderFns`
let templateRequest
const recyclable = hasRecyclable(descriptor.template) // fixed by xxxxxx
if (descriptor.template) {
const src = descriptor.template.src || resourcePath
const idQuery = `&id=${id}`
const scopedQuery = hasScoped ? `&scoped=true` : ``
const attrsQuery = attrsToQuery(descriptor.template.attrs)
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${inheritQuery}`
const request = templateRequest = stringifyRequest(src + query)
if(recyclable){ // fixed by xxxxxx
templateImport = `import { render, staticRenderFns, recyclableRender } from ${request}`
} else {
templateImport = `import { render, staticRenderFns } from ${request}`
}
}
// script
let scriptImport = `var script = {}`
if (descriptor.script) {
const src = descriptor.script.src || resourcePath
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js')
const query = `?vue&type=script${attrsQuery}${inheritQuery}`
const request = stringifyRequest(src + query)
scriptImport = (
`import script from ${request}\n` +
`export * from ${request}` // support named exports
)
}
// styles
let stylesCode = ``
if (descriptor.styles.length) {
stylesCode = genStylesCode(
loaderContext,
descriptor.styles,
id,
resourcePath,
stringifyRequest,
needsHotReload,
isServer || isShadow // needs explicit injection?
)
}
let code = `
${templateImport}
${scriptImport}
${stylesCode}
/* normalize component */
import normalizer from ${stringifyRequest(`!${componentNormalizerPath}`)}
var component = normalizer(
script,
render,
staticRenderFns,
${hasFunctional ? `true` : `false`},
${`null`},
${hasScoped ? JSON.stringify(id) : `null`},
${isServer ? JSON.stringify(hash(request)) : `null`}
${isShadow ? `,true` : ``}
)
`.trim() + `\n`
if (descriptor.customBlocks && descriptor.customBlocks.length) {
code += genCustomBlocksCode(
descriptor.customBlocks,
resourcePath,
resourceQuery,
stringifyRequest
)
}
if (needsHotReload) {
code += `\n` + genHotReloadCode(id, hasFunctional, templateRequest)
}
if(/injectStyles/.test(stylesCode)){// fixed by xxxxxx
code +=`\ninjectStyles.call(component)`
}
// Expose filename. This is used by the devtools and Vue runtime warnings.
if (!isProduction) {
// Expose the file's full path in development, so that it can be opened
// from the devtools.
code += `\ncomponent.options.__file = ${JSON.stringify(rawShortFilePath.replace(/\\/g, '/'))}`
} else if (options.exposeFilename) {
// Libraies can opt-in to expose their components' filenames in production builds.
// For security reasons, only expose the file's basename in production.
code += `\ncomponent.options.__file = ${JSON.stringify(filename)}`
}
if(recyclable){
code += `\nrecyclableRender && (component.options["@render"] = recyclableRender)` // fixed by xxxxxx
}
code += `\nexport default component.exports`
// console.log(code)
return code
}
module.exports.VueLoaderPlugin = plugin
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assetUrl_1 = __importDefault(require("@vue/component-compiler-utils/dist/templateCompilerModules/assetUrl"));
const srcset_1 = __importDefault(require("@vue/component-compiler-utils/dist/templateCompilerModules/srcset"));
const consolidate = require('consolidate');
const transpile = require('vue-template-es2015-compiler');
function compileTemplate(options) {
const { preprocessLang } = options;
const preprocessor = preprocessLang && consolidate[preprocessLang];
if (preprocessor) {
return actuallyCompile(Object.assign({}, options, {
source: preprocess(options, preprocessor)
}));
}
else if (preprocessLang) {
return {
code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
source: options.source,
tips: [
`Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`
],
errors: [
`Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`
]
};
}
else {
return actuallyCompile(options);
}
}
exports.compileTemplate = compileTemplate;
function preprocess(options, preprocessor) {
const { source, filename, preprocessOptions } = options;
const finalPreprocessOptions = Object.assign({
filename
}, preprocessOptions);
// Consolidate exposes a callback based API, but the callback is in fact
// called synchronously for most templating engines. In our case, we have to
// expose a synchronous API so that it is usable in Jest transforms (which
// have to be sync because they are applied via Node.js require hooks)
let res, err;
preprocessor.render(source, finalPreprocessOptions, (_err, _res) => {
if (_err)
err = _err;
res = _res;
});
if (err)
throw err;
return res;
}
function actuallyCompile(options) {
const { source, compiler, compilerOptions = {}, transpileOptions = {}, transformAssetUrls, isProduction = process.env.NODE_ENV === 'production', isFunctional = false, optimizeSSR = false, prettify = true } = options;
const compile = optimizeSSR && compiler.ssrCompile ? compiler.ssrCompile : compiler.compile;
let finalCompilerOptions = compilerOptions;
if (transformAssetUrls) {
const builtInModules = [
transformAssetUrls === true
? assetUrl_1.default()
: assetUrl_1.default(transformAssetUrls),
srcset_1.default()
];
finalCompilerOptions = Object.assign({}, compilerOptions, {
modules: [...builtInModules, ...(compilerOptions.modules || [])]
});
}
const { render, staticRenderFns, tips, errors, '@render': recyclableRender } = compile(source, finalCompilerOptions);
if (errors && errors.length) {
return {
code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
source,
tips,
errors
};
}
else {
const finalTranspileOptions = Object.assign({}, transpileOptions, {
transforms: Object.assign({}, transpileOptions.transforms, {
stripWithFunctional: isFunctional
})
});
const toFunction = (code) => {
return `function (${isFunctional ? `_h,_vm` : ``}) {${code}}`;
};
// transpile code with vue-template-es2015-compiler, which is a forked
// version of Buble that applies ES2015 transforms + stripping `with` usage
let code = transpile(`var __render__ = ${toFunction(render)}\n` +
(recyclableRender ? (`var __recyclableRender__ = ${toFunction(recyclableRender)}\n`) : '') +
`var __staticRenderFns__ = [${staticRenderFns.map(toFunction)}]`, finalTranspileOptions) + `\n`;
// #23 we use __render__ to avoid `render` not being prefixed by the
// transpiler when stripping with, but revert it back to `render` to
// maintain backwards compat
code = code.replace(/\s__(render|recyclableRender|staticRenderFns)__\s/g, ' $1 ');
if (!isProduction) {
// mark with stripped (this enables Vue to use correct runtime proxy
// detection)
code += `render._withStripped = true`;
if (prettify) {
code = require('prettier').format(code, {
semi: false,
parser: 'babel'
});
}
}
return {
code,
source,
tips,
errors
};
}
}
...@@ -28,7 +28,7 @@ function getAppStyleCode(stringifyRequest) { ...@@ -28,7 +28,7 @@ function getAppStyleCode(stringifyRequest) {
if (!process.env.UNI_USING_NVUE_COMPILER) { if (!process.env.UNI_USING_NVUE_COMPILER) {
return '' return ''
} }
let code = 'App.appStyle = {}\n' let code = 'Vue.prototype.__$appStyle__ = {}\n'
let styles = [] let styles = []
try { try {
if (fs.existsSync(appVuePath)) { if (fs.existsSync(appVuePath)) {
...@@ -37,7 +37,7 @@ function getAppStyleCode(stringifyRequest) { ...@@ -37,7 +37,7 @@ function getAppStyleCode(stringifyRequest) {
} catch (e) {} } catch (e) {}
styles.forEach((style, index) => { styles.forEach((style, index) => {
code = code + code = code +
`Vue.prototype.__merge_style(require(${genStyleRequest(style,index,stringifyRequest)}).default,App.appStyle)\n` `Vue.prototype.__merge_style && Vue.prototype.__merge_style(require(${genStyleRequest(style,index,stringifyRequest)}).default,Vue.prototype.__$appStyle__)\n`
}) })
return code return code
} }
...@@ -51,22 +51,25 @@ module.exports = function(content) { ...@@ -51,22 +51,25 @@ module.exports = function(content) {
if (this.resourceQuery) { if (this.resourceQuery) {
const params = loaderUtils.parseQuery(this.resourceQuery) const params = loaderUtils.parseQuery(this.resourceQuery)
if (params && params.page) { if (params) {
if (params.page) {
const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
params.page = decodeURIComponent(params.page) params.page = decodeURIComponent(params.page)
// import Vue from 'vue'是为了触发 vendor 合并 // import Vue from 'vue'是为了触发 vendor 合并
return ` return `
${statCode} ${statCode}
import App from './${normalizePath(params.page)}.nvue?mpType=page' import 'uni-app-style'
App.mpType = 'page' import App from './${normalizePath(params.page)}.nvue?mpType=page'
App.route = '${params.page}' App.mpType = 'page'
App.el = '#root' App.route = '${params.page}'
${getAppStyleCode(stringifyRequest)} App.el = '#root'
new Vue(App) new Vue(App)
` `
} else if (params.type === 'appStyle') {
const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
return `${getAppStyleCode(stringifyRequest)}`
}
} }
} }
return statCode + content return statCode + content
} }
...@@ -86,21 +86,21 @@ module.exports = function genStyleInjectionCode ( ...@@ -86,21 +86,21 @@ module.exports = function genStyleInjectionCode (
} }
}) })
} else { } else {
styleInjectionCode = `if(!this.$options.style){ styleInjectionCode = `if(!this.options.style){
this.$options.style = {} this.options.style = {}
} }
if(this.__merge_style && this.$root && this.$root.$options.appStyle){ if(Vue.prototype.__merge_style && Vue.prototype.__$appStyle__){
this.__merge_style(this.$root.$options.appStyle) Vue.prototype.__merge_style(Vue.prototype.__$appStyle__, this.options.style)
} }
` `
styles.forEach((style, i) => { styles.forEach((style, i) => {
if (isNotEmptyStyle(style)) { if (isNotEmptyStyle(style)) {
const request = genStyleRequest(style, i) const request = genStyleRequest(style, i)
styleInjectionCode += ( styleInjectionCode += (
`if(this.__merge_style){ `if(Vue.prototype.__merge_style){
this.__merge_style(require(${request}).default) Vue.prototype.__merge_style(require(${request}).default, this.options.style)
}else{ }else{
Object.assign(this.$options.style,require(${request}).default) Object.assign(this.options.style,require(${request}).default)
}\n`//fixed by xxxxxx 简单处理,与 weex-vue-loader 保持一致 }\n`//fixed by xxxxxx 简单处理,与 weex-vue-loader 保持一致
//`var style${i} = require(${request})\n` + //`var style${i} = require(${request})\n` +
//`if (style${i}.__inject__) style${i}.__inject__(context)\n` //`if (style${i}.__inject__) style${i}.__inject__(context)\n`
...@@ -119,8 +119,7 @@ ${styleImportsCode} ...@@ -119,8 +119,7 @@ ${styleImportsCode}
${hasCSSModules && needsHotReload ? `var cssModules = {}` : ``} ${hasCSSModules && needsHotReload ? `var cssModules = {}` : ``}
${needsHotReload ? `var disposed = false` : ``} ${needsHotReload ? `var disposed = false` : ``}
function injectStyles (context) { function injectStyles () {
${needsHotReload ? `if (disposed) return` : ``}
${styleInjectionCode} ${styleInjectionCode}
} }
......
const loaderUtils = require('loader-utils')
module.exports = function(content) {
this.cacheable && this.cacheable()
const vueLoaderOptions = this.loaders[0]
if (vueLoaderOptions.ident === 'vue-loader-options') {
const params = loaderUtils.parseQuery(this.resourceQuery)
if (params.recyclable) {
Object.assign(vueLoaderOptions.options.compilerOptions, {
recyclable: true
})
}
} else {
throw new Error('vue-loader-options parse error')
}
return content
}
const qs = require('querystring')
const loaderUtils = require('loader-utils')
const { compileTemplate } = require('@vue/component-compiler-utils')
// Loader that compiles raw template into JavaScript functions.
// This is injected by the global pitcher (../pitch) for template
// selection requests initiated from vue files.
module.exports = function (source) {
const loaderContext = this
const query = qs.parse(this.resourceQuery.slice(1))
// although this is not the main vue-loader, we can get access to the same
// vue-loader options because we've set an ident in the plugin and used that
// ident to create the request for this loader in the pitcher.
const options = loaderUtils.getOptions(loaderContext) || {}
const { id } = query
const isServer = loaderContext.target === 'node'
const isProduction = options.productionMode || loaderContext.minimize || process.env.NODE_ENV === 'production'
const isFunctional = query.functional
// allow using custom compiler via options
const compiler = options.compiler || require('vue-template-compiler')
const compilerOptions = Object.assign({
outputSourceRange: true
}, options.compilerOptions, {
scopeId: query.scoped ? `data-v-${id}` : null,
comments: query.comments
})
// for vue-component-compiler
const finalOptions = {
source,
filename: this.resourcePath,
compiler,
compilerOptions,
// allow customizing behavior of vue-template-es2015-compiler
transpileOptions: options.transpileOptions,
transformAssetUrls: options.transformAssetUrls || true,
isProduction,
isFunctional,
optimizeSSR: isServer && options.optimizeSSR !== false,
prettify: options.prettify
}
const compiled = compileTemplate(finalOptions)
// tips
if (compiled.tips && compiled.tips.length) {
compiled.tips.forEach(tip => {
loaderContext.emitWarning(typeof tip === 'object' ? tip.msg : tip)
})
}
// errors
if (compiled.errors && compiled.errors.length) {
// 2.6 compiler outputs errors as objects with range
if (compiler.generateCodeFrame && finalOptions.compilerOptions.outputSourceRange) {
// TODO account for line offset in case template isn't placed at top
// of the file
loaderContext.emitError(
`\n\n Errors compiling template:\n\n` +
compiled.errors.map(({ msg, start, end }) => {
const frame = compiler.generateCodeFrame(source, start, end)
return ` ${msg}\n\n${pad(frame)}`
}).join(`\n\n`) +
'\n'
)
} else {
loaderContext.emitError(
`\n Error compiling template:\n${pad(compiled.source)}\n` +
compiled.errors.map(e => ` - ${e}`).join('\n') +
'\n'
)
}
}
const { code } = compiled
if(query.recyclable) {// fixed by xxxxxx
return code + `\nexport { render, recyclableRender, staticRenderFns }`
}
// finish with ESM exports
return code + `\nexport { render, staticRenderFns }`
}
function pad (source) {
return source
.split(/\r?\n/)
.map(line => ` ${line}`)
.join('\n')
}
...@@ -4683,7 +4683,7 @@ function postTransformComponentRoot (el) { ...@@ -4683,7 +4683,7 @@ function postTransformComponentRoot (el) {
/* */ /* */
function postTransformRef (el, options) { function postTransformRef (el) {
if (el.ref) { if (el.ref) {
addAttr(el, 'ref', el.ref); addAttr(el, 'ref', el.ref);
delete el.ref; delete el.ref;
......
...@@ -27,7 +27,7 @@ const passiveOptions = supportsPassive ? { ...@@ -27,7 +27,7 @@ const passiveOptions = supportsPassive ? {
function updateCssVar (vm) { function updateCssVar (vm) {
if (uni.canIUse('css.var')) { if (uni.canIUse('css.var')) {
const pageVm = vm.$parent.$parent const pageVm = vm.$parent.$parent
const windowTop = pageVm.showNavigationBar && pageVm.navigationBar.type !== 'transparent' ? (NAVBAR_HEIGHT + const windowTop = pageVm.showNavigationBar && pageVm.navigationBar.type !== 'transparent' && pageVm.navigationBar.type !== 'float' ? (NAVBAR_HEIGHT +
'px') 'px')
: '0px' : '0px'
const windowBottom = getApp().$children[0].showTabBar ? (TABBAR_HEIGHT + 'px') : '0px' const windowBottom = getApp().$children[0].showTabBar ? (TABBAR_HEIGHT + 'px') : '0px'
...@@ -74,8 +74,8 @@ export default function initSubscribe (subscribe) { ...@@ -74,8 +74,8 @@ export default function initSubscribe (subscribe) {
const enablePageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom') const enablePageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom')
const onReachBottomDistance = pageVm.onReachBottomDistance const onReachBottomDistance = pageVm.onReachBottomDistance
const enableTransparentTitleNView = isPlainObject(pageVm.titleNView) && pageVm.titleNView.type === const enableTransparentTitleNView = (isPlainObject(pageVm.titleNView) && pageVm.titleNView.type ===
'transparent' 'transparent') || (isPlainObject(pageVm.navigationBar) && pageVm.navigationBar.type === 'transparent')
if (scrollListener) { if (scrollListener) {
document.removeEventListener('scroll', scrollListener) document.removeEventListener('scroll', scrollListener)
......
...@@ -308,7 +308,8 @@ uni-input[hidden] { ...@@ -308,7 +308,8 @@ uni-input[hidden] {
height: 100%; height: 100%;
background: none; background: none;
color: inherit; color: inherit;
opacity: inherit; opacity: 1;
-webkit-text-fill-color: currentcolor;
font: inherit; font: inherit;
line-height: inherit; line-height: inherit;
letter-spacing: inherit; letter-spacing: inherit;
......
...@@ -340,7 +340,8 @@ uni-textarea[auto-height] .uni-textarea-textarea { ...@@ -340,7 +340,8 @@ uni-textarea[auto-height] .uni-textarea-textarea {
resize: none; resize: none;
background: none; background: none;
color: inherit; color: inherit;
opacity: inherit; opacity: 1;
-webkit-text-fill-color: currentcolor;
font: inherit; font: inherit;
line-height: inherit; line-height: inherit;
letter-spacing: inherit; letter-spacing: inherit;
......
...@@ -136,9 +136,28 @@ export default { ...@@ -136,9 +136,28 @@ export default {
titleImage: { titleImage: {
type: String, type: String,
default: '' default: ''
},
transparentTitle: {
type: String,
default: 'none'
},
titlePenetrate: {
type: String,
default: 'NO'
} }
}, },
data () { data () {
const titleNViewTypeList = {
'none': 'default',
'auto': 'transparent',
'always': 'float'
}
const yesNoParseList = {
'YES': true,
'NO': false
}
const navigationBar = mergeTitleNView({ const navigationBar = mergeTitleNView({
loading: false, loading: false,
backButton: !this.isQuit && !this.$route.meta.isQuit, // redirectTo,reLaunch时可能动态修改 meta.isQuit backButton: !this.isQuit && !this.$route.meta.isQuit, // redirectTo,reLaunch时可能动态修改 meta.isQuit
...@@ -147,7 +166,10 @@ export default { ...@@ -147,7 +166,10 @@ export default {
titleText: this.navigationBarTitleText, titleText: this.navigationBarTitleText,
titleImage: this.titleImage, titleImage: this.titleImage,
duration: '0', duration: '0',
timingFunc: '' timingFunc: '',
type: titleNViewTypeList[this.transparentTitle],
transparentTitle: this.transparentTitle,
titlePenetrate: yesNoParseList[this.titlePenetrate]
}, this.titleNView) }, this.titleNView)
const showNavigationBar = this.navigationStyle === 'default' && this.titleNView const showNavigationBar = this.navigationStyle === 'default' && this.titleNView
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<uni-page-head :uni-page-head-type="type"> <uni-page-head :uni-page-head-type="type">
<div <div
:style="{transitionDuration:duration,transitionTimingFunction:timingFunc,backgroundColor:bgColor,color:textColor}" :style="{transitionDuration:duration,transitionTimingFunction:timingFunc,backgroundColor:bgColor,color:textColor}"
:class="{'uni-page-head-transparent':type==='transparent'}" :class="{'uni-page-head-transparent':type==='transparent','uni-page-head-titlePenetrate': titlePenetrate}"
class="uni-page-head" class="uni-page-head"
> >
<div class="uni-page-head-hd"> <div class="uni-page-head-hd">
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
v-if="!searchInput" v-if="!searchInput"
class="uni-page-head-bd"> class="uni-page-head-bd">
<div <div
:style="{fontSize:titleSize,opacity:type==='transparent'?0:1}" :style="{fontSize:titleSize}"
class="uni-page-head__title" class="uni-page-head__title"
> >
<i <i
...@@ -96,7 +96,8 @@ ...@@ -96,7 +96,8 @@
</div> </div>
</div> </div>
<div <div
v-if="type!=='transparent'" v-if="type!=='transparent'&&type!=='float'"
:class="{'uni-placeholder-titlePenetrate': titlePenetrate}"
class="uni-placeholder"/> class="uni-placeholder"/>
</uni-page-head> </uni-page-head>
</template> </template>
...@@ -122,6 +123,16 @@ uni-page-head .uni-page-head { ...@@ -122,6 +123,16 @@ uni-page-head .uni-page-head {
transition-property: all; transition-property: all;
} }
uni-page-head .uni-page-head-titlePenetrate,
uni-page-head .uni-page-head-titlePenetrate .uni-page-head-bd,
uni-page-head .uni-page-head-titlePenetrate .uni-page-head-bd * {
pointer-events: none;
}
uni-page-head .uni-page-head-titlePenetrate *{
pointer-events: auto;
}
uni-page-head .uni-page-head.uni-page-head-transparent .uni-page-head-ft > div { uni-page-head .uni-page-head.uni-page-head-transparent .uni-page-head-ft > div {
justify-content: center; justify-content: center;
} }
...@@ -131,6 +142,10 @@ uni-page-head .uni-page-head ~ .uni-placeholder { ...@@ -131,6 +142,10 @@ uni-page-head .uni-page-head ~ .uni-placeholder {
height: 44px; height: 44px;
} }
uni-page-head .uni-placeholder-titlePenetrate{
pointer-events: none;
}
uni-page-head .uni-page-head * { uni-page-head .uni-page-head * {
box-sizing: border-box; box-sizing: border-box;
} }
...@@ -277,7 +292,7 @@ uni-page-head .uni-page-head__title .uni-loading { ...@@ -277,7 +292,7 @@ uni-page-head .uni-page-head__title .uni-loading {
uni-page-head .uni-page-head__title .uni-page-head__title_image { uni-page-head .uni-page-head__title .uni-page-head__title_image {
width: auto; width: auto;
height: 20px; height: 26px;
vertical-align: middle; vertical-align: middle;
} }
</style> </style>
...@@ -335,7 +350,7 @@ export default { ...@@ -335,7 +350,7 @@ export default {
type: { type: {
default: 'default', default: 'default',
validator (value) { validator (value) {
return ['default', 'transparent'].indexOf(value) !== -1 return ['default', 'transparent', 'float'].indexOf(value) !== -1
} }
}, },
coverage: { coverage: {
...@@ -357,6 +372,16 @@ export default { ...@@ -357,6 +372,16 @@ export default {
titleImage: { titleImage: {
type: String, type: String,
default: '' default: ''
},
transparentTitle: {
default: 'none',
validator (value) {
return ['none', 'auto', 'always'].indexOf(value) !== -1
}
},
titlePenetrate: {
type: Boolean,
default: false
} }
}, },
data () { data () {
......
...@@ -6,7 +6,7 @@ export default { ...@@ -6,7 +6,7 @@ export default {
mounted () { mounted () {
if (this.type === 'transparent') { if (this.type === 'transparent') {
const transparentElemStyle = this.$el.querySelector('.uni-page-head-transparent').style const transparentElemStyle = this.$el.querySelector('.uni-page-head-transparent').style
const titleElem = this.$el.querySelector('.uni-page-head__title') // const titleElem = this.$el.querySelector('.uni-page-head__title')
const iconElems = this.$el.querySelectorAll('.uni-btn-icon') const iconElems = this.$el.querySelectorAll('.uni-btn-icon')
const iconElemsStyles = [] const iconElemsStyles = []
const textColor = this.textColor const textColor = this.textColor
...@@ -40,9 +40,10 @@ export default { ...@@ -40,9 +40,10 @@ export default {
} }
this._A = alpha this._A = alpha
// TODO 暂时仅处理背景色 // TODO 暂时仅处理背景色
if (titleElem) { // 对齐支付宝小程序,标题不透明渐变
titleElem.style.opacity = alpha // if (titleElem) {
} // titleElem.style.opacity = alpha
// }
transparentElemStyle.backgroundColor = `rgba(${this._R},${this._G},${this._B},${alpha})` transparentElemStyle.backgroundColor = `rgba(${this._R},${this._G},${this._B},${alpha})`
borderRadiusElemsStyles.forEach(function (borderRadiusElemStyle, index) { borderRadiusElemsStyles.forEach(function (borderRadiusElemStyle, index) {
let oldColor = oldColors[index] let oldColor = oldColors[index]
...@@ -52,17 +53,31 @@ export default { ...@@ -52,17 +53,31 @@ export default {
borderRadiusElemStyle.backgroundColor = `rgba(${rgba})` borderRadiusElemStyle.backgroundColor = `rgba(${rgba})`
}) })
}) })
} else if (this.transparentTitle === 'always') {
const iconElems = this.$el.querySelectorAll('.uni-btn-icon')
const iconElemsStyles = []
for (let i = 0; i < iconElems.length; i++) {
iconElemsStyles.push(iconElems[i].style)
}
const borderRadiusElems = this.$el.querySelectorAll('.uni-page-head-btn')
const oldColors = []
const borderRadiusElemsStyles = []
for (let i = 0; i < borderRadiusElems.length; i++) {
let borderRadiusElem = borderRadiusElems[i]
oldColors.push(getComputedStyle(borderRadiusElem).backgroundColor)
borderRadiusElemsStyles.push(borderRadiusElem.style)
}
} }
}, },
computed: { computed: {
color () { color () {
return this.type === 'transparent' ? '#fff' : this.textColor return this.type === 'transparent' || this.transparentTitle === 'always' ? '#fff' : this.textColor
}, },
offset () { offset () {
return parseInt(this.coverage) return parseInt(this.coverage)
}, },
bgColor () { bgColor () {
if (this.type === 'transparent') { if (this.type === 'transparent' || this.transparentTitle === 'always') {
const { const {
r, r,
g, g,
......
...@@ -33,9 +33,9 @@ export default { ...@@ -33,9 +33,9 @@ export default {
const { const {
latitude, latitude,
longitude, longitude,
scale, scale = 18,
name, name = '',
address address = ''
} = this.$route.query } = this.$route.query
return { return {
latitude, latitude,
......
...@@ -17,7 +17,7 @@ export default function getWindowOffset () { ...@@ -17,7 +17,7 @@ export default function getWindowOffset () {
const pages = getCurrentPages() const pages = getCurrentPages()
if (pages.length) { if (pages.length) {
const pageVm = pages[pages.length - 1].$parent.$parent const pageVm = pages[pages.length - 1].$parent.$parent
top = pageVm.showNavigationBar && pageVm.navigationBar.type !== 'transparent' ? NAVBAR_HEIGHT : 0 top = pageVm.showNavigationBar && (pageVm.navigationBar.type !== 'transparent' || pageVm.navigationBar.type !== 'float') ? NAVBAR_HEIGHT : 0
} }
const app = getApp() const app = getApp()
if (app) { if (app) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册