이 기사의 내용은 미니 프로그램에서 캔버스에서 온라인 패턴 사용자 정의 기능을 구현하는 방법에 대한 것입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
최근에 vue 및 element-ui를 기반으로 하는 범용 배경 프레임 페이지에 대한 요청을 받았습니다. 구체적인 요구 사항은 다음과 같습니다.
높은 다양성이 필요하고 나중에 40개 이상의 하위 프로젝트에서 사용해야 하므로 대부분의 위치를 구성할 수 있습니다.
스캐폴딩 형식이어야 하며, npm으로 설치 가능합니다.
여러 탭을 구현해야 하며, 브라우저 URL을 통해 여러 탭을 에코할 수 있습니다. 또한 탭에 기록 기록이 유지되어야 하며 뒤로 돌아갈 수 있습니다.
구성 요소에는 첫 번째 화면 로딩 시간을 줄이기 위해 비동기 로딩이 필요합니다.
분명히 이것은 ERP와 유사한
애플리케이션입니다. JSP 및 기타 백엔드를 수행한 학생들은 다중 페이지 탭에 익숙할 것입니다.
类 ERP
的应用. 做过 JSP 等后台的同学,对多页签应该都很熟悉吧.
那接下来我们就来谈谈实现.
这点其实没啥难点,无非就是麻烦了点,把所有的数据,都提取出来,放在一个 config
文件里面.然后在框架页里面引入,并且绑定到相应的位置上去. 这边有个比较难以取舍的问题,就是如果把一溜的数据全部绑定到 vue 的 data 上面,由于数据量比较多,会导致性能问题,如果分开,又会使配置文件看起来相对复杂,增加后期使用人员的学习成本。这块要看具体的项目需求,由于我这边暂时对前端的性能要求没那么高,所以暂时用全部绑定到 data 的方案
起初产品对这个的需求使做成组件的形式,然后发布 npm 包,方便后期更新的时候,只需更新一下 npm 就可以了,无需每个项目去复制粘贴替换,但是基于这是一个框架页,而且可配置项非常多,还要实现 tab 多页签等多方面的考虑,最终选择了脚手架的方案,即便这样后期升级会稍微麻烦一点(起初的方案是框架页放在一个文件夹里,到时候直接替换该文件夹),但相对于组件来说,还是更好维护的,况且后期可以再写一个更新的脚手架,毕竟现在发布一个 npm 工具的成本实在是太低了。
第一次开发脚手架,看了很多社区的帖子,发现目前大部分脚手架,一般都基于2种形式,一种基于文件复制的形式,另一种基于 git-clone 的形式,经过对比,我觉得文件复制的有点复杂了,我其实只是需要一个能一键安装的工具而已,所以 git-clone 的形式还是比较适合我。
以下就是脚手架的代码,虽然只是简单的五六十行代码,不过查资料+趟坑,也花了我一个上午的时间。
#!/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: '请输入项目名称', default: 'my-project', validate: (name)=>{ if(/^[a-z]+/.test(name)){ return true; }else{ return '项目名称必须以小写字母开头'; } } }] inquirer.prompt(questions).then((dir)=>{ downloadTemplate(dir.name); }) function downloadTemplate(dir){ // 判断目录是否已存在 let isHasDir = fs.existsSync(path.resolve(dir)); if(isHasDir){ spinner.fail('当前目录已存在!'); return false; } spinner.start(`您选择的目录是: ${chalk.red(dir)}, 数据加载中,请稍后...`); // 克隆 模板文件 gitClone(`https://github.com/noahlam/vue-multi-tab.git`, dir , null, function(err) { // 移除无用的文件 shell.rm('-rf', `${dir}/.git`) spinner.succeed('项目初始化成功!') // 运行常用命令 shell.cd(dir) spinner.start(`正在帮您安装依赖...`); shell.exec('npm i') spinner.succeed('依赖安装成功!') shell.exec('npm run dev') }) }
如果你这个脚手架有疑问或者兴趣,可以直接访问 github 上的代码 tab-cli
要想实现多页签,那么 vue-router 基本算是废了,为什么? vue-router 是根据 url 来切换单个组件的,而页签则需要再组件内部同时存在多个子组件的,所以路由无法胜任(至少我是这么认为的,如果你有更好的方案,恳请不吝赐教)。
多个页签的显示,其实不难, element 有现成的 tab 组件,于是老夫写代码就是一把梭,撸起袖子就是干,噼里啪啦一顿写,写完一测,没有任何问题,实在是不要太简单,丢给产品预览:
复制浏览器地址到别的地方粘贴,tab 不能正确回显
tab 内需要实现跳转,而且要能返回。
第一个问题比较简单,自己手写一个基于 hash 的 伪路由
把当前 tab 的 id 放到 url 上去,然后回显的时候,根据 url 打开对应的 tab.
tip: 关于如何实现路由,请看我另外一篇博客 自己动手实现一个前端路由
第二个问题,大概就是本文的重点了,这里详细说明一下需求,每个 tab 都可以在 tab 内部 跳转
config
파일에 넣은 다음 프레임 페이지에 넣고 해당 위치에 바인딩하세요. 여기서 어려운 선택이 있습니다. 즉, 모든 데이터를 vue의 데이터에 바인딩하면 데이터의 양이 많아 분리되면 구성 파일이 상대적으로 보이게 됩니다. 복잡해 나중에 사용자의 학습 비용이 증가합니다. 이는 특정 프로젝트 요구 사항에 따라 다릅니다. 당분간은 프런트 엔드 성능 요구 사항이 그다지 높지 않기 때문에 모든 것을 데이터에 바인딩하는 솔루션을 일시적으로 사용하겠습니다.
🎜
🎜
비계 형태로 제작
🎜
🎜
처음에는 이에 대한 제품의 요구가 컴포넌트 형태로 이루어졌고, 이후 npm 패키지가 출시되었습니다. 이후 업데이트를 용이하게 하기 위해 npm을 업데이트하기만 하면 됩니다. 각 프로젝트를 복사하여 붙여넣고 교체할 필요는 없습니다. 게다가 구성 가능한 항목도 많고, 탭을 여러 개 구현하는 등 고려해야 할 사항도 많습니다. 나중에 업그레이드하는 것이 조금 번거롭긴 하지만 결국 스캐폴딩 솔루션을 선택했습니다. 필요한 경우 폴더를 직접 교체할 수 있지만 구성 요소에 비해 여전히 유지 관리가 더 쉽습니다. 또한 나중에 업데이트된 스캐폴딩을 작성할 수 있으므로 npm 도구를 게시하는 데 드는 비용은 다음과 같습니다. 지금은 너무 낮습니다.
🎜
🎜
제가 처음으로 scaffolding을 개발해보았는데, 많은 커뮤니티 게시물을 읽어보니 현재 scaffolding의 대부분이 일반적으로 파일 복사 기반과 git-clone 기반이라는 두 가지 형태를 기반으로 하고 있다는 것을 알게 되었습니다. 파일 복사가 좀 복잡한 것 같아요. 사실 원클릭으로 설치할 수 있는 도구만 있으면 되니까 git-clone 방식이 저에게는 더 맞는 것 같아요.
🎜
🎜
다음은 비계의 코드입니다. 간단한 50~60줄의 코드지만, 정보를 확인하고 피트를 통과하는 데 오전 내내 시간이 걸렸습니다.
🎜
으아악
🎜
이 스캐폴딩에 대해 질문이나 관심이 있는 경우 github의 tab-cli 코드에 직접 액세스할 수 있습니다.
🎜
🎜
여러 탭 구현
🎜
🎜
여러 탭을 구현하려는 경우 vue-router는 기본적으로 쓸모가 없습니다. vue-router는 URL을 기반으로 단일 구성 요소를 전환하는 반면 탭에는 구성 요소 내부에 동시에 여러 하위 구성 요소가 있어야 하므로 라우팅이 적합하지 않습니다(적어도 그렇게 생각합니다. 더 나은 솔루션이 있는 경우 저를 계몽 주시기 바랍니다)).
🎜
🎜
여러 개의 탭을 표시하는 것은 사실 어렵지 않습니다. Element에는 이미 만들어진 탭 구성 요소가 있으므로 그냥 소매를 걷어붙이고 작성을 시작하면 아무런 문제가 없습니다. 필요하지 않습니다. 제품 미리보기에 남겨두세요.
🎜
🎜
🎜
🎜
브라우저 주소를 복사해서 다른 곳에 붙여넣었지만 탭이 제대로 반향되지 않습니다.
🎜
🎜
🎜
🎜
점프는 탭 내에서 구현되어야 하며 돌아올 수 있어야 합니다.
🎜
🎜
🎜
🎜
첫 번째 질문은 비교적 간단합니다. 해시 기반 의사 라우팅
을 직접 작성하여 현재 탭의 ID를 URL에 넣은 다음 에코되면 URL에 따라 해당 탭을 엽니다. .
🎜
팁: 라우팅 구현 방법에 대해서는 프런트 엔드 라우팅 직접 구현에 대한 다른 블로그 게시물을 읽어보세요.
🎜
두 번째 질문은 아마도 이 글의 핵심일 것입니다. 각 탭은 탭 내부에서 jump
할 수 있습니다. 여기서의 점프는 기본적으로 vue-router와 동일합니다. 마찬가지로 푸시, 교체, 뒤로 이동이 가능해야 하며 매개변수를 사용할 수도 있습니다.
🎜
那么怎么实现呢? 首先维护一个打开的 tab 列表,然后每个列表里面再维护一个用过的组件列表(包含参数),这样大概就能实现了吗?当然不是,组件的跳转,参数的传递,不可能让使用者自己去实现这些方法吧,我选择把封装一个公共对象,然后挂载在 vue.prototype上。然后类似 vue.$router.xxxx 一样(我的命名是 vue.$tab)可以在页面的任何地方使用,如果你对具体的实现方法有兴趣,欢迎点击本文结尾的链接,去我的Github仓库上查看。
之前只用过基于 vue-router 的异步加载方法,然而这个项目里面并没有使用 vue-router,怎么异步呢? 翻了一下 vue 的官方文档是这么写的:
Vue.component( 'async-webpack-example', // 这个 `import` 函数会返回一个 `Promise` 对象。 () => import('./my-async-component') )
然而我试了一下,发现报错了,import 不能在这里使用,换了 require 也不行,不知道上我哪里没弄好,如果你刚好知道又刚好有空,请告诉我,谢谢!后面在 segmentfault 上 看到 这一篇, 使用 webpack 的 require.ensure 可以实现
// 第一个字符串是 组件名,第二个是 组件路径,第三个是 chunkName (如果不指定则以1.js,2.js....n.js命名) vue.component('home', (resolve) => {require.ensure([], ()=>resolve(require('@/Views/index.vue')), 'home')})
顺便还要在 webpack 里面的 output 下面配置一下 chunkFilename: '[name].js',
, 当然文件名格式可以按你项目的需求来,我这边就按最简单的
相关推荐:
위 내용은 미니 프로그램에서 캔버스 패턴의 온라인 사용자 정의 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!