Heim  >  Artikel  >  Web-Frontend  >  Umfassende Zusammenfassung: Zusammenfassung der Lösungsprobleme, die bei der Verwendung von Vue auftreten (muss gelesen werden)

Umfassende Zusammenfassung: Zusammenfassung der Lösungsprobleme, die bei der Verwendung von Vue auftreten (muss gelesen werden)

不言
不言Original
2018-08-17 14:29:244970Durchsuche

Dieser Artikel bietet Ihnen eine umfassende Zusammenfassung: eine Zusammenfassung der Lösungen für Probleme, die bei der Verwendung von Vue auftreten (ein Muss). Der Artikel führt in das Verständnis hierfür in js ein, was einen gewissen Referenzwert hat und notwendig ist. Freunde können darauf verweisen, ich hoffe, es wird Ihnen hilfreich sein.

Dieser Artikel ist lediglich eine Zusammenfassung einiger persönlicher Erfahrungen aus der täglichen Praxis. Es ist ein kleiner Trick, keine brillante Technologie. Wenn es Ihnen hilft, wäre ich geehrt.

Dieser Artikel geht nicht auf 罕见API Verwendungsmethoden usw. ein. Der größte Teil des Inhalts basiert auf einigen Vue-Praktiken. Aufgrund des Verdachts auf Opportunismus kann es zu Nebenwirkungen kommen, die nicht den Spezifikationen entsprechen. Bitte verwenden Sie es entsprechend den Projektanforderungen.

  1. Diese Methode kann auf mehreren Seiten verwendet werden. Es ist sehr praktisch, sie auf vue.prototype

    zu platzieren neu bei vue Ich habe eine dumme Sache gemacht, weil ich eine asynchrone Anforderungsschnittstelle post gekapselt, sie in die post.js-Datei eingefügt und dann

    import port from './xxxx/xxxx/post'

    auf jeder Seite eingeführt habe, die asynchrone Anforderungen verwenden muss Wenn das alles ist, können wir eine Seite schreiben und sie später kopieren, um sicherzustellen, dass jede Seite die obige Aussage enthält. Was aber, wenn die Verzeichnisebene jeder Datei unterschiedlich ist?

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

    Natürlich können wir derzeit Aliase verwenden @/xxxx/post, aber es ist immer noch notwendig, auf jeder Seite darauf zu verweisen.
    Dann sehen wir uns an, wie praktisch die Verwendung von vue.prototype ist.
    Zuerst müssen Sie in der Eintragsdatei von vue folgende Einstellungen vornehmen vue-cli

     import port from './xxxx/xxxx/post'
    
     vue.prototype.$post = post
    /src/main.js (für das von generierte Projekt ist der Standardwert

    ). kann alles festlegen vue Die this.post()-Methode wird in der Komponente (Seite) verwendet, genau wie der leibliche Sohn von vue

    Tipp: Wenn Sie die Methode an prototype hängen, ist es am besten Fügen Sie ein $-Präfix hinzu, um Konflikte mit anderen Variablen zu vermeiden

    bis noch einmal: Hängen Sie nicht zu viele Methoden an prototype an, sondern nur einige sehr häufig verwendete Methoden

  2. Für Daten, auf die geantwortet werden muss, legen Sie beim Abrufen der Schnittstellendaten zuerst fest

    Sind Sie schon einmal auf diese Situation gestoßen, wenn wir die Liste schleifen? Das Listenelement a steuert die angezeigten Attribute, z. B. ob es gelöscht werden kann, ob es ausgewählt ist usw. Die Back-End-Schnittstelle gibt diese Art von Feld im Allgemeinen nicht zurück, da es sich um eine reine Front-End-Anzeige handelt und nichts damit zu tun hat Machen Sie mit dem Back-End. Die vom Back-End bereitgestellten Daten lauten beispielsweise wie folgt: Diese Liste muss gerendert werden und hinter jedem Element wird eine Häkchenschaltfläche angezeigt. Diese Schaltfläche ist derzeit grau Wenn wir diese Daten hinzufügen, wenn der Benutzer ein Häkchen setzt, kann der normale Ansatz nicht rechtzeitig reagieren.

    Wenn wir beim Abrufen der Daten zunächst jedem Element im Array ein Häkchen hinzufügen, können wir dieses Problem lösen. Wir gehen davon aus, dass die Daten, die wir erhalten,

    [
      {name: 'abc', age: 18},
      {name: 'def', age: 20},
      {name: 'ghi', age: 22},
    ]
    Die Der Grund dafür ist, dass

    nicht auf nicht vorhandene Attribute reagieren kann. Wenn wir also die Daten erhalten, fügen wir zuerst die erforderlichen Attribute hinzu und weisen sie dann res.list zu, also

    Wenn die Daten empfangen werden, ist dieses Attribut existiert bereits, daher wird es antworten. Es gibt natürlich auch andere Möglichkeiten, dies zu tun. Für eine Person mit Zwangsstörung bevorzuge ich jedoch immer noch diesen Ansatz

    vuedatadata

    Kapseln Sie die globale asynchrone Anforderungsmethode basierend auf
  3. Ich habe den Quellcode vieler Projekte gelesen und festgestellt, dass die meisten asynchronen Anforderungen direkt Methoden wie promise verwenden, wie folgt:

    res.list.map(item => { 
      item.isTicked = false
    })
    Wenn es domänenübergreifend ist oder Sie

    festlegen müssen Header, Sie müssen mehr hinzufügen. Es gibt viele Konfigurationen, und diese Konfigurationen sind im Grunde die gleichen für dasselbe Projekt. Der einzige Unterschied besteht in axios und Parametern. Warum kapseln wir sie in diesem Fall nicht in eine Methode?

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

    Tipp: Es stellt sich heraus, dass ich zum Abschluss eine zusätzliche Versprechensebene verwendet habe, die für einfache Zwecke zu überflüssig ist. Ich habe das Gefühl, dass der Nuggets-Benutzer http darauf hingewiesen hat url

    und In Kombination mit dem ersten Punkt können wir
    function post (url,param) {
        return axios({
          method: 'post',
          url: url,
          data: param
          ... axios 的其他配置
        })
    }
    @日月为易。 in jedem
    -Fall wie diesem verwenden. Ist es viel einfacher als das Original? Wenn Ihr Projekt

    vue unterstützt, können Sie auch

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

    Tipp verwenden: async Schlüsselwort muss in await

    await被 async 修饰的函数里面使用
    sein Sie haben das Gefühl, dass Sie manchmal wirklich die Eltern-Kind-Komponente brauchen, um einen Wert zu teilen. Warum versuchen Sie nicht, einen Referenztyp zu übergeben, um den Wert an die Eltern-Kind-Komponente von
  4. zu übergeben? Es gibt viele Möglichkeiten, aber hier nicht einzeln aufgeführt, aber was wir heute lernen wollen, ist, die Referenztypeigenschaften von zu verwenden, um einen anderen Zweck der Wertübertragung

    zu erreichen

    假设有这么一个需求,父组件需要传 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. 逻辑复杂的内容,尽量拆成组件

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

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

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

    <template>
     <p>
       <p>姓名:{{user.name}}</p>
       <p>性别:{{user.sex}}</p>
       <p>年龄:{{user.age}}</p>
       ...此处省略999个字段...
       <p>他隔壁邻居的阿姨家小狗的名字:{{user.petName}}</p>
     </p>
    </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

相关推荐:

Vue登录注册的实现方法(代码解析)

ES6中全新的数字方法总结(必看)

Das obige ist der detaillierte Inhalt vonUmfassende Zusammenfassung: Zusammenfassung der Lösungsprobleme, die bei der Verwendung von Vue auftreten (muss gelesen werden). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn