您好,登錄后才能下訂單哦!
小編給大家分享一下小程序中canvas怎么實(shí)現(xiàn)圖案在線定制的功能,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
最近收到一個(gè)這樣的需求,要求做一個(gè)基于 vue 和 element-ui 的通用后臺(tái)框架頁,具體要求如下:
要求通用性高,需要在后期四十多個(gè)子項(xiàng)目中使用,所以大部分地方都做成可配置的.
要求做成腳手架的形式.可以 npm 安裝
要求實(shí)現(xiàn)多頁簽,并且可以通過瀏覽器 url 回顯多頁簽.而且頁簽內(nèi)要維護(hù)一個(gè)歷史記錄,可以后退
組件要求異步加載,減少首屏加載時(shí)間.
很明顯,這就是一個(gè) 類 ERP
的應(yīng)用. 做過 JSP 等后臺(tái)的同學(xué),對(duì)多頁簽應(yīng)該都很熟悉吧.
那接下來我們就來談?wù)剬?shí)現(xiàn).
這點(diǎn)其實(shí)沒啥難點(diǎn),無非就是麻煩了點(diǎn),把所有的數(shù)據(jù),都提取出來,放在一個(gè) config
文件里面.然后在框架頁里面引入,并且綁定到相應(yīng)的位置上去. 這邊有個(gè)比較難以取舍的問題,就是如果把一溜的數(shù)據(jù)全部綁定到 vue 的 data 上面,由于數(shù)據(jù)量比較多,會(huì)導(dǎo)致性能問題,如果分開,又會(huì)使配置文件看起來相對(duì)復(fù)雜,增加后期使用人員的學(xué)習(xí)成本。這塊要看具體的項(xiàng)目需求,由于我這邊暫時(shí)對(duì)前端的性能要求沒那么高,所以暫時(shí)用全部綁定到 data 的方案
起初產(chǎn)品對(duì)這個(gè)的需求使做成組件的形式,然后發(fā)布 npm 包,方便后期更新的時(shí)候,只需更新一下 npm 就可以了,無需每個(gè)項(xiàng)目去復(fù)制粘貼替換,但是基于這是一個(gè)框架頁,而且可配置項(xiàng)非常多,還要實(shí)現(xiàn) tab 多頁簽等多方面的考慮,最終選擇了腳手架的方案,即便這樣后期升級(jí)會(huì)稍微麻煩一點(diǎn)(起初的方案是框架頁放在一個(gè)文件夾里,到時(shí)候直接替換該文件夾),但相對(duì)于組件來說,還是更好維護(hù)的,況且后期可以再寫一個(gè)更新的腳手架,畢竟現(xiàn)在發(fā)布一個(gè) npm 工具的成本實(shí)在是太低了。
第一次開發(fā)腳手架,看了很多社區(qū)的帖子,發(fā)現(xiàn)目前大部分腳手架,一般都基于2種形式,一種基于文件復(fù)制的形式,另一種基于 git-clone 的形式,經(jīng)過對(duì)比,我覺得文件復(fù)制的有點(diǎn)復(fù)雜了,我其實(shí)只是需要一個(gè)能一鍵安裝的工具而已,所以 git-clone 的形式還是比較適合我。
以下就是腳手架的代碼,雖然只是簡單的五六十行代碼,不過查資料+趟坑,也花了我一個(gè)上午的時(shí)間。
#!/usr/bin/env node const shell = require('shelljs'); const program = require('commander'); const inquirer = require('inquirer'); const ora = require('ora'); const fs = require('fs'); const path = require('path'); const spinner = ora(); const gitClone = require('git-clone') const chalk = require('chalk') program .version('1.0.0', '-v, --version') .parse(process.argv); const questions = [{ type: 'input', name: 'name', message: '請(qǐng)輸入項(xiàng)目名稱', default: 'my-project', validate: (name)=>{ if(/^[a-z]+/.test(name)){ return true; }else{ return '項(xiàng)目名稱必須以小寫字母開頭'; } } }] inquirer.prompt(questions).then((dir)=>{ downloadTemplate(dir.name); }) function downloadTemplate(dir){ // 判斷目錄是否已存在 let isHasDir = fs.existsSync(path.resolve(dir)); if(isHasDir){ spinner.fail('當(dāng)前目錄已存在!'); return false; } spinner.start(`您選擇的目錄是: ${chalk.red(dir)}, 數(shù)據(jù)加載中,請(qǐng)稍后...`); // 克隆 模板文件 gitClone(`https://github.com/noahlam/vue-multi-tab.git`, dir , null, function(err) { // 移除無用的文件 shell.rm('-rf', `${dir}/.git`) spinner.succeed('項(xiàng)目初始化成功!') // 運(yùn)行常用命令 shell.cd(dir) spinner.start(`正在幫您安裝依賴...`); shell.exec('npm i') spinner.succeed('依賴安裝成功!') shell.exec('npm run dev') }) }
如果你這個(gè)腳手架有疑問或者興趣,可以直接訪問 github 上的代碼 tab-cli
要想實(shí)現(xiàn)多頁簽,那么 vue-router 基本算是廢了,為什么? vue-router 是根據(jù) url 來切換單個(gè)組件的,而頁簽則需要再組件內(nèi)部同時(shí)存在多個(gè)子組件的,所以路由無法勝任(至少我是這么認(rèn)為的,如果你有更好的方案,懇請(qǐng)不吝賜教)。
多個(gè)頁簽的顯示,其實(shí)不難, element 有現(xiàn)成的 tab 組件,于是老夫?qū)懘a就是一把梭,擼起袖子就是干,噼里啪啦一頓寫,寫完一測(cè),沒有任何問題,實(shí)在是不要太簡單,丟給產(chǎn)品預(yù)覽:
復(fù)制瀏覽器地址到別的地方粘貼,tab 不能正確回顯
tab 內(nèi)需要實(shí)現(xiàn)跳轉(zhuǎn),而且要能返回。
第一個(gè)問題比較簡單,自己手寫一個(gè)基于 hash 的 偽路由
把當(dāng)前 tab 的 id 放到 url 上去,然后回顯的時(shí)候,根據(jù) url 打開對(duì)應(yīng)的 tab.
tip: 關(guān)于如何實(shí)現(xiàn)路由,請(qǐng)看我另外一篇博客 自己動(dòng)手實(shí)現(xiàn)一個(gè)前端路由
第二個(gè)問題,大概就是本文的重點(diǎn)了,這里詳細(xì)說明一下需求,每個(gè) tab 都可以在 tab 內(nèi)部 跳轉(zhuǎn)
,這里的跳轉(zhuǎn),要做的跟 vue-router 的有大體上差不多,要能 push, replace, back,還能帶參數(shù)。
那么怎么實(shí)現(xiàn)呢? 首先維護(hù)一個(gè)打開的 tab 列表,然后每個(gè)列表里面再維護(hù)一個(gè)用過的組件列表(包含參數(shù)),這樣大概就能實(shí)現(xiàn)了嗎?當(dāng)然不是,組件的跳轉(zhuǎn),參數(shù)的傳遞,不可能讓使用者自己去實(shí)現(xiàn)這些方法吧,我選擇把封裝一個(gè)公共對(duì)象,然后掛載在 vue.prototype上。然后類似 vue.$router.xxxx 一樣(我的命名是 vue.$tab)可以在頁面的任何地方使用,如果你對(duì)具體的實(shí)現(xiàn)方法有興趣,歡迎點(diǎn)擊本文結(jié)尾的鏈接,去我的Github倉庫上查看。
之前只用過基于 vue-router 的異步加載方法,然而這個(gè)項(xiàng)目里面并沒有使用 vue-router,怎么異步呢? 翻了一下 vue 的官方文檔是這么寫的:
Vue.component( 'async-webpack-example', // 這個(gè) `import` 函數(shù)會(huì)返回一個(gè) `Promise` 對(duì)象。 () => import('./my-async-component') )
然而我試了一下,發(fā)現(xiàn)報(bào)錯(cuò)了,import 不能在這里使用,換了 require 也不行,不知道上我哪里沒弄好,如果你剛好知道又剛好有空,請(qǐng)告訴我,謝謝!后面在 segmentfault 上 看到 這一篇, 使用 webpack 的 require.ensure 可以實(shí)現(xiàn)
// 第一個(gè)字符串是 組件名,第二個(gè)是 組件路徑,第三個(gè)是 chunkName (如果不指定則以1.js,2.js....n.js命名) vue.component('home', (resolve) => {require.ensure([], ()=>resolve(require('@/Views/index.vue')), 'home')})
以上是小程序中canvas怎么實(shí)現(xiàn)圖案在線定制的功能的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。