本文主要是介绍vue-mixins使用注意事项和高级用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
因为在项目中 mixins(混合)
特性使用频率是很高的 有必要熟练掌握
http://www.deboy.cn/Vue-mixins-advance-tips.html
官方文档: mixins
实际项目中 一般都存在 列表(list) 这种很常见的使用场景
话再多都不如上demo
file: mixins/list.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | module.exports = { data () { return { list: [], page: 1, limit: 15, total: 0 } }, created () { this.initList() }, watch: { page: 'loadData' }, methods: { * 获取请求参数 默认只传递index(页码) limit(每页条数) 可以由调用方传递指定对象合并(或者覆盖)原参数 * @param params * @returns {*} */ getParams (params) { return Object.assign({ index: this.page, limit: this.limit }, params) }, * 加载更多 */ loadMore () { this.page++ }, * 推送到list中 因为vue的监听特性 只能用push进行数据的添加 如果有特殊处理 通过传递一个filter来过滤数据 * @param list * @param filter */ pushToList (list, filter) { list.forEach((item) => { if (typeof filter === 'function') { this.list.push(filter(item)) } else { this.list.push(item) } }) }, * 初始化列表 */ initList () { this.page = 1 this.list = [] this.loadData() }, * @overwrite * 加载数据方法 用到该mixin的都应该重写该方法 否则无法实现加载数据 */ loadData () { } } } |
解析
一个列表的基本属性
属性 | 作用或备注 |
---|
list | 列表 |
page | 页码 |
limit | 每页条数 |
total | 总条数 |
基本方法
方法 | 作用或备注 |
---|
initList() | 初始化列表 |
loadData() | 加载数据 |
loadMore() | 加载更多 |
扩展方法[主要用于参数的处理和结果的处理]
方法 | 作用或备注 |
---|
getParams() | 获取HTTP请求参数 |
pushToList() | 数据处理方法 |
每一个列表结构都具备的属性以及方法 可以放到mixins
的声明中
从这段代码中可以得知 加载了该mixins
的组件会在创建之后执行一个initList
方法
顾名思义 就是初始化列表的方法
1 2 3 | created () { this.initList() } |
问题
但是问题来了 如果我的组件 不只是在初始化的时候使用
而是在使用了keep-alive
的应用下在route->data()
的钩子中执行初始化呢?
1 2 3 4 5 | route: { data () { this.initList() } } |
这时候你打开控制台 刷新页面 就会发现 第一次进入 初始化了两次
原因
因为mixins
的合并策略
当混合对象与组件包含同名选项时,这些选项将以适当的策略合并。例如,同名钩子函数被并入一个数组,因而都会被调用。另外,混合的钩子将在组件自己的钩子之前调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var mixin = { created: function () { console.log('mixin hook called') } } new Vue({ mixins: [mixin], created: function () { console.log('component hook called') } }) |
值为对象的选项,如 methods, components 和 directives 将合并到同一个对象内。如果键冲突则组件的选项优先。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | var mixin = { methods: { foo: function () { console.log('foo') }, conflicting: function () { console.log('from mixin') } } } var vm = new Vue({ mixins: [mixin], methods: { bar: function () { console.log('bar') }, conflicting: function () { console.log('from self') } } }) vm.foo() vm.bar() vm.conflicting() |
注意 Vue.extend() 使用同样的合并策略。
所以即使你在引用的组件中 把created
重写 也是被合并(两个都会执行) 因为合并的策略不同 导致了 methods
可以被重写 而created
ready
等只会被合并
解决方法
怎么解决?
读过阅读官方文档后我想你会有答案
我这里提供一个文档中提到的比较灵活的简单的方案 加一个自定义选项
1 2 3 4 5 6 | created () { let option = this.$options.doNotInit if (!option) { this.initList() } } |
通过该选项 doNotInit
来判断是否需要在组件创建完毕之后就初始化
在调用该mixins
的组件中 添加这么一个选项 就可以让组件不执行初始化方法
而是通过route->data()
钩子来控制列表的初始化
调用
file: anyVueComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import List from 'path/mixins/list' export default{ mixins: [List], data () { return { } }, methods: { loadData () { this.$http.post(yourApiUrl, this.getParams()).then((res) => { }) } }, doNotInit: true, route: { data () { this.initList() } } } |
说到底 仔细阅读Vue文档 项目中遇到的绝大多数问题 都能迎刃而解~
这篇关于vue-mixins使用注意事项和高级用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!