• vue-mixins使用注意事项和高级用法


    因为在项目中 mixins(混合)特性使用频率是很高的 有必要熟练掌握
    官方文档: mixins


    实际项目中 一般都存在 列表(list) 这种很常见的使用场景

    话再多都不如上demo

    file: mixins/list.js

     1 module.exports = {
     2   data () {
     3     return {
     4       list: [],
     5       page: 1,
     6       limit: 15,
     7       total: 0
     8     }
     9   },
    10   created () {
    11     this.initList()
    12   },
    13   watch: {
    14     page: 'loadData'
    15   },
    16   methods: {
    17     /**
    18      * 获取请求参数 默认只传递index(页码) limit(每页条数) 可以由调用方传递指定对象合并(或者覆盖)原参数
    19      * @param params
    20      * @returns {*}
    21      */
    22     getParams (params) {
    23       return Object.assign({
    24         index: this.page,
    25         limit: this.limit
    26       }, params)
    27     },
    28     /**
    29      * 加载更多
    30      */
    31     loadMore () {
    32         this.page++
    33     },
    34     /**
    35      * 推送到list中 因为vue的监听特性 只能用push进行数据的添加 如果有特殊处理 通过传递一个filter来过滤数据
    36      * @param list
    37      * @param filter
    38      */
    39     pushToList (list, filter) {
    40       list.forEach((item) => {
    41         if (typeof filter === 'function') {
    42           this.list.push(filter(item))
    43         } else {
    44           this.list.push(item)
    45         }
    46       })
    47     },
    48     /**
    49      * 初始化列表
    50      */
    51     initList () {
    52       this.page = 1
    53       this.list = []
    54       this.loadData()
    55     },
    56     /**
    57      * @overwrite
    58      * 加载数据方法 用到该mixin的都应该重写该方法 否则无法实现加载数据
    59      */
    60     loadData () {
    61       // 每个列表自己的获取数据的方法需要重写
    62     }
    63   }
    64 }

    解析

    一个列表的基本属性

    属性作用或备注
    list 列表
    page 页码
    limit 每页条数
    total 总条数

    基本方法

    方法作用或备注
    initList() 初始化列表
    loadData() 加载数据
    loadMore() 加载更多

    扩展方法[主要用于参数的处理和结果的处理]

    方法作用或备注
    getParams() 获取HTTP请求参数
    pushToList() 数据处理方法

    每一个列表结构都具备的属性以及方法 可以放到mixins的声明中

    从这段代码中可以得知 加载了该mixins的组件会在创建之后执行一个initList方法
    顾名思义 就是初始化列表的方法

    1 created () {
    2     this.initList()
    3 }

    问题

    但是问题来了 如果我的组件 不只是在初始化的时候使用
    而是在使用了keep-alive的应用下在route->data()的钩子中执行初始化呢?

    1 route: {
    2   data () {
    3     this.initList()
    4   }
    5 }

    这时候你打开控制台 刷新页面 就会发现 第一次进入 初始化了两次

    原因

    因为mixins的合并策略

    当混合对象与组件包含同名选项时,这些选项将以适当的策略合并。例如,同名钩子函数被并入一个数组,因而都会被调用。另外,混合的钩子将在组件自己的钩子之前调用。

     1 var mixin = {
     2   created: function () {
     3     console.log('mixin hook called')
     4   }
     5 }
     6 new Vue({
     7   mixins: [mixin],
     8   created: function () {
     9     console.log('component hook called')
    10   }
    11 })
    12 // -> "mixin hook called"
    13 // -> "component hook called"

    值为对象的选项,如 methods, components 和 directives 将合并到同一个对象内。如果键冲突则组件的选项优先。

     1 var mixin = {
     2   methods: {
     3     foo: function () {
     4       console.log('foo')
     5     },
     6     conflicting: function () {
     7       console.log('from mixin')
     8     }
     9   }
    10 }
    11 var vm = new Vue({
    12   mixins: [mixin],
    13   methods: {
    14     bar: function () {
    15       console.log('bar')
    16     },
    17     conflicting: function () {
    18       console.log('from self')
    19     }
    20   }
    21 })
    22 vm.foo() // -> "foo"
    23 vm.bar() // -> "bar"
    24 vm.conflicting() // -> "from self"

    注意 Vue.extend() 使用同样的合并策略。

    所以即使你在引用的组件中 把created重写 也是被合并(两个都会执行) 因为合并的策略不同 导致了 methods 可以被重写 而created ready等只会被合并

    解决方法

    怎么解决?

    读过阅读官方文档后我想你会有答案

    我这里提供一个文档中提到的比较灵活的简单的方案 加一个自定义选项

    1 created () {
    2     let option = this.$options.doNotInit
    3     if (!option) {
    4       this.initList()
    5     }
    6 }

    通过该选项 doNotInit 来判断是否需要在组件创建完毕之后就初始化

    在调用该mixins的组件中 添加这么一个选项 就可以让组件不执行初始化方法

    而是通过route->data()钩子来控制列表的初始化

    调用

    file: anyVueComponent.vue

     1 import List from 'path/mixins/list'
     2 export default{
     3     mixins: [List],
     4     data () {
     5         return {
     6         // 除列表外额外的属性
     7         }
     8     },
     9     methods: {
    10         loadData () {
    11             this.$http.post(yourApiUrl, this.getParams()).then((res) => {
    12             // do somethings
    13             })
    14         }
    15     },
    16     doNotInit: true,
    17     route: {
    18         data () {
    19             this.initList()
    20         }
    21     }
    22 }

    说到底 仔细阅读Vue文档 项目中遇到的绝大多数问题 都能迎刃而解~

  • 相关阅读:
    iOS-runtime-objc_setAssociatedObject(关联对象以及传值)
    iOS-runtime-根据类名推送到任意控制器,且实现属性传值
    程序员必须知道的git托管平台
    iOS第三方地图-百度地图中心点定位
    nested pop animation can result in corrupted navigation bar
    iOS KVC,KVO
    iOS第三方地图-百度地图定位的封装
    iOS第三方地图-百度地图常用功能使用(POI搜索,地理正反编码,定位,添加标注)
    MJRefresh插件引起的错误
    OC开发_Storyboard——AutoLayout
  • 原文地址:https://www.cnblogs.com/yuwenjing0727/p/6993261.html
Copyright © 2020-2023  润新知