zoukankan      html  css  js  c++  java
  • Vue项目实践中的功能实现与要点

    本贴记录项目实践中,各种功能的实现与技术要点,均有待改进。

    路由切换的时候,显示loading动画

    目前方案是: 在每个页面都手动装载一个loading组件
    组件的显示依赖vuex里面的一个值 , 在router的beforeEach事件里面控制loading的状态

    <template>
        <div>
            <div v-show="isLoading" class="myloading"><van-loading type="spinner" color="white"/></div>
        </div>
    </template>
    
    <script>
    export default {
        data(){
            return {}
        },
        computed:{
            isLoading(){
                return this.$store.state.isLoading
            }
        }
    }
    </script>
    
    <style>
    .myloading{
            background-color: #666;padding:20px;border-radius:5px;display:inline-block;
            position:fixed;z-index:999999;top:50%; left:50%;transform:translate(-50%,-50%);
    }
    </style>

    main.js的router.beforeEach事件:

        //显示loading
        store.commit('setLoading',true)
        //延迟一会加载页面,让loading效果显示一会。。。
        setTimeout(()=>{
            next()
        },300);

    在vuex里面使用axios

    vue脚手架3中,vuex是以单文件存在,即store.js,里面要使用axios

    需在头部import axios,然后直接调用axios.get...

    不知是否最佳姿势的“用户登录-保存状态”的方案

     登录页调用vuex里面的action,获取goken,并写入localstorage

        actions: {
            login(state){
                return new Promise((resolve,reject)=>{
                    axios.get('/gettoken',{parmas:{}})
                    .then(function(response){
                        resolve(response)
                        localStorage.setItem("userToken",response.data.data)
                    })
                    .catch(function(e){
                        reject(e)
                    })
                })
            },
            getUserInfo(store,token){
                axios.get('/api/userinfo.json',{parmas:{token}})
                .then(function(response){
                    console.log("拉取用户信息成功:",response.data.data)
                    store.commit('setLoginInfo',response.data.data)
                })
                .catch(function(e){
                    console.log(e)
                })
            }
        },

    在路由守卫里面,判断是否有token, 则获取用户信息

        let AUTO_LOGIN_TOKEN = localStorage.getItem("userToken")
    
        // 如果有保存token 就自动登录 
        if(AUTO_LOGIN_TOKEN != null && AUTO_LOGIN_TOKEN != undefined && AUTO_LOGIN_TOKEN != 'undefined'){
            console.log('token正常:',AUTO_LOGIN_TOKEN)
            if(store.getters.isLogin==0){
                console.log('准备自动登录,拉取用户信息。。。')
                store.dispatch('getUserInfo',AUTO_LOGIN_TOKEN)
            }
        }

    关于生命周期和dom操作的一点事儿

    项目中需要做一个仿app启动页,可以滚动的广告,并且有倒计时显示

        mounted(){
            //倒计时跳过
            let timehandler = setInterval(()=>{
                this.countdown --
                if(this.countdown<=0){
                    this.$router.push('home')
                    clearInterval(timehandler)
                }
            },1000)
        },
        updated(){
            //要放在updated里面,因为这里才完成dom渲染
            if(!this.Myswiper){
                console.log('初始化swiper');
                this.Myswiper = new Swiper('.swiper-container', {
                    pagination: {
                        el: '.swiper-pagination',
                        clickable:true
                    },
                    autoplay:{
                        delay:10000
                    },
                    navigation: {
                        nextEl: '.swiper-button-next',
                        prevEl: '.swiper-button-prev',
                    },
                    loop: false,
                    spaceBetween:0
                });
            }
    
        },

    总结:

    1、因为倒计时的时候,页面上也会显示剩余时间,每次都会触发updated事件,倒计时操作如果放在updated里面会出乱子

    2、初始化swiper必须等dom都准备好,因为dom异步数据获取 之后刷新的,所以也要放在updated里面(用nextTick事件应该也可以解决)
     但是有一点,上面定时器每次刷新时间都会触发updated,只要把swiper对象,挂到vue实例中,判断一下即可

    计算属性的坑点

    这里有2种方式,使用哪一种看情况而定,如果是第一种,不能在forEach的回调里面return 

    回调也是一个函数,里面return 和 外面的函数return是两码事

    第二种直接在for里面return,作用域是在curScrollIndex中,所以生效

        computed:{
            curScrollIndex(){
                //方式 1
                let returnValue = 0
                this.foodsLiHeight.forEach((val,index)=>{
                    if(this.curScrollposY >= this.foodsLiHeight[index] && this.curScrollposY < this.foodsLiHeight[index+1]){
                        console.log('计算属性:',index)
                        returnValue =  index
                    }
    
                })
                return returnValue
                // 方式 2
                for(let i=0;i<this.foodsLiHeight.length;i++){
                    if(this.curScrollposY >= this.foodsLiHeight[i] && this.curScrollposY < this.foodsLiHeight[i+1]){
                        console.log('计算属性:',i)
                        return i
                    }
                }
            }
        },

    关于使用全局Less

    less很方便,设置好变量,方法,打算在main.js引入less文件,在各子组件中直接使用

    但是无实现,经查阅,应该是webpack机制还无法实现

    参考:https://segmentfault.com/q/1010000010811479

    单页路由切换后,滚动高度不变的"BUG"

    切换了路由,滚动高度会继续上一个路由页面的数值
    在router实例中加入官方文档说的scrollBehavior,不知为何无效,也不想去折腾它

    那只能用最原始的办法,在路由的beforeEach中做手脚:

    router.beforeEach((to, from, next) => {
        console.log('beforeeach事件:',document.body.scrollTop)
        document.documentElement.scrollTop = 0;
        next()
    });

    这里要注意,使用了DTD文档头,要使用document.documentEelement.scrollTop

  • 相关阅读:
    android监控来电显示
    android 选择本地图片并预览
    解决android http请求带中文参数会乱码(url编码)
    android连接webservice是cookies和session保持方法
    eclipse中android自动补全/提示卡机或假死
    JS中创建类得几种方式
    AJAX的简单实例应用
    JavaScript中的eval函数的用法
    JSON 入门指南
    JS中关于clientWidth、offsetWidth、scrollWidth
  • 原文地址:https://www.cnblogs.com/vbyzc/p/9642134.html
Copyright © 2011-2022 走看看