Vue에서 테마에 따라 다양한 리소스를 얻고 사진을 전환하는 방법

青灯夜游
풀어 주다: 2021-12-02 19:12:28
앞으로
1952명이 탐색했습니다.

Vue에서 테마에 따라 다양한 리소스를 얻고 이미지를 전환하는 방법은 무엇입니까? 다음 기사에서는 다중 이미지 스키닝 요구 사항을 실현하는 Vue의 우아한 방법을 소개합니다. 이것이 도움이 되기를 바랍니다.

Vue에서 테마에 따라 다양한 리소스를 얻고 사진을 전환하는 방법

[관련 추천: "vue.js Tutorial"]

최근 회사 Y의 작은 게임은 현지화된 테마를 구현해야 합니다. 즉, 지역마다 다른 테마를 표시해야 하며 게임은 사진이 많으니 어떻게 우아해져야 하는지 정확한 피부 이미지를 빠르게 로딩하는 것이 특히 중요합니다.

CSS 스타일 전환 커뮤니티에는 이미 많은 솔루션이 있으므로 직접 참조할 수 있습니다. 기사에서 이미 자세히 설명했으므로 여기서는 주로 다양한 리소스를 얻는 방법에 대해 설명하지 않겠습니다. 테마에 따라 이미지를 전환합니다.

초기 계획

이미지 리스킨닝, 과거 경험을 바탕으로 웹팩의 종속성 관리 덕분에 우리는 일반적으로 이미지를 도입할 때 require를 사용합니다. 예를 들어(require(`@assets/img/${theme}/bg.png`))를 작성하는 방식으로 웹팩은 모든 파일을@assets/img에 저장합니다. code> 모두 번들에 추가되므로 런타임 중에 해당 이미지를 찾을 수 있습니다. 구체적인 구현은 다음과 같습니다. (require(`@assets/img/${theme}/bg.png`)),webpack会将@assets/img中的所有文件都加入到bundle中,从而在运行的时候可以找到对应的图片。具体实现如下:

 
로그인 후 복사

以上代码基本上能解决大部分的换肤需求,但是对于图片需要预先加载的项目,我们还需要区分不同主题的图片便于优化提前加载,由于编译后的图片链接跟编译前的链接是不同,因此我们获取编译后的图片链接。一般的项目中比如使用官方脚手架vue-cli构建的项目,所有的图片都会被url-loader处理后放到同一个文件夹image当中,这样编译前不同文件夹相同名字的图片编译后之后hash是不同,因此我们是无法区分不同主题的图片的。

于是,首先我们需要将不同的主题图片放置到不同的文件夹当中,同样适用用url-loader

// vue-cli配置 const imagesRule = config.module.rule('images'); imagesRule.uses.clear() //清除原本的images loader配置 imagesRule .test(/white/.+.(jpg|gif|png|svg)$/) .use('url-loader') .loader('url-loader') .options({ name:"img/white/[name].[hash:8].[ext]", limit: 8192 }) // 加多一个主题的配置 config.module .rule('image2') .test(/black/.+.(jpg|gif|png|svg)$/) .use('url-loader') .loader('url-loader') .options({name:"img/black/[name].[hash:8].[ext]", limit: 8192 }) // 自定义webpack配置 rules: [ { test: /white/.+.(png|svg|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: 'img/white/[name].[hash:8].[ext]', } } ], }, { test: /black/.+.(png|svg|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: 'img/black/[name].[hash:8].[ext]', } } ], }, ]
로그인 후 복사

这样子编译后不同主题的图片就会被放置到不同的文件夹当中,这样就结束了吗?还没有,我们还需要获取编译后的图片链接,才能在进入游戏页面的时候提前加载主题图片,这里我们可以写一个webpack plugin来帮我们收集相应的图片,生产各自主题的json文件。插件代码如下:

// webpack版本为4.x class WebPackSouceManifest { // 将 `apply` 定义为其原型方法,此方法以 compiler 作为参数 constructor(option = {}) { // 黑色主题的文件名 this.blackManifestName = option.blackManifestName || 'js/blackManifest.json' // 白色主题的文件名 this.whiteManifestName = option.whiteManifestName || 'js/whiteManifest.json' this.blackJsonData = { code: 0, data: [] } this.whiteJsonData = { code: 0, data: [] } this.addFileToSouceManifest.bind(this) } apply(compiler) { // 指定要附加到的事件钩子函数 compiler.hooks.emit.tapAsync( 'HashServiceWorkerStartPlugin', (compilation, callback) => { const allBuildFiles = Object.keys(compilation.assets) allBuildFiles.forEach((file) => { if (file.indexOf('white') !== -1) { this.addFileToSouceManifest('white', file) } else { this.addFileToSouceManifest('black', file) } }) const sourceBlack = JSON.stringify(this.blackJsonData) const sourceWhite = JSON.stringify(this.whiteJsonData) compilation.assets[this.blackManifestName] = { source: () => { return sourceBlack; }, size: () => { return sourceBlack.length; } } compilation.assets[this.whiteManifestName] = { source: () => { return sourceWhite; }, size: () => { return sourceWhite.length; } } callback() } ); } addFileToSouceManifest(type, file) { let fileItem = { src: file, } if (/.js$/.test(file)) { fileItem.type = 'text' } else if (/.js.map$/.test(file)) { fileItem.type = 'json' } if (type === 'white') { this.whiteJsonData.data.push(fileItem) } else { this.blackJsonData.data.push(fileItem) } } } module.exports = WebPackSouceManifest;
로그인 후 복사

因此我们得到不同主题的图片列表json,在进入页面的时候通过ajax获取到列表之后对别表中的图片进行加载,虽然以上的做法可以实现需求,但是实在太过复杂?那还有没有轻松的方式呢?当然是有的。

优化方案

仔细分析上面的代码后她,我们最终要获得的是图片编译后的结果,所以如果我们能够生成一个图片对象,将图片的name

 
로그인 후 복사

위 코드는 기본적으로 대부분의 스킨 변경 요구를 해결할 수 있지만, 이미지 사전 로딩이 필요한 프로젝트의 경우 최적화 및 조기 로딩을 용이하게 하기 위해 다양한 테마의 이미지를 구별해야 합니다. 컴파일된 이미지 링크와 컴파일은 이전 링크가 다르기 때문에 컴파일된 이미지 링크를 얻습니다. 공식 스캐폴딩 vue-cli를 사용하여 빌드한 프로젝트 등 일반 프로젝트에서는 모든 이미지를 url-loader로 처리한 후 동일한 폴더 이미지에 배치하여 Before를 컴파일합니다.

다른 폴더에 있는 동일한 이름의 사진

편집 후 해시가 다르기 때문에 서로 다른 테마의 사진을 구별할 수 없습니다.

그러므로 먼저 서로 다른 테마 사진을 서로 다른 폴더에 배치해야 합니다. url-loader

const black = require.context('../black', true, /.(png|jpg|gif)$/); const middleImageObj = {}; black.keys().forEach(path => { // 获取图片的key const key = path.slice(2, -4); blackImageObj[key] = rawSkin(path); });
로그인 후 복사
로그인 후 복사

를 사용할 때도 마찬가지입니다. 이런 식으로 편집 후에는 서로 다른 테마의 사진이 서로 다른 폴더에 배치됩니다. 위에? 아직은 게임 페이지에 들어갈 때 테마 이미지를 미리 로드하기 위해 컴파일된 이미지 링크를 가져와야 합니다. 여기에서 해당 이미지를 수집하고 각 테마에 대한 json 파일을 생성하는 데 도움이 되는 webpack 플러그인을 작성할 수 있습니다. 플러그인 코드는 다음과 같습니다:
const black = require.context('../black', true, /.(png|jpg|gif)$/); const middleImageObj = {}; black.keys().forEach(path => { // 获取图片的key const key = path.slice(2, -4); blackImageObj[key] = rawSkin(path); });
로그인 후 복사
로그인 후 복사

그래서 우리는 다양한 테마의 json 이미지 목록을 얻습니다. 페이지에 들어갈 때 ajax를 통해 목록을 얻은 다음 위의 접근 방식을 충족할 수 있지만 이미지를 로드합니다. 요구 사항이 너무 복잡합니까? 쉬운 방법이 있나요? 물론 있습니다.

최적화 계획

위 코드를 주의 깊게 분석한 결과, 우리가 궁극적으로 얻고자 하는 것은 이미지의 컴파일된 결과이므로 그림 객체를 생성할 수 있다면, picture이름이 키로 사용되며, 이미지의 컴파일된 결과가 값으로 사용됩니다. 그러면 위 코드는 다음과 같이 단순화될 수 있습니다.

rrreee

이렇게 하면 코드가 간결해집니다. , 기사 전체에서 require 및 try catch가 필요하지 않습니다. 그러면 이 skinImage 개체를 어떻게 구현합니까?

답은 webpack의 require.context를 사용하는 것입니다

require.context 함수를 실행하여 특정 컨텍스트를 가져옵니다. 주로 자동화된 가져오기 모듈을 구현하는 데 사용됩니다. 폴더에서 많은 모듈을 가져올 때 이 API를 사용할 수 있습니다. 매번 가져오기 모듈을 명시적으로 호출해야 합니다. 자세한 사용법은 여기에서 설명하지 않습니다.

자세한 내용은 공식 문서 requirecontext를 확인하세요https://webpack.docschina.org/guides/dependent-management/#requirecontext 그러면 자동으로 이미지를 가져와서 skinImage 객체를 생성하는 함수를 작성해 보겠습니다rrreee이렇게 하면 검은색 테마 이미지 객체를 얻게 됩니다. require.context는 런타임이 아닌 컴파일 과정에서 실행되므로 모든 매개변수는 정적일 수 있습니다. . 여기서도 다음과 같이 흰색 테마 이미지를 미리 가져와야 합니다. rrreee이 방법으로 두 테마의 이미지 개체를 얻은 다음 루트 구성 요소의 skinImage에 특정 개체만 할당하면 됩니다. 위의 것보다 더 간단하고 간결합니까? 더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 소개를 방문하세요! !

위 내용은 Vue에서 테마에 따라 다양한 리소스를 얻고 사진을 전환하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
vue
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.