• 使用vue2.0 vue-router vuex 模拟ios7操作


    其实你也可以,甚至做得更好...

    首先看一下效果:用vue2.0实现SPA:模拟ios7操作 与 通讯录实现

      

      github地址是:https://github.com/QRL909109/ios7 如果您觉得可以,麻烦给一个star,支持我一下。

      之前接触过Angular1.0,React,都只是学点入门,但对于Vue却觉得很容易上手,不止入门简单,插件也是很丰富的,脚手架也是便利的很...

    项目分析:

    1.首屏滑动解锁,并能移动小圆点

    2.主屏幕  长按图标抖动,删除图标,点击小圆点的主屏幕 抖动停止

    3.点击电话图标,进入电话模块

    4.进入个人中心:点击编辑,移入删除图标,滑动出现删除;点击完成,删除图标消失

    5.进入通讯录:右侧固定栏滑动 列表滑动到相应位置(使用better-scroll 插件)

    6.进入拨号:拨号与删除

    插件介绍:

    vue-router: vue路由插件  vue-router 2.0 中文文档

    vuex: vue状态管理 vuex 1.0 中文文档 方便组件共用状态 

    better-scroll: 优化滑动性能的插件

    lib-flexible: 手淘移动端H5 终端适配

    moment: 时间格式化插件

    项目布局:

    采用手淘的flexible   这里有学习资源  使用Flexible实现手淘H5页面的终端适配

    要点:

    1.根据手机dpr设置不同的scale,font-size (注意ios的dpr会适应变化,而Android的dpr一直为1)

    2.整个屏幕宽度默认为10rem,采用750设计稿上下兼容,1rem = 75px

    3.文字用px写,分别写出兼容

    div{
      font-size:12px; 
    }
    
    [data-dpr="2"]{
      font-size:24px;  
    }
    
    [data-dpr="3"]{
      font-size:36px;  
    }

    4.采用flex弹性布局(注意兼容高低版本)

    开始:(挑有用重点讲)

    1、修改webpack.base.conf.js

    利用webpack alias定义别名,方便输入路径,根据完整绝对地址

    例如:

    resolve: {
        extensions: ['', '.js', '.vue'],
        fallback: [path.join(__dirname, '../node_modules')],
        alias: {
          'vue$': 'vue/dist/vue',
          'src': path.resolve(__dirname, '../src'),
          'assets': path.resolve(__dirname, '../src/assets'),
          'components': path.resolve(__dirname, '../src/components'),
          'store':path.resolve(__dirname,'../src/vuex/store'),
          'getters':path.resolve(__dirname,'../src/vuex/getters'),
          'actions':path.resolve(__dirname,'../src/vuex/actions'),
          'mock':path.resolve(__dirname,'../src/mock')
        }
      },

    这样只要在任意位置使用 import ... from actions

    webpack将会自动匹配actions的位置,不用再去计算文件位置,写出'../../../actions'。

    2、配置路由:在src目录下新建 route-config.js 

    const routes=[
       {
            path: '/main',
            name: 'main',
            meta: {
                title: '主页面'
            },
            component: resolve => {
                require(['./views/main.vue'], resolve)
            },
            children: [
                {
                    path: '',
                    name: 'personal',
                    meta: {
                        title: '个人收藏'
                    },
                    component: resolve => {
                        require(['./views/phone/personal.vue'], resolve)
                    },
                    children:[
                        phone_detail
                    ]
                }
             ]
        },{
           .... 
        },{
           path: '*',
            redirect: {
                name: 'main'
            }
        }   
    ];
    export default routes 

    这里采用异步组件,按需加载,使用webpack的代码分割功能。

    路由机制是采用匹配规则,根据path匹配URL的路径,从而加载对应的组件。

    这里稍微提一下vue-router 1.0 和 vue-router 2.0 写法的区别

    vue-router1.0 

      传递vue-router实例,通过map进行定义路由映射

    vue-router2.0

        使用router 构造配置 routes

    tips: 设置标题栏的title

    通过vue-router实例后的afterEach,to能获取每个路由的状态,这时候便能使用document.title = to.meta.title (前提是router-config 里面有设置meta对象)

    3、APP.vue结构

    考虑到小圆点是所有页面都存在的,所以结构为router-view加载路由匹配页面,另外加载小圆点组件。

    <template>
        <div class="_full">
            <!-- app router -->
            <transition name="bounce">
                <keep-alive>
                  <router-view></router-view>
                </keep-alive>
            </transition>
    
            <!--小圆点-->
            <topPoint></topPoint>
        </div>
    </template>

    或许你有疑惑 keep-alive 加在这有什么用?

    keep-alive 会缓存不活动的组件实例,而不是销毁它们。主要用于保留组件状态或避免重新渲染

    在做“个人收藏”模块遇到很诡异的bug (没加 keep-alive)

    刚开始能删除数据,但跳转到其他页面重新回来后,就不能执行删除了。

    后面一分析才知道,在从其他页面跳转回来后,组件重新渲染,再次请求了列表数据,而页面的数据却缓存着,导致数据不一致。加入keep-alive就能保留组件状态

    4、v-touch不兼容vue2.0解决方案

    本以为应该会有插件支持的,结果没法找到,只能自己写简单指令识别下。(只支持长按 press,向上 swipeup,向下 swipedown,向左swipeleft,向右 swiperight)

    使用 v-touch:swiperight="methodFunc"

    vue指令 touch 使用bind,

    •   binding.arg 获得传入模式
    •   el 监听绑定的事件
    •   binding.value 获得传入的事件

    通过对touchstart touchmove touchend 的判断,执行对应的事件。

    5、引入better-scroll插件

    功能:优化滚动,能模仿像原生弹性的效果

    使用:需要在外部包含固定高度的容器

     

    <div ref="scrollWrapper">
       <ul>
           <li v-for="item in List" class="commit-hook"></li>
       </ul>    
    </div>
    
    <script>
      import BScroll from 'better-scroll'
    export default{
    
         created(){
                this.$nextTick(() => {  //这里需要异步
                    this._initScroll();
               })
            },
    
        methods: {
              _initScroll(){
                    this.containerScroll = new BScroll(this.$refs.scrollWrapper,{
                        click:true   //可点击
                    });
                }
       }
    }
    </script>

    这样将会添加translate,使用贝塞尔曲线,达到原生效果。

     如果需要实时知道滚动的区域,可以这么配置:

    created(){
        this.$nextTick(() => {
                    this._initScroll();
                    this._calculateHeight()
           })
    },
    methods:{
       _initScroll(){
               this.containerScroll = new BScroll(this.$refs.scrollWrapper, {
                    probeType: 3
                });
                this.containerScroll.on('scroll', (pos)=> {
                      this.scrollY = Math.abs(Math.round(pos.y)); //实时获取Y轴的数值
                })
     }
       _calculateHeight(){
                    let commitList = this.$refs.commitBox.getElementsByClassName('commit-hook'); //获取对应的DOM元素
                    let height = 0;
                    this.listHeight.push(height)
                    for (let i = 0; i < commitList.length; i++) {
                        let item = commitList[i]
                        height += item.clientHeight;
                        this.listHeight.push(height)
                    }
          }
    }
    computed: {
                currentIndex(){                  //实时获得当前的区域
                    for (let i = 0; i < this.listHeight.length; i++) {
                        let height1 = this.listHeight[i];
                        let height2 = this.listHeight[i + 1];
                        if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {
                            return i;
                        }
                    }
                    return 0;
                }
    }

     通过对比 v-for的  index 与 currentIndex 就能实时知道位置了。

    6、组件间的通信

    可以看看我的另一篇文章 vue2.0--组件通信(非vuex法) 

    主要用到父子 子父 通信方法,但为了方便项目使用 vuex状态管理。

    以上的项目很基础,练习一遍,便能比我做的更好... 如有缺漏,做不好的地方,欢迎大家指正讨论。

    如果您觉得有帮助,请star一下,给予我更好的支持。

    github地址是:https://github.com/QRL909109/ios7 

    如需转载,请注明出处。

  • 相关阅读:
    Android Studio 2.3.1导出jar文件不能生成release解决办法
    AndroidStudio 3.0 生成jar包的方法
    Android Studio如何打jar包
    Android Studio 如何打JAR包(修订版)
    6款程序员必备的开源中文处理工具
    Qt5.8 下链接 Mysql 错误以及解决方法(无论 Mysql 是什么版本的,64 位 Qt 要用 64 位的 Mysql 驱动,32 位的 Qt 要用 32 位的Mysql 驱动)
    Go 语言如果按这样改进,能不能火过 Java?
    基于 CSP 的设计思想和 OOP 设计思想的异同
    DELPHI下多线程编程的几个思维误区(QDAC)
    如何使用表单
  • 原文地址:https://www.cnblogs.com/QRL909109/p/6143394.html
Copyright © 2020-2023  润新知