Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tenon): 修复 tenon 错误无法捕获问题 && 添加 treeview 更新视图 #437

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Temporary Items
# Log
*.log

# Node version
.node-version

# Web
node_modules
coverage
Expand Down
3 changes: 2 additions & 1 deletion tenon/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ module.exports = {
'error',
'ObjectExpression > SpreadElement',
'ObjectPattern > RestElement'
]
],
'no-restricted-syntax': 'off'
},
overrides: [
// tests, no restrictions (runs in Node / jest with jsdom)
Expand Down
15 changes: 12 additions & 3 deletions tenon/packages/tenon-dev-tool/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,21 @@ export function run(container: any, type: string = 'tenon-vue') {
'getViewTree': function (ws: any, params: any) {
let data = getViewData(formatedNode, type)
viewMap = data.viewMap
if (formatedNode?.element?.dbg_getDescription) {
formatedNode.element.dbg_getDescription((node: any) => {
if (params.refresh) {
formatedNode?.element?.dbg_getDescription((node: any) => {
// tenon 特殊处理,外层包裹一个 template,和组件对齐
if(type === 'tenon-vue'){
node.tagName = 'template'
}
let refreshFormatedNode = formatNode(node, type, true)
let refreshData = getViewData(refreshFormatedNode, type)
viewMap = refreshData.viewMap;
sendMessage(ws, {
method: 'setViewTree',
params: {
...params,
viewTree: [data.simpleRoot],
refresh: true,
viewTree: [refreshData.simpleRoot],
path: path,
baseInfo: __GLOBAL__.Hummer.env,
devToolType: type
Expand All @@ -60,6 +68,7 @@ export function run(container: any, type: string = 'tenon-vue') {
method: 'setViewTree',
params: {
...params,
refresh: false,
viewTree: [data.simpleRoot],
path: path,
baseInfo: __GLOBAL__.Hummer.env,
Expand Down
16 changes: 13 additions & 3 deletions tenon/packages/tenon-dev-tool/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ export const getPartUrlByParam = (url: string, param: string) => {
* @param type
* @returns simplenode
*/
export const formatNode = function (node: any, type: string = 'tenon-vue') {
export const formatNode = function (node: any, type: string = 'tenon-vue', refresh = false) {
let formatedNode = Object.create({})
const treeTraveler = function (node: any, rootView: any) {
processView(node, rootView, type)
processView(node, rootView, type, refresh)
if (node.children) {
// hummer children类型Array tenon-vue类型Set 处理一下
let arr = Array.from(node.children)
Expand Down Expand Up @@ -179,7 +179,7 @@ export const getViewData = function (container: any, type: string = 'tenon-vue')
// return res
// })
// }
const processView = function (node: any, rootView: any, type: string = 'tenon-vue') {
const processView = function (node: any, rootView: any, type: string = 'tenon-vue', refresh = false) {
let nameKey = '__NAME',
idKey = '__view_id',
textKey = '_text',
Expand All @@ -198,6 +198,16 @@ const processView = function (node: any, rootView: any, type: string = 'tenon-vu
srcKey = 'content'
rootView.style = node.element.style
break;
case 'tenon-vue':
// 刷新之后的节点要格式化一下
if(refresh){
nameKey = 'tagName';
idKey = 'id';
textKey = 'content';
srcKey = 'content';
rootView.style = node.element.style;
}
break
default:
break;
}
Expand Down
27 changes: 18 additions & 9 deletions tenon/packages/tenon-vue/src/runtime/handlers/events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Base } from '../nodes/Base'
import {
ComponentInternalInstance
ComponentInternalInstance,
callWithAsyncErrorHandling
} from '@vue/runtime-core'

const LongPress = 'longpress'
Expand Down Expand Up @@ -34,19 +35,27 @@ export function patchEvents(
}
}

function patchInvokerHandler(initialValue: any, instance: ComponentInternalInstance | null, args: any) {
// TODO: Array.isArray兼容性测试
if (Array.isArray(initialValue)) {
return initialValue.map(func => () => func && func.apply(instance, args))
} else {
return () => initialValue.apply(instance, args)
}
}

function createInvoker(
initialValue: EventValue,
instance: ComponentInternalInstance | null
){
// TODO: Array.isArray兼容性测试
const invoker:Invoker = (...args) => {
if(Array.isArray(initialValue)){
initialValue.forEach((func:Function) => {
func.apply(instance, [...args])
})
}else {
initialValue.apply(instance, [...args])
}
// 搜集 Error
callWithAsyncErrorHandling(
patchInvokerHandler(initialValue, instance, [...args]),
instance,
5,
[...args]
);
}
invoker.value = initialValue
initialValue.invoker = invoker
Expand Down
21 changes: 14 additions & 7 deletions tenon/packages/tenon-vue/src/runtime/helper/lifecycle-helper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ComponentInternalInstance, callWithAsyncErrorHandling } from "@vue/runtime-core"
interface LifeCycleMixins {
onLoad: Array<any>,
onReady: Array<any>,
Expand Down Expand Up @@ -78,14 +79,15 @@ export const initPageLifeCycle = (container: any, instance: any, config: any) =>

container[lifecycle] = () => {
globalLifeCycleMixins[lifecycle].forEach((func: Function) => {
applyLifeCycle(instance, func)
})
extendOptions && applyLifeCycle(instance, extendOptions[lifecycle])
lifecycleAsyncErrorTracker(instance, func);
});
extendOptions && lifecycleAsyncErrorTracker(instance, extendOptions[lifecycle]);

lifeCycleMixins[lifecycle].forEach((func: Function) => {
applyLifeCycle(instance, func)
})
applyLifeCycle(instance, config[lifecycle])
}
lifecycleAsyncErrorTracker(instance, func);
});
lifecycleAsyncErrorTracker(instance, config[lifecycle]);
};
})
}

Expand Down Expand Up @@ -116,3 +118,8 @@ function applyPageMixin(mixins: any): (LifeCycleMixins | null) {
function applyLifeCycle(instance: any, func: Function) {
return func && func.apply(instance);
}
function lifecycleAsyncErrorTracker(instance: any, func: Function){
// instance 是编译主入口的 proxy 格式数据,而 instance._ 是 createComponentInstance 实例
const errorInternalInstance: ComponentInternalInstance = instance._
func && callWithAsyncErrorHandling(() => applyLifeCycle(instance, func), errorInternalInstance, 10)
}
4 changes: 3 additions & 1 deletion tenon/packages/tenon-vue/src/runtime/nodes/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ export class Base {
private setCacheProp(key:string, value:any){
// 如果是 datattr 格式的属性,缓存到 dataset 中,方便事件可以获取到 dataset (Chameleon事件需求)
if(/^data/.test(key)){
let dataKey = key.slice(4).toLowerCase()
// 父组件 data 开头就截取4个,子组件 data- 开头就截取5个
let cutNum = key.includes('-') ? 5 : 4
let dataKey = key.slice(cutNum).toLowerCase()
if(dataKey){
this.dataset[dataKey] = value
}
Expand Down