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

feat(h5): wxs event

上级 7aeb8cc5
{ {
"name": "@dcloudio/uni-cli-shared", "name": "@dcloudio/uni-cli-shared",
"version": "0.2.991", "version": "0.2.993",
"description": "uni-cli-shared", "description": "uni-cli-shared",
"main": "lib/index.js", "main": "lib/index.js",
"files": [ "files": [
......
...@@ -4,18 +4,25 @@ const { ...@@ -4,18 +4,25 @@ const {
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/ const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
function processEvent (expr) { function processEvent(expr, filterModules) {
const isMethodPath = simplePathRE.test(expr) const isMethodPath = simplePathRE.test(expr)
if (isMethodPath) { if (isMethodPath) {
expr = expr + '($event)' if (filterModules.find(name => expr.indexOf(name + '.') === 0)) {
return `
$event = $handleWxsEvent($event);
${expr}($event, $getComponentDescriptor())
`
} else {
expr = expr + '($event)'
}
} }
return ` return `
$event = $handleEvent($event); $event = $handleEvent($event);
${expr} ${expr}
` `
} }
function hasOwn (obj, key) { function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key) return hasOwnProperty.call(obj, key)
} }
...@@ -26,7 +33,7 @@ const deprecated = { ...@@ -26,7 +33,7 @@ const deprecated = {
} }
} }
function addTag (tag) { function addTag(tag) {
if (!process.UNI_TAGS) { if (!process.UNI_TAGS) {
process.UNI_TAGS = new Set() process.UNI_TAGS = new Set()
} }
...@@ -36,7 +43,7 @@ function addTag (tag) { ...@@ -36,7 +43,7 @@ function addTag (tag) {
module.exports = { module.exports = {
preserveWhitespace: false, preserveWhitespace: false,
modules: [require('../format-text'), { modules: [require('../format-text'), {
preTransformNode (el, { preTransformNode(el, {
warn warn
}) { }) {
if (el.tag.indexOf('v-uni-') === 0) { if (el.tag.indexOf('v-uni-') === 0) {
...@@ -46,8 +53,9 @@ module.exports = { ...@@ -46,8 +53,9 @@ module.exports = {
el.tag = 'v-uni-' + el.tag el.tag = 'v-uni-' + el.tag
} }
}, },
postTransformNode (el, { postTransformNode(el, {
warn warn,
filterModules
}) { }) {
if (el.tag === 'block') { if (el.tag === 'block') {
el.tag = 'template' el.tag = 'template'
...@@ -65,6 +73,7 @@ module.exports = { ...@@ -65,6 +73,7 @@ module.exports = {
} }
} }
if (el.events) { if (el.events) {
filterModules = filterModules || []
const { const {
events: eventsMap events: eventsMap
} = deprecated } = deprecated
...@@ -81,11 +90,10 @@ module.exports = { ...@@ -81,11 +90,10 @@ module.exports = {
const handlers = el.events[name] const handlers = el.events[name]
if (Array.isArray(handlers)) { if (Array.isArray(handlers)) {
handlers.forEach(handler => { handlers.forEach(handler => {
handler.value = processEvent( handler.value = processEvent(handler.value, filterModules)
handler.value)
}) })
} else { } else {
handlers.value = processEvent(handlers.value) handlers.value = processEvent(handlers.value, filterModules)
} }
}) })
} }
......
...@@ -10,7 +10,7 @@ const { ...@@ -10,7 +10,7 @@ const {
const WebpackHtmlAppendPlugin = require('../../packages/webpack-html-append-plugin') const WebpackHtmlAppendPlugin = require('../../packages/webpack-html-append-plugin')
function resolve (dir) { function resolve(dir) {
return path.resolve(__dirname, '../../', dir) return path.resolve(__dirname, '../../', dir)
} }
...@@ -61,7 +61,7 @@ if (devServer && Object.keys(devServer).length) { ...@@ -61,7 +61,7 @@ if (devServer && Object.keys(devServer).length) {
module.exports = { module.exports = {
vueConfig, vueConfig,
webpackConfig (webpackConfig) { webpackConfig(webpackConfig) {
return { return {
devtool: process.env.NODE_ENV === 'production' ? false : 'source-map', devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',
resolve: { resolve: {
...@@ -80,6 +80,11 @@ module.exports = { ...@@ -80,6 +80,11 @@ module.exports = {
before: [`<template><App :keepAliveInclude="keepAliveInclude"/></template>`] before: [`<template><App :keepAliveInclude="keepAliveInclude"/></template>`]
} }
} }
}, {
resourceQuery: /vue&type=template/,
use: [{
loader: resolve('packages/h5-vue-template-loader')
}]
}, { }, {
resourceQuery: /blockType=wxs/, resourceQuery: /blockType=wxs/,
use: [{ use: [{
...@@ -95,7 +100,7 @@ module.exports = { ...@@ -95,7 +100,7 @@ module.exports = {
plugins plugins
} }
}, },
chainWebpack (webpackConfig) { chainWebpack(webpackConfig) {
webpackConfig.plugins.delete('copy') webpackConfig.plugins.delete('copy')
if (!process.env.UNI_OPT_PREFETCH) { if (!process.env.UNI_OPT_PREFETCH) {
......
{ {
"name": "@dcloudio/vue-cli-plugin-uni", "name": "@dcloudio/vue-cli-plugin-uni",
"version": "0.9.527", "version": "0.9.528",
"description": "uni-app plugin for vue-cli 3", "description": "uni-app plugin for vue-cli 3",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
......
const path = require('path')
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)
/* eslint-disable no-mixed-operators */
const filterModules = JSON.parse(params && params['filter-modules'] || '{}')
Object.assign(vueLoaderOptions.options.compilerOptions, {
filterModules: Object.keys(filterModules)
})
} else {
throw new Error('vue-loader-options parse error')
}
return content
}
{ {
"name": "@dcloudio/webpack-uni-pages-loader", "name": "@dcloudio/webpack-uni-pages-loader",
"version": "0.2.874", "version": "0.2.875",
"description": "uni-app pages.json loader", "description": "uni-app pages.json loader",
"main": "lib/index.js", "main": "lib/index.js",
"files": [ "files": [
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
"strip-json-comments": "^2.0.1" "strip-json-comments": "^2.0.1"
}, },
"uni-app": { "uni-app": {
"compilerVersion": "2.2.3" "compilerVersion": "2.2.4"
}, },
"gitHead": "08ea04b669e93f0db3acb2dfa38138298edd5789" "gitHead": "08ea04b669e93f0db3acb2dfa38138298edd5789"
} }
...@@ -9,6 +9,10 @@ import { ...@@ -9,6 +9,10 @@ import {
import initBehaviors from './behaviors' import initBehaviors from './behaviors'
import {
createComponentDescriptor
} from './wxs/component-descriptor'
function pageMounted () { function pageMounted () {
// 通知 Service,View 层已 ready // 通知 Service,View 层已 ready
UniViewJSBridge.publishHandler('onPageReady', {}, this.$page.id) UniViewJSBridge.publishHandler('onPageReady', {}, this.$page.id)
...@@ -25,17 +29,36 @@ export default { ...@@ -25,17 +29,36 @@ export default {
} = {}) { } = {}) {
initEvents() initEvents()
const findUniTarget = function ($event, $el) {
let target = $event.target
for (; target && target !== $el; target = target.parentNode) {
if (target.tagName && target.tagName.indexOf('UNI-') === 0) {
break
}
}
return target
}
Vue.prototype.$handleEvent = function ($event) { Vue.prototype.$handleEvent = function ($event) {
if ($event instanceof Event) { // 未处理的 event 对象 需要对 target 校正及包装 if ($event instanceof Event) { // 未处理的 event 对象 需要对 target 校正及包装
// 查找 uniTarget // 查找 uniTarget
let target = $event.target const target = findUniTarget($event, this.$el)
const $el = this.$el $event = processEvent.call(this, $event.type, $event, {}, target || $event.target, $event.currentTarget)
for (; target && target !== $el; target = target.parentNode) { }
if (target.tagName && target.tagName.indexOf('UNI-') === 0) { return $event
break }
}
} Vue.prototype.$getComponentDescriptor = function (vm) {
return createComponentDescriptor(vm || this)
}
Vue.prototype.$handleWxsEvent = function ($event) {
if ($event instanceof Event) { // 未处理的 event 对象 需要对 target 校正及包装
// 查找 uniTarget
const target = findUniTarget($event, this.$el)
const instance = target && target.__vue__ && target.__vue__.$getComponentDescriptor()
$event = processEvent.call(this, $event.type, $event, {}, target || $event.target, $event.currentTarget) $event = processEvent.call(this, $event.type, $event, {}, target || $event.target, $event.currentTarget)
$event.instance = instance
} }
return $event return $event
} }
...@@ -43,13 +66,13 @@ export default { ...@@ -43,13 +66,13 @@ export default {
Vue.mixin({ Vue.mixin({
beforeCreate () { beforeCreate () {
const options = this.$options const options = this.$options
const wxs = options.wxs const wxs = options.wxs
if (wxs) { if (wxs) {
Object.keys(wxs).forEach(module => { Object.keys(wxs).forEach(module => {
this[module] = wxs[module] this[module] = wxs[module]
}) })
} }
if (options.behaviors && options.behaviors.length) { if (options.behaviors && options.behaviors.length) {
initBehaviors(options, this) initBehaviors(options, this)
......
import {
isPlainObject
} from 'uni-shared'
const CLASS_RE = /^\s+|\s+$/g
const WXS_CLASS_RE = /\s+/
function getWxsClsArr (clsArr, classList, isAdd) {
const wxsClsArr = []
let checkClassList = function (cls) {
if (isAdd) {
checkClassList = function (cls) {
return !classList.contains(cls)
}
} else {
checkClassList = function (cls) {
return classList.contains(cls)
}
}
return checkClassList(cls)
}
clsArr.forEach(cls => {
cls = cls.replace(CLASS_RE, '')
checkClassList(cls) && wxsClsArr.push(cls)
})
return wxsClsArr
}
function parseStyleText (cssText) {
const res = {}
const listDelimiter = /;(?![^(]*\))/g
const propertyDelimiter = /:(.+)/
cssText.split(listDelimiter).forEach(function (item) {
if (item) {
const tmp = item.split(propertyDelimiter)
tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim())
}
})
return res
}
class ComponentDescriptor {
constructor (vm) {
this.$vm = vm
this.$el = vm.$el
}
selectComponent (selector) {
if (!this.$el || !selector) {
return
}
const el = this.$el.querySelector(selector)
return el && el.__vue__ && createComponentDescriptor(el.__vue__)
}
selectAllComponents (selector) {
if (!this.$el || !selector) {
return []
}
const descriptors = []
this.$el.querySelectorAll(selector).forEach(el => {
el.__vue__ && descriptors.push(createComponentDescriptor(el.__vue__))
})
return descriptors
}
setStyle (style) {
if (!this.$el || !style) {
return this
}
if (typeof style === 'string') {
style = parseStyleText(style)
}
if (isPlainObject(style)) {
this.$el.__wxsStyle = style
}
return this
}
addClass (...clsArr) {
if (!this.$el || !clsArr.length) {
return this
}
const wxsClsArr = getWxsClsArr(clsArr, this.$el.classList, true)
if (wxsClsArr.length) {
const wxsClass = this.$el.__wxsClass || ''
this.$el.__wxsClass = wxsClass + (wxsClass ? ' ' : '') + wxsClsArr.join(' ')
this.$vm.$forceUpdate()
}
return this
}
removeClass (...clsArr) {
if (!this.$el || !clsArr.length) {
return this
}
const oldWxsClsArr = (this.$el.__wxsClass || '').split(WXS_CLASS_RE)
const wxsClsArr = getWxsClsArr(clsArr, this.$el.classList, false)
if (wxsClsArr.length) {
oldWxsClsArr.length && wxsClsArr.forEach(cls => {
const clsIndex = oldWxsClsArr.findIndex(oldCls => oldCls === cls)
if (clsIndex !== -1) {
oldWxsClsArr.splice(clsIndex, 1)
}
})
this.$el.__wxsClass = oldWxsClsArr.join(' ')
this.$vm.$forceUpdate()
}
return this
}
hasClass (cls) {
return this.$el && this.$el.classList.contains(cls)
}
getDataset () {
return this.$el && this.$el.dataset
}
callMethod (funcName, args = {}) {
// TODO 需跨平台
return (this.$vm[funcName] && this.$vm[funcName](JSON.parse(JSON.stringify(args))), this)
}
requestAnimationFrame (callback) {
return (global.requestAnimationFrame(callback), this)
}
getState () {
return this.$el && (this.$el.__wxsState || (this.$el.__wxsState = {}))
}
triggerEvent (eventName, detail = {}, options = {}) {
// TODO options
return (this.$vm.$emit(eventName, detail), this)
}
}
export function createComponentDescriptor (vm) {
if (vm && vm.$el) {
if (!vm.$el.__wxsComponentDescriptor) {
vm.$el.__wxsComponentDescriptor = new ComponentDescriptor(vm)
}
return vm.$el.__wxsComponentDescriptor
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册