Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
}
}
}
if (isObject(value)) {
for (const i in value) {
if (!oldValue || value[i] !== (oldValue as StyleValue)[i]) {
setStyle(style, i, value[i])
}
}
}
}
} else if (isEventName(name)) {
setEvent(dom, name, value, oldValue)
} else if (
!isFunction(value) &&
name !== 'dangerouslySetInnerHTML' // TODO: 实现 innerHTML
) {
if (value == null) {
dom.removeAttribute(name)
} else {
dom.setAttribute(name, value as string)
}
}
}
if (path.endsWith(Shortcuts.Childnodes)) {
resetPaths.add(path)
}
data[path] = value
}
for (const path in data) {
resetPaths.forEach(p => {
// 已经重置了数组,就不需要分别再设置了
if (path.includes(p) && path !== p) {
delete data[path]
}
})
const value = data[path]
if (isFunction(value)) {
data[path] = value()
}
}
ctx.setData(data, () => {
this.pendingUpdate = false
})
}, 1)
}
export function createVueApp (App: VueInstance) {
let Vue
// webpack 开发模式不会执行 tree-shaking,因此我们需要做此判断
if (process.env.FRAMEWORK === 'vue') {
const v = require('vue')
Vue = v.default || v
}
ensure(!!Vue, '构建 Vue 项目请把 process.env.FRAMEWORK 设置为 \'vue\'')
Vue.config.getTagNamespace = noop
const elements: VNode[] = []
const pages: Array<(h: Vue.CreateElement) => VNode> = []
let appInstance: VueAppInstance
const wrapper = new (Vue as VueConstructor)({
render (h) {
while (pages.length > 0) {
const page = pages.pop()!
elements.push(page(h))
}
return h(App.$options, { ref: 'app' }, elements.slice())
},
if (process.env.FRAMEWORK === 'nerv') {
R = require('nervjs')
ReactDOM = R
}
// 其它 react-like 框架走 react 模式,在 webpack.resolve.alias 设置 react/react-dom 到对应包
if (process.env.FRAMEWORK === 'react') {
R = require('react')
ReactDOM = require('react-dom')
}
react = R
PageContext = R.createContext('')
ensure(!!ReactDOM, '构建 React/Nerv 项目请把 process.env.FRAMEWORK 设置为 \'react\'/\'nerv\' ')
const ref = R.createRef()
let wrapper: AppWrapper
class AppWrapper extends R.Component {
// run createElement() in a render function to make sure that owner is right
private pages: Array<() => React.FunctionComponentElement> = []
private elements: Array> = []
public mount (component: React.FunctionComponent, id: string, cb: () => void) {
const page = () => R.createElement(component, { key: id, tid: id })
this.pages.push(page)
this.forceUpdate(cb)
}
private _stopPropagation (event: TaroEvent) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
let target = this
// eslint-disable-next-line no-cond-assign
while ((target = target.parentNode as this)) {
const listeners = target.__handlers[event.type]
if (!isArray(listeners)) {
continue
}
for (let i = listeners.length; i--;) {
const l = listeners[i]
l._stop = true
}
}
}
}
if (isOnce) {
const wrapper = function () {
handler.apply(this, arguments) // this 指向 Element
this.removeEventListener(type, wrapper)
}
this.addEventListener(type, wrapper, {
...(options as AddEventListenerOptions),
once: false
})
return
}
warn(isCapture, 'The event capture feature is unimplemented.')
if (isArray(handlers)) {
handlers.push(handler)
} else {
this.__handlers[type] = [handler]
}
}
public addEventListener (type: string, handler: EventHandler, options?: boolean | AddEventListenerOptions) {
type = type.toLowerCase()
const handlers = this.__handlers[type]
let isCapture = Boolean(options)
let isOnce = false
if (isObject(options)) {
isCapture = Boolean(options.capture)
isOnce = Boolean(options.once)
}
if (isOnce) {
const wrapper = function () {
handler.apply(this, arguments) // this 指向 Element
this.removeEventListener(type, wrapper)
}
this.addEventListener(type, wrapper, {
...(options as AddEventListenerOptions),
once: false
})
return
}
style.cssText = value
} else {
if (isString(oldValue)) {
style.cssText = ''
oldValue = null
}
if (isObject(oldValue)) {
for (const i in oldValue) {
if (!(value && i in (value as StyleValue))) {
setStyle(style, i, '')
}
}
}
if (isObject(value)) {
for (const i in value) {
if (!oldValue || value[i] !== (oldValue as StyleValue)[i]) {
setStyle(style, i, value[i])
}
}
}
}
} else if (isEventName(name)) {
setEvent(dom, name, value, oldValue)
} else if (
!isFunction(value) &&
name !== 'dangerouslySetInnerHTML' // TODO: 实现 innerHTML
) {
if (value == null) {
dom.removeAttribute(name)
} else {
name === 'key' ||
name === 'children' ||
name === 'ref'
) {
// skip
} else if (name === 'style') {
const style = dom.style
if (isString(value)) {
style.cssText = value
} else {
if (isString(oldValue)) {
style.cssText = ''
oldValue = null
}
if (isObject(oldValue)) {
for (const i in oldValue) {
if (!(value && i in (value as StyleValue))) {
setStyle(style, i, '')
}
}
}
if (isObject(value)) {
for (const i in value) {
if (!oldValue || value[i] !== (oldValue as StyleValue)[i]) {
setStyle(style, i, value[i])
}
}
}
}
} else if (isEventName(name)) {
function setProperty (dom: TaroElement, name: string, value: unknown, oldValue?: unknown) {
name = name === 'className' ? 'class' : name
if (
name === 'key' ||
name === 'children' ||
name === 'ref'
) {
// skip
} else if (name === 'style') {
const style = dom.style
if (isString(value)) {
style.cssText = value
} else {
if (isString(oldValue)) {
style.cssText = ''
oldValue = null
}
if (isObject(oldValue)) {
for (const i in oldValue) {
if (!(value && i in (value as StyleValue))) {
setStyle(style, i, '')
}
}
}
if (isObject(value)) {
for (const i in value) {
if (!oldValue || value[i] !== (oldValue as StyleValue)[i]) {
setStyle(style, i, value[i])