Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 306|回复: 0

framework7的改进,以及与vue组合使用遇到的问题以及解决方法 (附vue的原理)

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-30 15:18:25 | 显示全部楼层 |阅读模式

    framework7官方提供了vue+framework7的组合包,但是那个包用起来复杂度较高,而且不灵活。听说bug也不少。

    所以我想用最原始的方式单独使用vue和framework7.

     遇到以下问题:

    1.framework7的router跳转到新的页面,这个页面的代码无法使用一个普通的包含js,css引用的html文件。

       引用的js都要放到主页面中,导致加载速度慢.而且我希望一个html页面可以单独打开,也可以嵌入在单页程序里打开,所以现有的框架并不满足。

      解决方案:修改framework7代码,在router加载新页面的时候,原始版本只是加载页面中class为page的div,修改成加载script和css到主页面,返回后再删除script和css,这样就实现了嵌入完整的html页面到单页程序. 需要代码的可以留言

     

    2.framework7页面过度动画完成之前初始化vue,会导致vue无法工作(变量没有渲染)

       解决办法:应该可以深入研究framework7和vue的代码从底层解决。 但是这里偷懒了,在页面动画完成后,再初始化vue. 

    这样就解决了。但是如果前一页面也用了vue,返回时就没法返回了(解决方案见2)

    3.vue初始化时会将dom上后添加的一些变量都去掉。会导致从使用vue的页面跳转到另一页面,就返回不了了。

      而framework7 会在作为page的div对象上写上一些变量,比如f7Page等。如果在vue初始化之前framework7已经初始化,这些变量会丢失,所以framework7的部分功能就失效了。

    实际应用中,发现router受到了影响。   一个页面使用了vue,之后把page div上的f7Page对象删了,然后从这个页面跳到其他页面,就返回不了了。

      解决方法:修改 vue.js,在vue初始化函数中,有个替换div的操作, 在替换之后,把旧div上的变量再塞回去。具体代码在patch函数中,修改的代码注释为by xiang. 如下:

    return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) {
    if (isUndef(vnode)) {
    if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); }
    return
    }

    var isInitialPatch = false;
    var insertedVnodeQueue = [];

    if (isUndef(oldVnode)) {
    // empty mount (likely as component), create new root element
    isInitialPatch = true;
    createElm(vnode, insertedVnodeQueue, parentElm, refElm);
    } else {
    var isRealElement = isDef(oldVnode.nodeType);
    if (!isRealElement && sameVnode(oldVnode, vnode)) {
    // patch existing root node
    patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly);
    } else {
    if (isRealElement) {
    // mounting to a real element
    // check if this is server-rendered content and if we can perform
    // a successful hydration.
    if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
    oldVnode.removeAttribute(SSR_ATTR);
    hydrating = true;
    }
    if (isTrue(hydrating)) {
    if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
    invokeInsertHook(vnode, insertedVnodeQueue, true);
    return oldVnode
    } else {
    warn(
    'The client-side rendered virtual DOM tree is not matching ' +
    'server-rendered content. This is likely caused by incorrect ' +
    'HTML markup, for example nesting block-level elements inside ' +
    '<p>, or missing <tbody>. Bailing hydration and performing ' +
    'full client-side render.'
    );
    }
    }
    // either not server-rendered, or hydration failed.
    // create an empty node and replace it
    oldVnode = emptyNodeAt(oldVnode);
    }

    // replacing existing element
    var oldElm = oldVnode.elm;
    var parentElm$1 = nodeOps.parentNode(oldElm);

    // create new node
    createElm(
    vnode,
    insertedVnodeQueue,
    // extremely rare edge case: do not insert if old element is in a
    // leaving transition. Only happens when combining transition +
    // keep-alive + HOCs. (#4590)
    oldElm._leaveCb ? null : parentElm$1,
    nodeOps.nextSibling(oldElm)
    );

    // update parent placeholder node element, recursively
    if (isDef(vnode.parent)) {
    var ancestor = vnode.parent;
    var patchable = isPatchable(vnode);
    while (ancestor) {
    for (var i = 0; i < cbs.destroy.length; ++i) {
    cbs.destroy(ancestor);
    }
    ancestor.elm = vnode.elm;
    if (patchable) {
    for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
    cbs.create[i$1](emptyNode, ancestor);
    }
    // #6513
    // invoke insert hooks that may have been merged by create hooks.
    // e.g. for directives that uses the "inserted" hook.
    var insert = ancestor.data.hook.insert;
    if (insert.merged) {
    // start at index 1 to avoid re-invoking component mounted hook
    for (var i$2 = 1; i$2 < insert.fns.length; i$2++) {
    insert.fns[i$2]();
    }
    }
    } else {
    registerRef(ancestor);
    }
    ancestor = ancestor.parent;
    }
    }



    var prop;//by xiang to attach the properties removed by vue. framwork7 set some property such as f7Page to Dom, if that is removed, it will not work properly(i've found a problem in the router. it can not return back if the previous page use vue(f7Page is removed))
    for (prop in oldVnode.elm) {
    if (vnode.elm[prop] === undefined) {
    var op = oldVnode.elm[prop];
    if (op) {
    try {
    vnode.elm[prop] = op;
    } catch (e) {}
    }
    }
    }
    /*
    function setEvt(obj, arr) {

    if (obj.id && obj.dom7Listeners) {
    //
    var son = $$(vnode.elm).find('#' + obj.id)[0];
    if (son && !son.dom7Listeners) {
    son.dom7Listeners = obj.dom7Listeners;
    var evt;
    for (evt in son.dom7Listeners) {
    son.addEventListener(evt, son.dom7Listeners[evt][0].listener, false);
    }
    }
    }
    if (obj.children.length > 0) {
    for (var i = 0; i < obj.children.length; i++) {
    setEvt(obj.children, arr);
    }
    }
    }
    setEvt(oldVnode.elm);*/
    // destroy old node
    if (isDef(parentElm$1)) {
    removeVnodes(parentElm$1, [oldVnode], 0, 0);
    } else if (isDef(oldVnode.tag)) {
    invokeDestroyHook(oldVnode);
    }
    }
    }

    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
    return vnode.elm

    4.vue初始化会将dom上的一些通过代码添加的js事件去掉

        可以按照第前面的思路把事件塞回去,但是实际测试中还是不能完全解决问题,比如picker控件,可以解决点击input弹出选择框,但是选择框滑动之后,input内容不联动。应该可以从底层解决,但是这里偷懒了,在vue加载完毕之后,再去初始化picker控件。

    vue原理解密:

      跟踪vue代码后发现,vue的原理就是把挂载div的outerHtml作为模板,填充变量后,生成新的div,然后替换到网页里。outerHtml是原始网页的内容,不会随dom的改变而改变。

     5. 做html editor时用到div的contentEditable,div不能正常获取焦点

         framework7会自动处理来自document的touchEnd, 其中有个handleTouchEnd函数,因为div中的元素不是activeElement,就会调用e.preventDefault.现在加了一个判断该元素是否是具有contentEditable 的div的子元素。如果是,就不调用activeElement.

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 23:58 , Processed in 0.069793 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表