feat(core): 增强核心事件通讯总线,增强跨组件交互能力
This commit is contained in:
1221
common/js/diy.js
1221
common/js/diy.js
File diff suppressed because it is too large
Load Diff
133
common/js/dom-event-bridge.js
Normal file
133
common/js/dom-event-bridge.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Uniapp DOM 事件桥接类,用于将 DOM 事件桥接到 EventBus
|
||||
* 支持将 DOM 事件转换为 EventBus 事件,可配置是否阻止默认行为和停止传播
|
||||
*
|
||||
* @author ZFSun <lauer3912@gmail.com>
|
||||
* @version 1.0.0
|
||||
* @createTime 2023-08-10
|
||||
*/
|
||||
|
||||
class DomEventBridge {
|
||||
constructor() {
|
||||
this.eventBus = null
|
||||
this.domListeners = new Map()
|
||||
}
|
||||
|
||||
// 设置 EventBus 实例
|
||||
setEventBus(eventBus) {
|
||||
this.eventBus = eventBus
|
||||
}
|
||||
|
||||
// 桥接 DOM 事件到 EventBus
|
||||
bridgeDomEvent(domEventName, eventBusEventName, options = {}) {
|
||||
const handler = (domEvent) => {
|
||||
if (!this.eventBus) return
|
||||
|
||||
// 创建 EventBus 兼容的事件对象
|
||||
const eventBusEvent = this.createEventBusEvent(domEvent, eventBusEventName)
|
||||
|
||||
// 触发 EventBus 事件
|
||||
const shouldContinue = this.eventBus.emit(eventBusEventName, eventBusEvent)
|
||||
|
||||
// 根据 EventBus 处理结果决定是否阻止 DOM 事件默认行为
|
||||
if (!shouldContinue && options.preventDefault) {
|
||||
domEvent.preventDefault()
|
||||
}
|
||||
|
||||
// 根据 EventBus 处理结果决定是否停止 DOM 事件传播
|
||||
if (!shouldContinue && options.stopPropagation) {
|
||||
domEvent.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
// 保存监听器引用以便清理
|
||||
const listenerKey = `${domEventName}-${eventBusEventName}`
|
||||
this.domListeners.set(listenerKey, handler)
|
||||
|
||||
// 添加 DOM 事件监听
|
||||
// #ifdef H5
|
||||
document.addEventListener(domEventName, handler, options)
|
||||
// #endif
|
||||
|
||||
return () => this.unbridgeDomEvent(domEventName, eventBusEventName)
|
||||
}
|
||||
|
||||
// 创建 EventBus 兼容的事件对象
|
||||
createEventBusEvent(domEvent, eventBusEventName) {
|
||||
return {
|
||||
type: eventBusEventName,
|
||||
domEvent: domEvent,
|
||||
originalEvent: domEvent,
|
||||
target: domEvent.target,
|
||||
currentTarget: domEvent.currentTarget,
|
||||
timestamp: Date.now(),
|
||||
|
||||
// EventBus 的取消方法
|
||||
preventDefault: function () {
|
||||
this._preventDefault = true
|
||||
},
|
||||
|
||||
stopPropagation: function () {
|
||||
this._stopPropagation = true
|
||||
},
|
||||
|
||||
// DOM 事件的代理方法
|
||||
stopImmediatePropagation: function () {
|
||||
domEvent.stopImmediatePropagation()
|
||||
},
|
||||
|
||||
get isDefaultPrevented() {
|
||||
return this._preventDefault || false
|
||||
},
|
||||
|
||||
get isPropagationStopped() {
|
||||
return this._stopPropagation || false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 取消桥接
|
||||
unbridgeDomEvent(domEventName, eventBusEventName) {
|
||||
const listenerKey = `${domEventName}-${eventBusEventName}`
|
||||
const handler = this.domListeners.get(listenerKey)
|
||||
|
||||
if (handler) {
|
||||
// #ifdef H5
|
||||
document.removeEventListener(domEventName, handler)
|
||||
// #endif
|
||||
this.domListeners.delete(listenerKey)
|
||||
}
|
||||
}
|
||||
|
||||
// 从 EventBus 触发 DOM 事件
|
||||
triggerDomEventFromEventBus(domEventName, detail = {}) {
|
||||
// #ifdef H5
|
||||
const event = new CustomEvent(domEventName, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: detail
|
||||
})
|
||||
|
||||
document.dispatchEvent(event)
|
||||
return !event.defaultPrevented
|
||||
// #endif
|
||||
|
||||
// #ifdef MP - WEIXIN
|
||||
// 小程序环境不支持 DOM 事件
|
||||
return true
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 清理所有桥接
|
||||
destroy() {
|
||||
for (const [listenerKey, handler] of this.domListeners) {
|
||||
const [domEventName] = listenerKey.split('-')
|
||||
// #ifdef H5
|
||||
document.removeEventListener(domEventName, handler)
|
||||
// #endif
|
||||
}
|
||||
this.domListeners.clear()
|
||||
}
|
||||
}
|
||||
|
||||
export default new DomEventBridge()
|
||||
260
common/js/event-bus.js
Normal file
260
common/js/event-bus.js
Normal file
@@ -0,0 +1,260 @@
|
||||
/**
|
||||
* Uniapp 事件总线类,用于在应用内进行事件通信
|
||||
* 支持同步和异步事件触发,可配置是否继续传播事件
|
||||
* 可配置是否在任意监听器抛出错误后立即停止传播
|
||||
* 可配置是否在每个监听器执行后调用 defaultAsyncHandler
|
||||
* 如果 allowAsyncHandlerRun 为 true,在每个监听器执行后调用 defaultAsyncHandler
|
||||
* 如果 allowAsyncHandlerRun 为 false,不调用 defaultAsyncHandler
|
||||
* 注意:如果 allowAsyncHandlerRun 为 false,defaultAsyncHandler 不会被调用,也不会等待其 resolve
|
||||
*
|
||||
* @author ZFSun <lauer3912@gmail.com>
|
||||
* @version 1.0.0
|
||||
* @createTime 2023-08-10
|
||||
*/
|
||||
|
||||
class EventBus {
|
||||
constructor() {
|
||||
this.events = new Map()
|
||||
this.domBridge = null
|
||||
this.platform = this.detectPlatform()
|
||||
}
|
||||
|
||||
// 检测平台
|
||||
detectPlatform() {
|
||||
// #ifdef H5
|
||||
return 'h5'
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
return 'weapp'
|
||||
// #endif
|
||||
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
// 设置 DOM 桥接
|
||||
setDomBridge(bridge) {
|
||||
this.domBridge = bridge
|
||||
bridge.setEventBus(this)
|
||||
}
|
||||
|
||||
// 监听事件(自动处理平台差异),支持取消
|
||||
on(eventName, callback, options = { priority: 0 }) {
|
||||
// 如果是 H5 平台且事件名是 DOM 事件,自动创建桥接
|
||||
if (this.platform === 'h5' && this.isDomEvent(eventName) && this.domBridge) {
|
||||
return this.domBridge.bridgeDomEvent(
|
||||
this.getDomEventName(eventName),
|
||||
eventName,
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
// 普通 EventBus 监听
|
||||
if (!this.events.has(eventName)) {
|
||||
this.events.set(eventName, new Set())
|
||||
}
|
||||
|
||||
const handler = { callback, options }
|
||||
this.events.get(eventName).add(handler)
|
||||
|
||||
// 返回取消函数
|
||||
return () => this.off(eventName, handler)
|
||||
}
|
||||
|
||||
// 监听多个事件,支持取消
|
||||
onMany(eventNames = [], callback, options = { priority: 0 }) {
|
||||
// 支持字符串数组或空格分隔的字符串,自动转换为数组
|
||||
if (typeof eventNames === 'string') {
|
||||
// 支持使用空格分隔事件名
|
||||
// 支持使用逗号分隔事件名
|
||||
// 下面代码使用正则表达式,自动处理逗号和空格分隔的字符串
|
||||
eventNames = eventNames.replace(/\s+/g, ',').split(',')
|
||||
}
|
||||
const removeFns = eventNames.map(eventName => this.on(eventName, callback, options))
|
||||
return () => removeFns.forEach(fn => fn())
|
||||
}
|
||||
|
||||
|
||||
// 异步触发事件,支持取消传播,并支持在监听处理后调用异步函数 defaultAsyncHandler
|
||||
// 使用方式:await eventBus.emit(eventName, data, defaultAsyncHandler)
|
||||
// defaultAsyncHandler 会在每个监听器执行后被调用,签名为 defaultAsyncHandler(event, handler, handlerResult)
|
||||
// 如果 defaultAsyncHandler 返回 Promise,会等待其 resolve
|
||||
// 如果 allowContinuePropagation 为 false,事件触发后将立即返回,不继续传播
|
||||
// 如果 stopOnError 为 true,在任意监听器抛出错误后立即停止传播
|
||||
// 如果 allowAsyncHandlerRun 为 true,在每个监听器执行后调用 defaultAsyncHandler
|
||||
// 如果 allowAsyncHandlerRun 为 false,不调用 defaultAsyncHandler
|
||||
// 注意:如果 allowAsyncHandlerRun 为 false,defaultAsyncHandler 不会被调用,也不会等待其 resolve
|
||||
async emit(eventName, data, defaultAsyncHandler, { allowContinuePropagation = true, stopOnError = false, allowAsyncHandlerRun = true } = {}) {
|
||||
// 先创建事件对象,方便传入 defaultAsyncHandler
|
||||
const event = this.createEvent(eventName, data)
|
||||
|
||||
// helper to call defaultAsyncHandler only when allowed
|
||||
const callDefaultAsyncHandler = async (evt, handler, handlerResult) => {
|
||||
if (typeof defaultAsyncHandler !== 'function' || !allowAsyncHandlerRun) return
|
||||
try {
|
||||
const res = defaultAsyncHandler(evt, handler, handlerResult)
|
||||
if (res instanceof Promise) {
|
||||
const awaited = await res
|
||||
if (awaited === false) evt.preventDefault()
|
||||
} else {
|
||||
if (res === false) evt.preventDefault()
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`EventBus defaultAsyncHandler error for ${eventName}:`, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是 H5 平台且需要触发 DOM 事件
|
||||
if (this.platform === 'h5' && data && data.triggerDomEvent) {
|
||||
const domResult = this.domBridge.triggerDomEventFromEventBus(
|
||||
this.getDomEventName(eventName),
|
||||
data.detail
|
||||
)
|
||||
|
||||
// 调用 defaultAsyncHandler(仅当允许)
|
||||
await callDefaultAsyncHandler(event, null, domResult)
|
||||
|
||||
// 如果不允许继续传播,则直接返回(根据 defaultPrevented 判断结果)
|
||||
if (!allowContinuePropagation) {
|
||||
return !event.defaultPrevented
|
||||
}
|
||||
// 否则继续走普通 EventBus 处理(fallthrough)
|
||||
}
|
||||
|
||||
// 普通 EventBus 触发
|
||||
const handlers = this.events.get(eventName)
|
||||
|
||||
// 如果没有监听器,执行 defaultAsyncHandler(如果有),并返回结果
|
||||
if (!handlers) {
|
||||
await callDefaultAsyncHandler(event, null, true)
|
||||
return !event.defaultPrevented
|
||||
}
|
||||
|
||||
// 如果不允许继续传播,则不执行任何监听器,只调用一次 defaultAsyncHandler(若提供),然后返回
|
||||
if (!allowContinuePropagation) {
|
||||
await callDefaultAsyncHandler(event, null, true)
|
||||
return !event.defaultPrevented
|
||||
}
|
||||
|
||||
// 按优先级排序执行
|
||||
const sortedHandlers = Array.from(handlers).sort((a, b) => {
|
||||
return (b.options?.priority || 0) - (a.options?.priority || 0)
|
||||
})
|
||||
|
||||
// 按优先级顺序执行每个监听器
|
||||
for (const handler of sortedHandlers) {
|
||||
if (event.defaultPrevented) break
|
||||
|
||||
try {
|
||||
// 支持监听器返回 Promise 或同步值
|
||||
const result = handler.callback(event)
|
||||
const awaitedResult = result instanceof Promise ? await result : result
|
||||
|
||||
// 如果回调返回 false,也停止默认行为
|
||||
if (awaitedResult === false) {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
// 在每个监听器执行后,如果允许并且提供了 defaultAsyncHandler,就调用并等待它
|
||||
await callDefaultAsyncHandler(event, handler, awaitedResult)
|
||||
} catch (error) {
|
||||
console.error(`EventBus ${eventName} error:`, error)
|
||||
// 如果全局或该 handler 指定遇错停止传播,则停止
|
||||
if (stopOnError || handler.options?.stopOnError) {
|
||||
break
|
||||
}
|
||||
// 否则继续下一个 handler
|
||||
}
|
||||
|
||||
// 一次性监听自动移除
|
||||
if (handler.options?.once) {
|
||||
this.off(eventName, handler)
|
||||
}
|
||||
}
|
||||
|
||||
return !event.defaultPrevented
|
||||
}
|
||||
|
||||
|
||||
// 移除监听
|
||||
off(eventName, handler) {
|
||||
const handlers = this.events.get(eventName)
|
||||
if (handlers) {
|
||||
handlers.delete(handler)
|
||||
if (handlers.size === 0) {
|
||||
this.events.delete(eventName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移除多个事件监听
|
||||
offMany(eventNames, handler) {
|
||||
eventNames.forEach(eventName => this.off(eventName, handler))
|
||||
}
|
||||
|
||||
// 移除所有监听
|
||||
offAll(eventName) {
|
||||
this.events.delete(eventName)
|
||||
}
|
||||
|
||||
// 一次性监听
|
||||
once(eventName, callback, options = {}) {
|
||||
return this.on(eventName, callback, { ...options, once: true })
|
||||
}
|
||||
|
||||
// 前置监听(高优先级)
|
||||
preOn(eventName, callback) {
|
||||
return this.on(eventName, callback, { priority: 100 })
|
||||
}
|
||||
|
||||
// 后置监听(低优先级)
|
||||
postOn(eventName, callback) {
|
||||
return this.on(eventName, callback, { priority: -100 })
|
||||
}
|
||||
|
||||
// 判断是否是 DOM 事件
|
||||
isDomEvent(eventName) {
|
||||
const domEvents = ['click', 'touchstart', 'touchend', 'mousedown', 'mouseup']
|
||||
return domEvents.includes(eventName.toLowerCase())
|
||||
}
|
||||
|
||||
// 获取对应的 DOM 事件名
|
||||
getDomEventName(eventName) {
|
||||
const map = {
|
||||
'tap': 'click',
|
||||
'click': 'click',
|
||||
'touchstart': 'touchstart',
|
||||
'touchend': 'touchend'
|
||||
}
|
||||
return map[eventName] || eventName
|
||||
}
|
||||
|
||||
// 创建可取消的事件对象
|
||||
createEvent(eventName, data) {
|
||||
const event = {
|
||||
type: eventName,
|
||||
data,
|
||||
timestamp: Date.now(),
|
||||
defaultPrevented: false,
|
||||
_isPropagationStopped: false
|
||||
}
|
||||
|
||||
// 阻止事件继续传播
|
||||
event.preventDefault = function () {
|
||||
this.defaultPrevented = true
|
||||
}
|
||||
|
||||
// 停止传播
|
||||
event.stopPropagation = function () {
|
||||
this._isPropagationStopped = true
|
||||
}
|
||||
|
||||
event.isPropagationStopped = function () {
|
||||
return this._isPropagationStopped
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
}
|
||||
|
||||
export default new EventBus()
|
||||
@@ -1,77 +1,90 @@
|
||||
<template>
|
||||
<view class="diy-picture" :style="style">
|
||||
<view class="fui-picture">
|
||||
<view v-for="(item,index) in value.list" style="line-height: 0;">
|
||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-if="item.link.wap_url" @click="redirectTo(item.link)"></image>
|
||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else @click="previewImg(item.imageUrl)"></image>
|
||||
</view>
|
||||
<!-- <view wx:if="{{!childitem.linkurl}}" bindtap="previewImg" data-src="{{childitem.imgurl}}" style="padding:{{diyitem.style.paddingtop==0?0:diyitem.style.paddingtop+'rpx'}} {{diyitem.style.paddingleft==0?0:diyitem.style.paddingleft+'rpx'}}" wx:for="{{diyitem.data}}" wx:for-index="childid" wx:for-item="childitem" wx:key="{{childid}}">
|
||||
<image mode="widthFix" src="{{childitem.imgurl}}" style="{{bannerheight?'height:'+bannerheight+'px':'height:auto'}}"></image>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'diy-picture',
|
||||
props: {
|
||||
value: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// this.getDataList();
|
||||
},
|
||||
watch: {
|
||||
// 组件刷新监听
|
||||
componentRefresh: function(nval) {
|
||||
// this.getDataList();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
var css = '';
|
||||
css += 'background-color:' + this.value.contentBgColor + ';';
|
||||
if (this.value.elementAngle == 'round') {
|
||||
css += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
|
||||
css += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
|
||||
css += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
|
||||
css += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
|
||||
}
|
||||
return css;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
previewImg(img){
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [this.$util.img(img)],
|
||||
success: function (res) {},
|
||||
fail: function (res) {},
|
||||
complete: function (res) {},
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
redirectTo(link) {
|
||||
if (link.wap_url) {
|
||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
||||
this.$refs.login.open(link.wap_url);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.$util.diyRedirectTo(link);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
<template>
|
||||
<view class="diy-picture" :style="style">
|
||||
<view class="fui-picture">
|
||||
<view v-for="(item,index) in value.list" style="line-height: 0;">
|
||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-if="item.link.wap_url" @click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else @click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
||||
</view>
|
||||
<!-- <view wx:if="{{!childitem.linkurl}}" bindtap="previewImg" data-src="{{childitem.imgurl}}" style="padding:{{diyitem.style.paddingtop==0?0:diyitem.style.paddingtop+'rpx'}} {{diyitem.style.paddingleft==0?0:diyitem.style.paddingleft+'rpx'}}" wx:for="{{diyitem.data}}" wx:for-index="childid" wx:for-item="childitem" wx:key="{{childid}}">
|
||||
<image mode="widthFix" src="{{childitem.imgurl}}" style="{{bannerheight?'height:'+bannerheight+'px':'height:auto'}}"></image>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import minx from './minx.js'
|
||||
export default {
|
||||
name: 'diy-picture',
|
||||
props: {
|
||||
value: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// this.getDataList();
|
||||
},
|
||||
watch: {
|
||||
// 组件刷新监听
|
||||
componentRefresh: function(nval) {
|
||||
// this.getDataList();
|
||||
}
|
||||
},
|
||||
mixins: [minx],
|
||||
computed: {
|
||||
style() {
|
||||
var css = '';
|
||||
css += 'background-color:' + this.value.contentBgColor + ';';
|
||||
if (this.value.elementAngle == 'round') {
|
||||
css += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
|
||||
css += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
|
||||
css += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
|
||||
css += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
|
||||
}
|
||||
return css;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
previewImg(img){
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [this.$util.img(img)],
|
||||
success: function (res) {},
|
||||
fail: function (res) {},
|
||||
complete: function (res) {},
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
redirectTo(link) {
|
||||
if (link.wap_url) {
|
||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
||||
this.$refs.login.open(link.wap_url);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.$util.diyRedirectTo(link);
|
||||
},
|
||||
|
||||
async handlerClick(item) {
|
||||
await this.__$emitEvent({eventName: 'pictureTap', data: item, promiseCallback: (event, handler, awaitedResult) => {
|
||||
if (!awaitedResult) return;
|
||||
if (item.link.wap_url) {
|
||||
this.redirectTo(item.link);
|
||||
} else {
|
||||
this.previewImg(item.imageUrl);
|
||||
}
|
||||
}})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
8
components/diy-components/minx.js
Normal file
8
components/diy-components/minx.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
methods: {
|
||||
// 异步触发事件
|
||||
async __$emitEvent(payload = {eventName: '__unnamedEvent', data: {}, promiseCallback: null}) {
|
||||
await this.$eventBus?.emit(payload.eventName, payload.data, payload.promiseCallback)
|
||||
},
|
||||
}
|
||||
}
|
||||
124
main.js
124
main.js
@@ -1,59 +1,67 @@
|
||||
// #ifdef H5
|
||||
import './common/js/pc'
|
||||
// #endif
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import Util from './common/js/util.js'
|
||||
import Http from './common/js/http.js'
|
||||
import Lang from './common/js/lang.js'
|
||||
import Config from './common/js/config.js'
|
||||
import globalConfig from './common/js/golbalConfig.js';
|
||||
import {
|
||||
uniStorage
|
||||
} from './common/js/storage.js'
|
||||
|
||||
Vue.prototype.$store = store //挂在vue
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.prototype.$util = Util;
|
||||
Vue.prototype.$api = Http;
|
||||
|
||||
Vue.prototype.$langConfig = Lang; //语言包对象
|
||||
Vue.prototype.$lang = Lang.lang; //解析语言包
|
||||
|
||||
Vue.prototype.$config = Config;
|
||||
|
||||
Vue.mixin(globalConfig);
|
||||
|
||||
App.mpType = 'app';
|
||||
|
||||
// 重写存储,增加前缀
|
||||
uniStorage();
|
||||
|
||||
//常用组件
|
||||
import loadingCover from '@/components/loading-cover/loading-cover.vue';
|
||||
Vue.component('loading-cover', loadingCover);
|
||||
|
||||
import nsEmpty from '@/components/ns-empty/ns-empty.vue';
|
||||
Vue.component('ns-empty', nsEmpty);
|
||||
|
||||
import MescrollUni from "@/components/mescroll/my-list-mescroll.vue";
|
||||
Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件
|
||||
|
||||
import MescrollBody from "@/components/mescroll/mescroll-body.vue"
|
||||
Vue.component('mescroll-body', MescrollBody);
|
||||
|
||||
import NsLogin from "@/components/ns-login/ns-login.vue"
|
||||
Vue.component('ns-login', NsLogin);
|
||||
|
||||
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue';
|
||||
Vue.component('privacy-popup', PrivacyPopup)
|
||||
|
||||
const app = new Vue({
|
||||
...App,
|
||||
store
|
||||
})
|
||||
|
||||
// #ifdef H5
|
||||
import './common/js/pc'
|
||||
// #endif
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import Util from './common/js/util.js'
|
||||
import Http from './common/js/http.js'
|
||||
import Lang from './common/js/lang.js'
|
||||
import Config from './common/js/config.js'
|
||||
import EventBus from './common/js/event-bus.js'
|
||||
import DomEventBridge from './common/js/dom-event-bridge.js'
|
||||
import globalConfig from './common/js/golbalConfig.js';
|
||||
import {
|
||||
uniStorage
|
||||
} from './common/js/storage.js'
|
||||
|
||||
Vue.prototype.$store = store //挂在vue
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.prototype.$util = Util;
|
||||
Vue.prototype.$api = Http;
|
||||
|
||||
Vue.prototype.$langConfig = Lang; //语言包对象
|
||||
Vue.prototype.$lang = Lang.lang; //解析语言包
|
||||
|
||||
Vue.prototype.$config = Config;
|
||||
|
||||
|
||||
// #ifdef H5
|
||||
EventBus.setDomBridge(DomEventBridge)
|
||||
// #endif
|
||||
Vue.prototype.$eventBus = EventBus;
|
||||
|
||||
Vue.mixin(globalConfig);
|
||||
|
||||
App.mpType = 'app';
|
||||
|
||||
// 重写存储,增加前缀
|
||||
uniStorage();
|
||||
|
||||
//常用组件
|
||||
import loadingCover from '@/components/loading-cover/loading-cover.vue';
|
||||
Vue.component('loading-cover', loadingCover);
|
||||
|
||||
import nsEmpty from '@/components/ns-empty/ns-empty.vue';
|
||||
Vue.component('ns-empty', nsEmpty);
|
||||
|
||||
import MescrollUni from "@/components/mescroll/my-list-mescroll.vue";
|
||||
Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件
|
||||
|
||||
import MescrollBody from "@/components/mescroll/mescroll-body.vue"
|
||||
Vue.component('mescroll-body', MescrollBody);
|
||||
|
||||
import NsLogin from "@/components/ns-login/ns-login.vue"
|
||||
Vue.component('ns-login', NsLogin);
|
||||
|
||||
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue';
|
||||
Vue.component('privacy-popup', PrivacyPopup)
|
||||
|
||||
const app = new Vue({
|
||||
...App,
|
||||
store
|
||||
})
|
||||
|
||||
app.$mount()
|
||||
@@ -127,6 +127,7 @@
|
||||
<privacy-popup ref="privacyPopup"></privacy-popup>
|
||||
<!-- #endif -->
|
||||
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
|
||||
<ns-login ref="login"></ns-login>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -140,17 +141,12 @@
|
||||
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
minScrollTop: 100, // 设置回到顶端按钮显示要求,最小滚动距离
|
||||
}
|
||||
},
|
||||
components: {
|
||||
uniPopup,
|
||||
nsNavbar,
|
||||
toTop
|
||||
},
|
||||
mixins: [diyJs, indexJs, scroll]
|
||||
mixins: [diyJs, scroll, indexJs]
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
minScrollTop: 100, // 设置回到顶端按钮显示要求,最小页面滚动距离
|
||||
wechatQrcode: '', // 公众号二维码
|
||||
diyRoute: '/pages/index/index'
|
||||
};
|
||||
@@ -16,8 +17,17 @@ export default {
|
||||
|
||||
},
|
||||
onShow() {
|
||||
// 获取关注公众号二维码
|
||||
this.getFollowQrcode();
|
||||
},
|
||||
mounted() {
|
||||
// 监听图片点击事件
|
||||
this.unsubscribe = this.$eventBus?.on('pictureTap', this._handleDiyGroupInteractionEvent);
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 移除图片点击事件监听
|
||||
if (this.unsubscribe) this.unsubscribe();
|
||||
},
|
||||
methods: {
|
||||
// 关注公众号
|
||||
getFollowQrcode() {
|
||||
@@ -37,5 +47,17 @@ export default {
|
||||
officialAccountsClose() {
|
||||
this.$refs.officialAccountsPopup.close();
|
||||
},
|
||||
// 统一处理点击及触摸事件
|
||||
_handleDiyGroupInteractionEvent(payload) {
|
||||
if (this.storeToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 打开登录弹窗
|
||||
this.$refs.login?.open();
|
||||
|
||||
// 阻止事件继续传播
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user