• 【初恋】vue单页应用开发总结


    vue新人,没有高级技巧

    本文主要总结了使用vue-cli脚手架安装开发环境,使用vue.js等进行单页应用开发所遇问题的总结。
    技术栈:
    Vue v1.0.21, vue-resource v0.91, vue-router v0.7.13,webpack v1.12.2vue-cli

    开发中注意所使用的库的版本!

    项目中问题总结:

    一:ESlint验证相关报错

    ESlint中默认没有alert、使用 “===” 作为比较、不使用双引号等。
    但是可以在.eslintrc.js 文件中配置验证规则,配置符合自己团队需求的验证规范。
    比如:
    允许tab和space混用:<'rules': { "no-mixed-spaces-and-tabs": [0, "smart-tabs"] }>
    其它配置规则可以参考eslint中文官网

    二:Vue 相关

    始终要记住的是vue指令绑定的都是javascript对象

    1:事件绑定
    v-click=”eventName” 或者 @click=”eventName”
    2:属性绑定
    v-bind:href=”url” 或者 :href=”url”
    注意:属性绑定和事件绑定简写的区别
    3: 动态绑定 style
    :style=”{ color: colorName, fontSize: size}”

    new Vue({
        data: {
            colorName: 'red',
            size: '14px'
        }
    })
    

    也可以绑定一个对象
    :style=”styleObj”

    new Vue({
        data: {
            marginTop: '15px',
            color: 'red'
        }
    })
    

    这里要注意三点:

    • 绑定对象和属性的区别,一个直接绑定, 后者需要 {},
    • 如果要根据不同条件切换绑定的对象,可以:style ="[ isTrue ? Style1 : style2]",
    • new vue( ) 中的data 和 vm 中的data写法有区别(参考官网文档)

    4:绑定class
    可以使用对象语法或者数组语法

    数组语法:
    1.绑定多个

    :class="[ 'a', 'b']"
    

    2.动态绑定

    :class="class-a"  :class="[isA ? 'a' :  'b']"
    

    或者

    :class=”[ ‘class-a', {'a': isA, 'b': isB}]'
    

    像下面这样数组嵌套不能识别

    :class="[ ‘class-a', [isA ? 'a' : 'b']]" // class-a, 0
    

    对象语法
    1.单个

    :class="{ 'class-a' : isA}"
    

    2.动态绑定

    :class="{ 'class-a': isA, 'class-b': isB}'
    

    或者作为一个对像绑定
    :class="classObj"

    data: {
        classObj: {
            isA: true,
            isB: false
        }
    }
    

    注意:绑定class时,需要注意class是字符串,需要用引号包裹

    5:data中的数据没有被渲染到dom中
    在子组件中,data必须是一个function,如下。其中的data需要return返回,才会被监听,响应数据侦听

    exports default {
        data () {
            return {
                color: ‘red’
            }
        }
    }
    

    6:父子组件通信
    知识点:props,dispatch,broadcast,emit

    假设有如下父子组件

    <parent>
        <header>头部组件</header>
        <child><child>
        <sidebar-contact>侧边客服组件</sidebar-contact>
        <footer>脚步组件</footer>
    </parent>
    
    // 子组件child
    <ul>
        <li v-for=”item in items”> {{ item }} </li>
    </ul>
    

    其中,child组件为一个列表,数据异步获取。
    路由切换到parent所在组件时,在route中获取数据,并将数据传给child。代码如下:

    // 父组件中
    <parent>
        <header>头部组件</header>
        <child  :data-for-child="dataForChild"><child>
        <sidebar-contact>侧边客服组件</sidebar-contact>
        <footer>脚步组件</footer>
    </parent>
    
    <script>
    export default {
        route: {
            data (transition) {
                this.$http.get('url').then((res) => {
                    this.dataForChild = res.json().data // 假设结果是数组,经过.json()处理,获取结果同jquery的ajax返回值res.data
                })
            }
        },
        data () {
            return {
                dataForChild: ''// 绑定的数据应该显示声明
            }
        }
    }
    </script>
    

    子组件中通过props接受数据

    // child组件内容
    <ul>
        <li v-for=”item in dataForChild”> {{ item }} </li>
    </ul>
    <script>
        export default {
            props: {
                dataForChild: {
                    type: Array // 声明数据类型,非必须
                }
            }
        }
    </script>
    

    这样就完成了基本父子组件通信。

    增加需求,动态获取li的高度值
    获取LI的高度方法(getLiH)肯定是写在child组件上,但直接写在child组件上,不管在child组件生命周期的任何时候调用都是不能获取到li的高度。(在执行getLiH时,异步数据可能没有返回,此时li为null)
    因此我们需要知道什么数据已经返回且DOM已经更新。
    官网说:

    Vue.nextTick(() => {
        // dom更新了
    })
    

    因此,代码改为:

    //parent组件
    //....
        this.dataForChild = res.json().data // 假设结果是数组
        this.$nextTick(() => {
            this.$broadcast(‘getLiH’)
        })
    //...
    
    //child 组件 
    events: {
        getLiH () {
            // 获取li的高度
        }
    }
    

    知识补充:
    events为一个对象,键是监听的事件对象,值是回调。我的理解是events中的一个事件相当于事件执行vm.$on 和事件触发vm.$emit.左边代码等价于:

    methods: {
        getLiHFn () {
            // 获取li的高度
        }
    },
    ready: {
        this.$on('getLiH', this.getLiHFn)
    }    
    

    需求变更 child组件是一个分页组件,需要实现上拉加载更多功能,当加载最后一页数据后需要fire掉上拉加载更多这个方法

    假设数据加载完变量为 <this.loadMore.loadAll = true;> 因为加载更多的逻辑实现在child,数据来源于parent 通过ajax异步请求返回的数据。整个过程为child执行上拉操作,告诉parent执行异步请求,当异步请求返回的data.lengh 为0 时,设置<this.loadMore.loadAll = true>并通过props传递给child,child中执行fire上拉加载这个函数。

    // parent组件:
    
    // 父组件中
    template:
    <parent>
        <header>头部组件</header>
        <child  :data-for-child="dataForChild" :load-more="loadMore"><child> // 传递数据
        <sidebar-contact>侧边客服组件</sidebar-contact>
        <footer>脚步组件</footer>
    </parent>
    
    script:
    data () {
        return {
            loadMore: {
                size: 10,
                page: 1,
                loadAll: false
            }
        }
    },
    method:{
        //...
        loadMore (size, page, done) {
            this.$http.get('url').then((res) => {
                if (res.json().code == 0) { done }
            })
        }
        //...
    },
    compiled: {
        this.$on('loadMoreData', this.loadMore)
    }
    
    // child组件中
    props: { // 通过props接受数据
        loadMore: {
            type: Object,
            default: '' // 默认数据,可以不写
        }    
    },
    methods: {
        //...
        this.$dispatch('loadMoreData', this.loadMore.size, this.loadMore.page, () => {
            if (this.loadMore.loadAll) {
            // fired 上拉加载更多
            }
        })
        //...
    }
    

    知识点
    1:$dispatch,子组件告知父组件要干啥
    2:dispatch中匿名函数done的调用。ajax异步请求处理需要在回调中进行

    7:[Vue warn]: Attribute "transition" is ignored on component because the component is a fragment instance:
    官方说,出现实例片段的原因如下:
    1、模板包含多个顶级元素。
    2、模板只包含普通文本。
    3、模板只包含其它组件(其它组件可能是一个片段实例)。
    4、模板只包含一个元素指令,如 或 vue-router 的
    5、模板根节点有一个流程控制指令,如 v-if 或 v-for。
    常犯的错误是模板中这样写,造成片段实例产生

    <template>
        <nav></nav>
        <content></content>
     </template>
    

    用个div包裹在 nav和content就行了

    vue-resource相关

    使用版本:v0.91
    **1:使用timeout 选项时,报错: Uncaught TypeError: request.cancel is not a function **
    参考答案在这里
    注:v0.93版本已经修复

    2:微信中,有返回数据,但是res.data.data 的数据为空
    原因v0.91中res是整个http请求的数据,包含response的header、body等,区别jquery返回的res,可以通过res.data.data 获取到渲染用的数据(类似jquery res.data);
    在微信中res.data 被转为一个字符串,不同于其他浏览器(除微信)输出json对象,故res.data.data 在微信中输出是一个空字符串。

    解决方法, 使用res.json() 获取返回中的json,处理后的res的值类似jquery的ajax返回的res

    vue-route 相关

    1:带参数的跳转,成功跳转后,url地址栏中url却没有携带参数
    v-link=”name: ’lists’, query: { list: id12}” 或者router.go({ name: ‘lists’, query: { list: id12}})
    给参数加上’’ , 即v-link=”name: ’lists’, query: { list: ‘id12’}”

    **2:跨页面参数 **
    下面是 router中data(transition) 的transition对象,跨页面(或者跨路由)传递参数主要使用的是 ‘to’ 和 ‘from’ 下面的属性(query,params等)的值。

    在vm实例中,可以通vm.$route的属性获取到与transition.to 相同的值,如下图:

    如果要知道你是从哪个页面跳转来的,在vm.$route 下没有找到相关信息,但是通过transition.from 你可以轻易知道来自哪个页面,像这样 <transition.from.path>获取跳转前路由的路劲

    其它错误:

    1:图片地址错误

  • 相关阅读:
    Android vector标签 PathData 画图超详解
    Echarts 出现不明竖线解决方案
    关于华为手机Log.d打印不出来log的问题
    Java源码解读(一)——HashMap
    算法小题
    Python简单小程序练习
    TCP/IP协议栈(三)——linux 向下的报文处理
    TCP协议(二)——TIME_WAIT状态
    Linux文件系统inode、block解释权限(三)
    Linux 基本权限(一)
  • 原文地址:https://www.cnblogs.com/wbengineer/p/5785926.html
Copyright © 2020-2023  润新知