<p><code></p> <p><span class="img-wrap"><img data-src="/img/remote/1460000017716551?w=4160&amp;h=3120" src="/img/remote/1460000017716551?w=4160&amp;h=3120" alt="云南大理崇圣寺" title="云南大理崇圣寺" style="cursor: pointer; display: inline;"></span></p> <p><a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>中的混入 <a href="https://cn.vuejs.org/v2/guide/mixins.html" rel="nofollow noreferrer" target="_blank">mixins</a> 是一种提供分发 <a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a> 组件中可复用功能的非常灵活的方式。听说在3.0版本中可能会用Hooks的形式实现,但这并不妨碍它的强大。</p> <p>这里主要来讨论 mixins 如何优化我们的数据列表代码。</p> <p>如果我们有大量的表格页面,仔细一扒拉你发现非常多的东西都是可以复用的例如分页,表格高度,加载方法, laoding 声明等一大堆的东西。下面我们来整理出来一个简单通用混入 <code>list.js</code></p> <p>list.js</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="const list = { data () { return { loading: false, pageParam: { pageNum: 1, // 页码 pageSize: 20, // 页长 total: 0 // 总记录数数 }, pageSizes: [10, 20, 30, 50], // 页长数 pageLayout: 'total, sizes, prev, pager, next, jumper', // 分页布局 pageCount: 5, // 页码按钮的数量,当总页数超过该值时会折叠(大于等于 5 且小于等于 21 的奇数) list: [] } }, methods: { // 分页回掉事件 handleSizeChange (val) { this.pageParam.pageSize = val this.getList() }, handleCurrentChange (val) { this.pageParam.pageNum = val this.getList() }, /** * 表格数据请求成功的回调 处理完公共的部分(分页,loading取消)之后把控制权交给页面 * @param {*} apiResult * @returns {*} promise */ listSuccessCb (apiResult = {}) { return new Promise((resolve, reject) => {<br /> let tempList = [] // 临时list<br /> try {<br /> this.loading = false<br /> tempList = apiResult.data<br /> this.pageParam.total = apiResult.page.total<br /> // 直接抛出<br /> resolve(tempList)<br /> } catch (error) {<br /> reject(error)<br /> }<br /> })<br /> },<br /> /**<br /> * 处理异常情况<br /> * ==> 简单处理 仅仅是对表格处理为空以及取消loading<br /> */<br /> listExceptionCb (error) {<br /> this.loading = false<br /> console.error(error)<br /> }<br /> },<br /> created () {<br /> // 这个生命周期是在使用组件的生命周期之前<br /> this.$nextTick().then(() => {<br /> // todo<br /> })<br /> }<br /> }<br /> export default list" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-keyword"><a href="http://www.js-code.com/tag/const" title="浏览关于“const”的文章" target="_blank" class="tag_link">const</a></span> list = { data () { <span class="hljs-keyword">return</span> { <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">pageParam</span>: { <span class="hljs-attr">pageNum</span>: <span class="hljs-number">1</span>, <span class="hljs-comment">// 页码</span> pageSize: <span class="hljs-number">20</span>, <span class="hljs-comment">// 页长</span> total: <span class="hljs-number">0</span> <span class="hljs-comment">// 总记录数数</span> }, <span class="hljs-attr">pageSizes</span>: [<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">50</span>], <span class="hljs-comment">// 页长数</span> pageLayout: <span class="hljs-string">'total, sizes, prev, pager, next, jumper'</span>, <span class="hljs-comment">// 分页布局</span> pageCount: <span class="hljs-number">5</span>, <span class="hljs-comment">// 页码按钮的数量,当总页数超过该值时会折叠(大于等于 5 且小于等于 21 的奇数)</span> list: [] } }, <span class="hljs-attr">methods</span>: { <span class="hljs-comment">// 分页回掉事件</span> handleSizeChange (val) { <span class="hljs-keyword"><a href="http://www.js-code.com/tag/this" title="浏览关于“this”的文章" target="_blank" class="tag_link">this</a></span>.pageParam.pageSize = val <span class="hljs-keyword">this</span>.getList() }, handleCurrentChange (val) { <span class="hljs-keyword">this</span>.pageParam.pageNum = val <span class="hljs-keyword">this</span>.getList() }, <span class="hljs-comment">/** * 表格数据请求成功的回调 处理完公共的部分(分页,loading取消)之后把控制权交给页面 * @param {*} apiResult * @returns {*} promise */</span> listSuccessCb (apiResult = {}) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in"><a href="http://www.js-code.com/tag/promise" title="浏览关于“Promise”的文章" target="_blank" class="tag_link">Promise</a></span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> { <span class="hljs-keyword"><a href="http://www.js-code.com/tag/let" title="浏览关于“let”的文章" target="_blank" class="tag_link">let</a></span> tempList = [] <span class="hljs-comment">// 临时list</span> <span class="hljs-keyword">try</span> { <span class="hljs-keyword">this</span>.loading = <span class="hljs-literal">false</span> tempList = apiResult.data <span class="hljs-keyword">this</span>.pageParam.total = apiResult.page.total <span class="hljs-comment">// 直接抛出</span> resolve(tempList) } <span class="hljs-keyword">catch</span> (error) { reject(error) } }) }, <span class="hljs-comment">/** * 处理异常情况 * ==&gt; 简单处理 仅仅是对表格处理为空以及取消loading */</span> listExceptionCb (error) { <span class="hljs-keyword">this</span>.loading = <span class="hljs-literal">false</span> <span class="hljs-built_in">console</span>.error(error) } }, created () { <span class="hljs-comment">// 这个生命周期是在使用组件的生命周期之前</span> <span class="hljs-keyword">this</span>.$nextTick().then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> { <span class="hljs-comment">// todo</span> }) } } <span class="hljs-keyword"><a href="http://www.js-code.com/tag/export" title="浏览关于“export”的文章" target="_blank" class="tag_link">export</a></span> <span class="hljs-keyword">default</span> list</code></pre> <p>下面我们直接在组件中使用这个<code>mixins</code></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="import mixin from '@/mixins/list' // 引入 import {getList} from '@/api/demo' export default { name: 'mixins-demo', mixins: [mixin], // 使用mixins data () { return { } }, methods: { // 加载列表 getList () { const params = { ...this.searchForm, ...this.pageParam } fetchUserList(params).then(res => {<br /> if (res.code === 0) {<br /> this.listSuccessCb(res).then((list) => {<br /> this.list = list<br /> }).catch((err) => {<br /> console.log(err)<br /> })<br /> }<br /> })<br /> },<br /> },<br /> created() {<br /> this.load()<br /> }<br /> }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-keyword">import</span> mixin <span class="hljs-keyword">from</span> <span class="hljs-string">'@/mixins/list'</span> <span class="hljs-comment">// 引入</span> <span class="hljs-keyword">import</span> {getList} <span class="hljs-keyword">from</span> <span class="hljs-string">'@/api/demo'</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> { <span class="hljs-attr">name</span>: <span class="hljs-string">'mixins-demo'</span>, <span class="hljs-attr">mixins</span>: [mixin], <span class="hljs-comment">// 使用mixins</span> data () { <span class="hljs-keyword">return</span> { } }, <span class="hljs-attr">methods</span>: { <span class="hljs-comment">// 加载列表</span> getList () { <span class="hljs-keyword">const</span> params = { ...this.searchForm, ...this.pageParam } fetchUserList(params).then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> { <span class="hljs-keyword">if</span> (res.code === <span class="hljs-number">0</span>) { <span class="hljs-keyword">this</span>.listSuccessCb(res).then(<span class="hljs-function">(<span class="hljs-params">list</span>) =&gt;</span> { <span class="hljs-keyword">this</span>.list = list }).catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> { <span class="hljs-built_in">console</span>.log(err) }) } }) }, }, created() { <span class="hljs-keyword">this</span>.load() } }</code></pre> <p>使用了 mixins 之后一个简单的有 loadoing, 分页,数据的表格大概就只需要上面这些代码。</p> <p>在<code>list.js</code>中我们可以直接调用组件的方法,比如在分页回调事件中调用组件的 <code>getList()</code>方法,在组件中直接调用 <code>list.js</code>中的代码,如直接访问 <code><a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.pageParam</code>。</p> <div class="google-auto-placed ap_container" style="text-align: center; width: 100%; height: auto; clear: none;"><ins data-ad-format="auto" class="adsbygoogle adsbygoogle-noablate" data-ad-client="ca-pub-6330872677300335" data-adsbygoogle-status="done" style="display: block; margin: auto; background-color: transparent;"><ins id="aswift_4_expand" style="display: inline-table; border: none; height: 0px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 697px; background-color: transparent;"><ins id="aswift_4_anchor" style="display: block; border: none; height: 0px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 697px; background-color: transparent; overflow: hidden; opacity: 0;"><iframe width="697" height="175" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){setTimeout(h,0)}else if(h.match){try{h=s.upd(h,i)}catch(e){}w.location.replace(h)}}" id="aswift_4" name="aswift_4" style="left:0;position:absolute;top:0;border:0px;width:697px;height:175px;"></iframe></ins></ins></ins></div> <p>当组件和 mixins 对象含有同名选项时,这些选项将以恰当的方式混合。比如,数据对象在内部会进行<strong>浅合并</strong> (一层属性深度),在和组件的数据发生冲突时以组件数据优先。</p> <p>你学会了吗?还不快试试。。。</p> <p></code></p>

本文固定链接: http://www.js-code.com/vue-js/vue-js_27510.html