1. 多个页面都使用的到方法,放在 vue.prototype上会很方便

    刚接触 vue的时候做过一件傻事,因为封装了一个异步请求接口post,放在 post.js文件里面,然后在每个需要使用异步请求的页面引入

    import port from './xxxx/xxxx/post'
    复制代码

    如果只是这样,还没什么,我们可以写好一个页面以后再复制,可以保证每个页面都有上面的语句。但是如果每个文件所在的目录层级不一样呢?

    // 假设正常是这样
    import port from '../xxxx/xxxx/post'
    // 目录加深一级,就变成这样
    import port from '../../xxxx/xxxx/post'
    // 再加深一级的样子
    import port from '../../../xxxx/xxxx/post'
    复制代码

    当然,这个时候,我们可以用 别名 @/xxxx/post,但是还是少不了要每个页面引用。 那我们来看看,用vue.prototype有多方便? 首先,你得在 vue的入口文件( vue-cli生成的项目的话,默认是 /src/main.js)里面做如下设置

     import port from './xxxx/xxxx/post'
    
     vue.prototype.$post = post
    复制代码

    这样,我们就可以在所有的 vue组件(页面)里面使用 this.post()方法了,就像 vue的亲儿子一样

    tip: 把方法挂在到 prototype上的时候,最好加一个 $前缀,避免跟其他变量冲突

    til again: 不要挂载太多方法到 prototype上,只挂载一些使用频率非常高的

  2. 需要响应的数据,在获取到接口数据的时候,先设置

    大家有没有很经常碰到这样都一种情况,在循环列表的时候,我们需要给列表项一个控制显示的属性,如 是否可删除,是否已选中等等,而后端接口一般不会返回这种字段,因为这属于纯前端展示的,跟后端没啥关系,比如后端给的数据如下

    [
    {name: 'abc', age: 18},
    {name: 'def', age: 20},
    {name: 'ghi', age: 22},
    ]
    复制代码

    我们不妨假设以上数据为学生列表

    然后我们需要渲染这个列表,在每一项后面显示一个勾选按钮,如果用户打勾,则这个按钮是绿色,默认这个按钮是灰色,这个时候,上表是没有满足这个渲染条件的数据,而如果我们在用户打勾的时候,再去添加这个数据的话,正常的做法是无法及时响应的。

    如果我们在获取到数据的时候,先给数组的每一项都加一个是否打勾的标示,就可以解决这个问题,我们假设我们获取到的数据是 res.list

    res.list.map(item => {
    item.isTicked = false
    })
    复制代码

    这么做的原理是 vue无法对不存在的属性作响应,所以我们在获取到数据的时候,先把需要的属性加上去,然后在赋值给 data, 这样 data接收到数据的时候,已经是存在这个属性了,所以会响应。当然还有其他方法可以实现。不过对于一个强迫症来说,我还是比较倾向于这种做法

  3. 封装全局基于 promise的异步请求方法

    看过很多项目的源码,发现大部分的异步请求都是直接使用 axios之类的方法,如下

    axios({
    method: 'post',
    url: '/user/12345',
    data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
    }
    })
    .then(function (response) {
    console.log(response);
    })
    .catch(function (error) {
    console.log(error);
    });
    复制代码

    如果有跨域,或者需要设置 http头等,还需要加入更多的配置,而这些配置,对于同一个项目来说,基本都是一样的,不一样的只有 url跟参数,既然这样,那我吗为什么不把它封装成一个方法呢?

    function post (url,param) {
    return new Promise((resolve, reject) => {
    axios({
    method: 'post',
    url: url,
    data: param
    })
    .then(function (response) {
    resolve(response);
    })
    .catch(function (error) {
    reject(error);
    });
    })
    } 复制代码

    再结合第一点,我们就可以再任意 vue实例中这样使用

    let param = {
    firstName: 'Fred',
    lastName: 'Flintstone'
    }
    this.post('/user/12345',param)
    .then(...)
    .catch(...)
    复制代码

    有没有比原始的简单很多呢?如果你的项目支持 asyncawait,还可以这样用

    let param = {
    firstName: 'Fred',
    lastName: 'Flintstone'
    }
    let res = await this.post('/user/12345',param)
    console.log(res) // res 就是异步返回的数据 复制代码

    tip: await关键字必须在 被 async 修饰的函数里面使用

  4. 如果你觉得有时候,你真的需要父子组件共享一个值,不如试试传个引用类型过去

    vue的父子组件传值,有好多种方法,这里就不一一列举了,但是今天我们要了解的,是利用 javascript的引用类型特性,还达到另一种传值的目的

    假设有这么一个需求,父组件需要传 3 个值到子组件,然后再子组件里面改动后,需要立马再父组件上作出响应,我们通常的做法上改完以后,通过 this.$emit发射事件,然后再父组件监听对应的事件,然而这么做应对一两个数据还好,如果传的数据多了,会累死人。 我们不妨把这些要传递的数据,包再一个对象/数组 里面,然后在传给子组件

    <subComponent :subData="subData"></subComponent>
    复制代码
    data () {
    return {
    subData: {
    filed1: 'field1',
    filed2: 'field2',
    filed3: 'field3',
    filed4: 'field4',
    filed5: 'field5',
    }
    }
    }
    复制代码

    这样,我们在子组件里面改动 subData的内容,父组件上就能直接作出响应,无需 this.$emit或 vuex而且如果有其他兄弟组件的话,只要兄弟组件也有绑定这个 subData,那么兄弟组件里面的 subData也能及时响应

    tip: 首先,这么做我个人上感觉有点不符合规范的,如果没有特别多的数据,还是乖乖用 this.$emit吧,其次,这个数据需要有特定的条件才能构造的出来,并不是所有情况都适用。

  5. 异步请求的参数在 data里面构造好,用一个对象包起来,会方便很多

    有做过类似 ERP类型的系统的同学,一定碰到过这样的一个场景,一个列表,有 N 个过滤条件,这个时候通常我们这么绑定

     <input type="text" v-model="field1">
    <input type="text" v-model="field2">
    <input type="text" v-model="field3">
    ....
    <input type="text" v-model="fieldn">
    复制代码
    data () {
    return {
    field1: 'value1',
    field2: 'value2',
    field3: 'value3',
    ...
    fieldn:'valuen'
    }
    }
    复制代码

    然后提交数据的时候这样:

     var param = {
    backend_field1: this.field1,
    backend_field2: this.field2,
    backend_field3: this.field3,
    ...
    backend_fieldn: this.fieldn
    }
    this.post(url,param)
    复制代码

    如你看到的,每次提交接口,都要去构造参数,还很容易遗漏,我们不妨这样:先去接口文档里面看一下后端需要的字段名称,然后

        <input type="text" v-model="queryParam.backend_field1">
    <input type="text" v-model="queryParam.backend_field2">
    <input type="text" v-model="queryParam.backend_field3">
    ....
    <input type="text" v-model="queryParam.backend_fieldn">
    ``` ```javascript
    data () {
    return {
    queryParam:{
    backend_field1: 'value1'
    backend_field2: 'value2'
    backend_field3: 'value3'
    ...
    backend_fieldn: 'valuen'
    }
    }
    }
    ```
    然后提交数据的时候这样:
    ```javascript
    this.post(url,this.queryParam)
    ```
    是的,这样做也是有局限性的,比如你一个数据在 2 个地方共用,比如前端组件绑定的是一个数组,你需要提交给后端的是 2 个字符串(例:`element ui` 的时间控件),不过部分特殊问题稍微处理一下,也比重新构建一个参数简单不是吗? 复制代码
  6. data里面的数据多的时候,给每个数据加一个备注,会让你后期往回看的时候很清晰

    续上一点,data里面有很多数据的时候,可能你写的时候是挺清晰的,毕竟都是你自己写的东西,可是过了十天半个月,或者别人看你的代码,相信我,不管是你自己,还是别人,都是一头雾水(记忆力超出常人的除外),所以我们不妨给每个数据后面加一个备注

    data () {
    return {
    field1: 'value1', // 控制xxx显示
    field2: 'value2', // 页面加载状态
    field3: [], // 用户列表
    ...
    fieldn: 'valuen' // XXXXXXXX
    }
    }
    复制代码
  7. 逻辑复杂的内容,尽量拆成组件

    假设我们有一个这样的场景:

    <div>
    <div>姓名:{{user1.name}}</div>
    <div>性别:{{user1.sex}}</div>
    <div>年龄:{{user1.age}}</div>
    ...此处省略999个字段...
    <div>他隔壁邻居的阿姨家小狗的名字:{{user1.petName}}</div>
    </div>
    <-- 当然,显示中我们不会傻到不用 v-for,我们假设这种情况无法用v-for -->
    <div>
    <div>姓名:{{user2.name}}</div>
    <div>性别:{{user2.sex}}</div>
    <div>年龄:{{user2.age}}</div>
    ...此处省略999个字段...
    <div>他隔壁邻居的阿姨家小狗的名字:{{user2.petName}}</div>
    </div>
    复制代码

    这种情况,我们不妨把[用户]的代码,提取到一个组件里面: 假设如下代码,在 comUserInfo.vue

    <template>
    <div>
    <div>姓名:{{user.name}}</div>
    <div>性别:{{user.sex}}</div>
    <div>年龄:{{user.age}}</div>
    ...此处省略999个字段...
    <div>他隔壁邻居的阿姨家小狗的名字:{{user.petName}}</div>
    </div>
    </template> <script >
    export default {
    props:{
    user:{
    type:Object,
    default: () => {}
    }
    }
    }
    </script>
    复制代码

    然后原来的页面可以改成这样(省略掉导入和注册组件,假设注册的名字是 comUserInfo):

    <comUserInfo :user="user1"/>
    <comUserInfo :user="user2"/>
    复制代码

    这样是不是清晰很多?不用看注释,都能猜的出来,这是2个用户信息模块, 这样做,还有一个好处就是出现错误的时候,你可以更容易的定位到错误的位置。

  8. 如果你只在子组件里面改变父组件的一个值,不妨试试 $emit('input'),会直接改变 v-model

    我们正常的父子组件通信是 父组件通过 props传给子组件,子组件通过 this.$emit('eventName',value)通知父组件绑定在 @eventName上的方法来做相应的处理。 但是这边有个特例,vue默认会监听组件的 input事件,而且会把子组件里面传出来的值,赋给当前绑定到 v-model上的值

    正常用法 - 父组件

    <template>
    <subComponent :data="param" @dataChange="dataChangeHandler"></subComponent>
    </template> <script >
    export default {
    data () {
    return {
    param:'xxxxxx'
    }
    },
    methods:{
    dataChangeHandler (newParam) {
    this.param = newParam
    }
    }
    }
    </script>
    复制代码

    正常用法 - 子组件

    <script >
    export default {
    methods:{
    updateData (newParam) {
    this.$emit('dataChange',newParam)
    }
    }
    }
    </script>
    复制代码

    利用默认 input事件 - 父组件

    <template>
    <subComponent v-model="param"></subComponent>
    </template>
    复制代码

    利用默认 input事件 - 子组件

    <script >
    export default {
    methods:{
    updateData (newParam) {
    this.$emit('input',newParam)
    }
    }
    }
    </script>
    复制代码

    这样,我们就能省掉父组件上的一列席处理代码,vue会自动帮你处理好

    tip: 这种方法只适用于改变单个值的情况,且子组件对父组件只需简单的传值,不需要其他附加操作(如更新列表)的情况。

  9. conponents放在 Vue options的最上面

    不知道大家有没有这样的经历: 导入组件,然后在也页面中使用,好的,报错了,为啥?忘记注册组件了,为什么会经常忘记注册组件呢?因为正常的一个 vue实例的结构大概是这样的:

    import xxx form 'xxx/xxx'
    export default {
    name: 'component-name',
    data () {
    return {
    // ...根据业务逻辑的复杂程度,这里省略若干行
    }
    },
    computed: {
    // ...根据业务逻辑的复杂程度,这里省略若干行
    },
    created () {
    // ...根据业务逻辑的复杂程度,这里省略若干行
    },
    mounted () {
    // ...根据业务逻辑的复杂程度,这里省略若干行
    },
    methods () {
    // ...根据业务逻辑的复杂程度,这里省略若干行
    },
    }
    复制代码

    我不知道大家正常是把 components属性放在哪个位置,反正我之前是放在最底下,结果就是导致经常犯上述错误。

    后面我把 components调到第一个去了

    import xxx form 'xxx/xxx'
    export default {
    components: {
    xxx
    },
    // 省略其他代码
    }
    复制代码

    从此以后,妈妈再也不用担心我忘记注册组件了,导入和注册都在同一个位置,想忘记都难。

  10. 大部分情况下,生命周期里面,不要有太多行代码,可以封装成方法,再调用

    看过很多代码,包括我自己之前的,在生命周期里面洋洋洒洒的写了一两百行的代码,如:把页面加载的时候,该做的事,全部写在 created里面,导致整个代码难以阅读,完全不知道你在页面加载的时候,做了些什么, 这个时候,我们不妨把那些逻辑封装成方法,然后在生命周期里面直接调用:

    created () {
    // 获取用户信息
    this.getUserInfo()
    // 获取系统信息
    this.getSystemInfo()
    // 获取配置
    this.getConfigInfo()
    },
    methods:{
    // 获取用户信息
    getUserInfo () {...},
    // 获取系统信息
    getSystemInfo () {...},
    // 获取配置
    getConfigInfo () {...},
    }
    复制代码

    这样是不是一眼就能看的出,你在页面加载的时候做了些什么?

    tip: 这个应该算是一个约定俗成的规范吧,只是觉得看的比较多这样写的,加上我自己初学的时候,也这么做了,所以写出来,希望新入坑的同学能避免这个问题

  11. 少用 watch,如果你觉得你好多地方都需要用到 watch,那十有八九是你对 vue的 API还不够了解

    vue本身就是一个数据驱动的框架,数据的变动,能实时反馈到视图上去,如果你想要根据数据来控制试图,正常情况一下配合 computed服用就能解决大部分问题了,而视图上的变动,我们一般可以通过监听 inputchange等事件,达到实时监听的目的, 所以很少有需求使用到 watch的时候,至少我最近到的十来个项目里面,是没有用过 watch当然,并不是说 watch是肯定没用处, vue提供这个api,肯定是有他的道理,也有部分需求是真的需要用到的,只是我觉得应该很少用到才对,如果你觉得到处都得用到的话, 那么我觉得 十有八九你应该多去熟悉一下 computed和 vue的其他 api

vue 实站技巧总结的更多相关文章

  1. 使用VUE实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部

    使用VUE实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部 <template> <div> <table> <tr v-for="i ...

  2. Vue + Element 小技巧

    说是小技巧 ,其实就是本人 就是一个小菜比 .如有大佬可以纠正,或者再救救我这个小菜比    跪谢 1.当后台返回一个字段需要根据不同字段内容在表格内显示相对应的文字(字段内容是死的,表格内需要显示对 ...

  3. VUE基础实用技巧

    Vue以前听说过,有了解过一点.当时还在热衷于原生JavaScript去写一些方法的封装,不是为啥,就感觉这样很帅,后面多多少少接触了一些JQuery的用法,到现在为止,JavaScript原生封装的 ...

  4. vue的开发技巧

    1.监听组件的生命周期 比如有父组件 Parent和子组件 Child,如果父组件监听到子组件挂载 mounted就做一些逻辑处理,常规的写法可能如下: // Parent.vue <Child ...

  5. vue 优化小技巧 之 require.context()

    1.require.context() 回忆一下 当我们引入组件时 第一步 创建一个子组件 第二步 import ... form ... 第三步 components:{..} 第四步 页面使用 & ...

  6. 在vuex的mutations中使用vue的小技巧

    问题: 在vuex组件中的mutations属性中的定义的函数,有时会要用到vue这个对象.正常在其他的地方使用是通过this这个变量来获取,但是在mutations定义的函数中this指定的是Vue ...

  7. GO后端开发+VUE实列

    因为我是从java转到go,代码结构跟我之前用java的很像 在这里只浅显的实战运用,没有过多理论讲解 工作环境:IDE:Goland , Go 1.17.7 框架 Gin+Gorm ,前端VUE 这 ...

  8. Maven实站读后感

    这本书是一本非常经典的Maven教程,通俗易懂,同时介绍的东西十分实用,在工作上都能用到. 以前在公司里面需要要问同时的有关的Maven的问题,都可以自己解决了. 除了最基本的,以后自己可能要用到的: ...

  9. vue页面操作技巧

    // this.$router.push({ path: "https://www.baidu.com/"}); // POST请求的时候 // this.$router.push ...

随机推荐

  1. JDK 1.6 HashMap 源码分析

    前言 ​ 前段时间研究了一下JDK 1.6 的 HashMap 源码,把部份重要的方法分析一下,当然HashMap中还有一些值得研究得就交给读者了,如有不正确之处还望留言指正. 准备 ​ 需要熟悉数组 ...

  2. c++ <vector>学习

    https://www.cnblogs.com/mr-wid/archive/2013/01/22/2871105.html 具体参考上面博客,很详细,也是看他的.今天c++学习200%,项目开发0% ...

  3. 在Java中,关于.Class()与.getCalss与.getClass().getName()的区别

    ** * Java反射 *所谓反射,可以理解为在运行时期获取对象类型信息的操作. *传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下, *编程人员可以动态获取这些信息,从而编写更加 ...

  4. linux 学习笔记 ftp

    server with sites set up for download files sometimes provide an anonymous ftp account 数据传输 ftp 192. ...

  5. atom那些事儿

    基于electron(Electron 的底层基于Chromium 和node.js)

  6. python基础一 ------可迭代对象和迭代器对象

    可迭代对象和迭代器对象:前者生成后者 比喻:10个硬币都可以一一数(迭代),放入到存钱罐(可以取钱的那种),那这个存钱罐就是一个迭代器对象 需求:从网络抓取各个城市气温信息,并依次显示若依次抓取较多的 ...

  7. 如何在Android中的Activity启动第三方应用程序?

    如何在点击某个按键后,执行启动第三方应用程序界面? /** * <功能描述> 启动应用程序 * * @return void [返回类型说明] */ private void startU ...

  8. me 云面试

    元祖的特点: 1.元组内的元素,不可以增加,删除,只能访问,这个是元祖的特性,比较安全.类似于字符串.但是我们可以对整个元祖进行删除.使用del内置函数 2.当元祖内只有一个元素的时候,需要加逗号消除 ...

  9. vue给methods中的方法传入当前点击行的值

    <template> <!-- 在template中,只能存在一个根组件 --> <div class="event"> <ul> ...

  10. React生命周期函数详解

    React生命周期函数 生命周期函数是指在某一个周期自动执行的函数. React中的生命周期执行过程 以下是React中的常用的生命周期函数,按个部分中按照自动执行顺序列出,这几个过程可能存在同时进行 ...