美文网首页
框架升级记事

框架升级记事

作者: 大乔是个美少女 | 来源:发表于2019-07-28 10:17 被阅读0次

升级原因:
我们现在一直维护的项目是一个angularjs的老项目,前端技术发展的很快,而且angular已经不向下兼容了。
https://segmentfault.com/a/1190000013258094
技术框架比较老旧,热更新、组件化……很多可以方便我们开发的工具都没法使用。
新框架,提高开发效率。
迁移方向:
迁移到vue的技术栈上,和angularjs的数据绑定比较相似,又有组件化等一些新的特性。
迁移成本低。
方案选择:
老的项目开发维护3年,整体功能效果都比较好,如果全部迁移vue,重写成本高,周期长,回报低。
angularjs内嵌vue项目功能。
1)ngvue
angularjs使用ngvue,将vue封装为angularjs指令。
尝试功能效果详见:使用ngvue开发可视化查询功能
2) iframe
vue + element UI
内外通信:sendMessage

    # 向父窗口发送消息
    sendMessageToParent: (action, data) ->
        window.parent.postMessage({action, data}, '*')

    message_event_name = 'message.iframe_vue onmessage.iframe_vue'
    scroll_event_name = 'scroll.iframe_vue'

    $(window)
        # 监听 iframe 高度变化后,自适应
        .off(message_event_name).on message_event_name, (e) ->
            # 如果已经不在 iframe 页面了,就注销监听
            if not hasIframeVue()
                return $(window).off(message_event_name)

            {action, data} = e.originalEvent.data
            $timeout ->
                switch action
                    # 设置 iframe 高度,自适应
                    when 'set-height'
                        {height} = data
                        # 最小为屏蔽高减去顶部 header
                        min_height = screen.height - $('.page-header-v2').height()
                        height = Math.max(min_height, height)
                        page_content = $('.page-container .page-content')
                        getIframe().add(page_content).css({height, minHeight: height})

    # 与 iframe 子页面通信
    getIframe = -> $('#iframe-vue')
    sendMessageToIframe = (action, data) ->
        getIframe()[0].contentWindow.postMessage({action, data}, '*')

    # 监听父窗口发来的消息
    onParentWindowMessage: ->
        window.addEventListener('message', (e) =>
            {action, data} = e.data
            Vue.nextTick =>
                switch action
                    # 监听父窗口的获取localStorage的值,存到 iframe 的localStorage中
                    when 'init'
                        {storage} = data
                        for key,value of storage
                            localStorage.setItem(key,value)
        )

问题:
vue 单页路由切换无法保存路由信息,浏览器回退失效?无法复制访问路径。
解决方案:将iframe页面路径在路由跳转完成后,更新到父页面的URL上。
当URL重新访问时,修改iframe src地址。

# 跳转后
router.afterEach (to, from) ->
    addPathToURL(to, from)

addPathToURL = (to, from, next) ->
    params = (new URL(document.location)).searchParams
    before_url = params.get("path")
    if not before_url? || before_url.indexOf(to.path) == -1
        data =
            name: to.name
            url: to.fullPath
        utils.sendMessageToParent('change-url', data)

# 修改URL
when 'change-url'
    {name, url} = data
    params = new URL(location.href).searchParams
    path = decodeURIComponent(window.atob(params.get("path")))

    if path.indexOf(url) == -1
        new_url = "#{url}"
        new_url = "#{location.pathname}?path=" + window.btoa(encodeURIComponent(new_url))
        document.title = name + ' | 云窗'
        # window.history.replaceState("" , "", new_url)
        $location.url(new_url)
        $location.replace()
        # $window.history.pushState(null, 'any', $location.absUrl())
        #强制刷新更新页面URL
        # location.replace(new_url)

当时遇到一个比较烦恼的问题是:在更新URL的时候,location.href赋值会导致页面强制刷新,单独使用pushState和replaceState的时候都会不同程度的加入浏览路径到浏览器历史存储的栈里,影响正常回退效果。
最后,感觉可能是父页面的angularjs的路由变化会加入到浏览器历史存储的栈里,https://stackoverflow.com/questions/22914228/successfully-call-history-pushstate-from-angular-without-inifinite-digest
更新后,成功。

image.png
    if location.search.indexOf('?path=') > -1
        _host = host.replace('/yunchuang-vue/views', '')
        params = new URL(location.href).searchParams
        path = decodeURIComponent(window.atob(params.get("path")))
        url =_host + path
        console.log url
    else
        # 添加一个随机数,防止缓存
        url = host + iframe_url_lut[$state.current.name]

        symbol = if url.indexOf('?') > -1 then '&' else '?'
        url = "#{url}#{symbol}r=#{Math.random()}#{new Date().getTime()}"

需要注意的地方是:子页面向父页面传递URL,拼接在父页面的URL时,浏览器会对特殊字符进行编码,导致匹配的时候,也需要对path解码。有时候处理search路径时,search内容长度长,内容为中文,编码后的长度会超过浏览器显示的长度,显示效果不好。decodeURIComponent(window.atob(params.get("path")))window.btoa(encodeURIComponent(new_url))所以我们对path进行了手动编码后base64处理,显示效果更友好。

后续问题:angularjs路由不变更,点击router不变化,代码更新为:

    if $stateParams.path
        _host = host.replace('/yunchuang-vue/views', '')
        path = decodeURIComponent(window.atob($stateParams.path))
        url =_host + path
    else
        # 添加一个随机数,防止缓存
        url = host + iframe_url_lut[$state.current.name]

        symbol = if url.indexOf('?') > -1 then '&' else '?'
        url = "#{url}#{symbol}r=#{Math.random()}#{new Date().getTime()}"

 if path.indexOf(url) == -1
     document.title = name + ' | 云窗'
     path = window.btoa(encodeURIComponent(url))
      # $location.url(new_url)
      # $location.replace()
      $state.transitionTo($state.current, {'path': path}, {notify: false})

相关文章

  • 框架升级记事

    升级原因:我们现在一直维护的项目是一个angularjs的老项目,前端技术发展的很快,而且angular已经不向下...

  • 立刻可以实践的"16分割笔记"!

    使用框架,思路清晰,效果显著 "16分割笔记"的原型,实际上就是便利贴。没有框架的记事本和有框假的记事本,哪个更容...

  • AndroidX升级

    1,配置文件两行去掉2,1个开源框架不升级3,anko框架需要用common包4,gradle升级 glide:4...

  • 遨游4 不自动 升级遨游5 的方法

    不升级的方法:开始菜单-搜索记事本-以管理员模式打开,然后记事本的菜单里面选择打开,找到 “C:\Windows\...

  • 新版小程序登录授权

    首先近期工作中需要做小程序框架升级,升级成美团开源的mpvue框架;然后因为微信小程序API的改版,所以也顺便将授...

  • Ioc获取RoleManager失败问题

    自从更新了.net code2.1框架,Microsoft.AspNetCore.All框架也升级了。我的User...

  • 大数据框架升级

    五、部分框架升级 5.1 Hadoop 3.1.3 5.1.1 安装 安装方式同旧版本 5.1.2 配置文件 co...

  • swift我自己在项目中用到的框架

    在这里做个记录,顺便推荐给大家! Alamofire网络请求框架 Moya网络请求框架(Alamofire的升级版...

  • 上班第二周

    任务 升级调试热修复框架 还是解决项目的ANR问题 热修复框架 目前公司项目有用到两套热修复框架:阿里的Sophi...

  • 日志框架 - 基于SpringBoot 2.0 - 完整使用手册

    相对于日志框架 - 基于spring-boot - 使用入门,这是本框架升级到SpringBoot 2.0版本的使...

网友评论

      本文标题:框架升级记事

      本文链接:https://www.haomeiwen.com/subject/mhjurctx.html