vue 实践技能合集

媒介

本文纯属个人日常平凡实践过程当中的一些经验总结,算是一点点小技能吧,不是何等高妙的手艺,假如对你有协助,那末不胜幸运。

本文不触及稀有API运用要领等,大部份内容都是基于对vue的一些实践罢了。由于涉嫌投机倒把,能够会带来一些不符合范例的副作用,请依据项目要求酌情运用。

  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 axios({
          method: 'post',
          url: url,
          data: param
          ... axios 的其他设置
        })
    }
    

    tip: 这里本来我多用了一层promise包起来,对简朴的需求来讲是太过剩了,以为掘金用户
    @日月为易。 指出

    再连系第一点,我们就可以够再恣意 vue 实例中如许运用

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

    有无比原始的简朴许多呢?假如你的项目支撑 async await,还能够如许用

    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.$emitvuex 而且假如有其他兄弟组件的话,只需兄弟组件也有绑定这个 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: 这类要领只实用于转变单个值的状况,且子组件对父组件只需简朴的传值,不须要其他附加操纵(如更新列表)的状况。

    补充一个 this.$emit('update:fidldName',value) 要领 (谢谢掘金用户 @日月为易。 指出)
    详细用法以下:

    父组件

        <subComponent field1.sync="param1" field2.sync="param2"></subComponent>

    子组件

    <script >
      export default {
        methods:{
          updateData1 (newValue) {
            this.$emit('update:field1',newValue)
          },
          updateData2 (newValue) {
            this.$emit('update:field2',newValue)
          }
        }
      }
    </script>

    该要领,个人认为比较实用于 要更新的数据不能绑定在 v-model 的状况下,或许要双向通讯的数据大于 1 个(1个也能够用,但我个人更引荐 input 的体式格局, 看个人喜好吧),但又不会许多的状况下.

  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,那十有八九是你对 vueAPI 还不够相识

    vue 自身就是一个数据驱动的框架,数据的更改,能及时反应到视图上去,假如你想要依据数据来掌握试图,一般状况一下合营 computed 服用就可以处置惩罚大部份题目了,而视图上的更改,我们平常能够经由过程监听 input change 等事宜,到达及时监听的目标,
    所以很少有需求运用到 watch 的时刻,最少我近来到的十来个项目内里,是没有用过 watch 固然,并非说 watch 是一定没用途, vue 供应这个api,一定是有他的原理,也有部份需求是真的须要用到的,只是我以为应当很罕用到才对,假如你以为随处都得用到的话,
    那末我以为 十有八九你应当多去熟习一下 computedvue 的其他 api

末了

本文的github地点 迎接随便star,follow, 和 不随便的 issue

别的,github上另有其他一些关于前端的教程和组件,
有兴致的童鞋能够看看,你们的支撑就是我最大的动力。

    原文作者:noahlam
    原文地址: https://segmentfault.com/a/1190000016035831
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞