これは NetEase Cloud Music の PC 側を模倣した Web アプリケーションであり、Vue + Element UI に基づいて構築されており、Web ページの本体はウィンドウ アプリを開くように設計されています。アプリケーションの本体はウィンドウであり、右下隅をドラッグしてウィンドウのサイズを変更できます。Web アプリケーションとしてこのように設計するのは少し奇妙かもしれませんが、そうではありません。おそらく、クラウド デスクトップに似た感覚の Web デスクトップが将来派生する可能性があります。
おそらく、将来的には、このような Web デスクトップを構築し、各ウィンドウのライフサイクルを管理するための基本的なプラットフォームを提供し、このプラットフォームに基づいて Web アプリケーションを開発し、独自のものを配置することを試みることができるでしょう。その上のWebアプリケーション。
プロジェクトのバックエンドは、NetEase Cloud Music NodeJS バージョン API とプロジェクトの完全なインターフェイス ドキュメントから取得されます。
このプロジェクトのインターフェイス ドキュメント ページにはアクセスできなくなりました。オフライン ドキュメントを生成しました。ここからダウンロードできます。
プロジェクトにはまだ完成していないページがいくつかありますが、主要なページは完成しており、プロジェクトは継続的に更新され、私の NetEase Cloud Music (模倣) に展開されます。
サーバーが国内サーバーで、国内ホストへのドメイン名解決には登録が必要で、居住許可を持っていないため登録が通らないため、IPで直接アクセスするしかありません。
このセクションでは、このプロジェクトを適切に動作させる方法について説明します
$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi.git
$ npm install
サーバー起動用のデフォルトのポートは 3000 です。ポート 3000 を使用したくない場合は、次のコマンドを使用できます: windows
$ set PORT=4000
Mac/Linux の場合
$ PORT=4000
$ cd NeteaseCloudMusicApi
$ node app.js
$ git clone https://github.com/ColorlessWin/cloud_music.git
$ npm install
プロジェクトのデフォルトのサーバー アドレスはhttp://localhost
で、ポートは3000
です。これを変更する必要がある場合は、このプロジェクトのルート ディレクトリに新しい.env.local
ファイルを作成し、次のキーと値のペアを書き留めます。 。
VUE_APP_HOST=/*这里填你的服务器地址(需要加http或https前缀)*/
VUE_APP_PORT=/*这里填你的服务器端口*/
/**
* 示例
* VUE_APP_HOST=https://webservices.fun
* VUE_APP_PORT=80
*/
$ npm run serve
$ npm run build
このプロジェクトには、独自に作成した Webpack プラグインが含まれており、その機能は、ビルドの完了後にビルドされたファイルをサーバーに自動的にアップロードすることです。ただし、
.env.local
ファイルの構成により、正しくビルドできるのはこのプラグインだけです。私のコンピューターでサーバーを見つけてファイルをアップロードすると、コンピューター上でビルドするときにエラーが報告されますが、これはプロジェクトのビルドには影響しません。
ローカルで実行しているだけの場合は、すべての構成をデフォルトのままにしておきます。
このパートでは、プロジェクトのコア コンポーネントである<Rendering/>
について説明します。このコンポーネントはプロジェクト内の多数のページで使用されます。このコンポーネントの動作を理解することは、このコンポーネントのソース コードのほとんどを理解するための重要な方法です。プロジェクト。
<Rendering/>
コンポーネントは、Array<Object>
形式に抽象化できるプロジェクト内のすべてのデータをレンダリングする役割を果たします。プロジェクトには、曲リスト、歌手リスト、アルバム リスト、コメント リストなどの大量のデータが含まれています。 etc.Array<Object>
形式に準拠したデータ。また、
<Rendering/>
コンポーネントは、これらのデータのロード、ページング処理なども引き継ぎます。必要なことは、filling
メソッドを実装し、それを<Rendering/>
コンポーネントに渡すだけです。小道具。
このコンポーネントは、プロジェクト内の簡単なページを通じて紹介します。
これは MV 分類ページです。異なる分類タグを切り替えると、ページ下部に簡単なページング機能もあります。 <Rendering/>
を使用してこれらの関数を簡単に実装する方法を見てみましょう。
まずはこのページを試してみてください
下のページネーション
このページのソース コード部分の一般的な構造を見てみましょう。
< template >
< span >地区:</ span >
< simple-radio :options = " areaLabel " v-model = " area " /> < br >
< span >类型:</ span >
< simple-radio :options = " typeLabel " v-model = " type " /> < br >
< span >排序:</ span >
< simple-radio :options = " orderLabel " v-model = " order " /> < br >
< rendering
class = " mvs "
:component = " require('@/components/content/matrices/CommonVideoMatrices').default "
:adapter = " adapter "
:show-creator = " true "
:total = " total "
:filling = " filling "
:unique = " area + type + order "
/>
</ template >
< script >
import ...
export default {
name : " Mv " ,
components : {LArea, Rendering, SimpleRadio},
data () {
return {
total : - 1 ,
area : '全部' ,
type : '全部' ,
order : '上升最快' ,
areaLabel : [ '全部' , '内地' , '港台' , '欧美' , '日本' ],
typeLabel : [ '全部' , '官方版' , '原声' , '现场版' , '网易出品' ],
orderLabel : [ '上升最快' , '最热' , '最新' ],
adapter : { ... }
}
},
methods : {
filling ( offset , limit , first_load ) { ... }
}
}
</ script >
注意を必要としない一部の内容はここに折りたたまれています。完全なソース コードについては、ここを参照してください。
ページのテンプレート部分は比較的単純であることがわかります。最初の 3 つの<simple-radio/>
コンポーネントは、 data
で定義された 3 つの Label 配列を通じてレンダリングされます。ラベルがクリックされます。 次に、 v-model
を通じて対応するバインドされたプロパティを更新し、その後、多くのプロパティがバインドされた<rendering/>
コンポーネントを更新します。
<rendering/>
コンポーネントの詳細<rendering/>
にはたくさんの props があるように見えますが、実際はそうではありません。 <rendering/>
は 2 つの props しかなく、他の props は内部の<component/>
と<pagination/>
に渡されます。
< template >
< div >
< component
:is = " component "
v-bind = " Object.assign(props, $attrs) "
v-on = " $listeners "
/>
< pagination
v-model = " props.datas "
v-on = " $listeners "
v-bind = " $attrs "
:filling = " filling "
/>
</ div >
</ template >
< script >
import Pagination from " @/components/common/Pagination " ;
export default {
name : " Rendering " ,
components : {Pagination},
props : {
component : { type : [ Object , Function ], required : true },
filling : { type : Function , required : true },
},
data () {
return {
props : {
datas : [],
}
}
}
}
</ script >
<Rendering/>
ソース コード スニペット。注意する必要のない一部の内容はここでは削除されています。完全なソース コードについては、ここを参照してください。
<pagination/>
はページング コンポーネントであり、ページング コンポーネントをレンダリングして対話を提供し、データのロードを管理します。
<component/>
は、 component
prop を通じて渡されるコンポーネントをロードする役割を果たします。この MV ページでは、 require([path]).default
を通じてCommonVideoMatrices
コンポーネントをcomponent
に動的に渡します。 component
はCommonVideoMatrices
CommonVideoMatrices
内のv-on="$listeners"
$emit
イベントを<rendering/>
で直接リッスンできることを意味します。
CommonVideoMatrices
、実際の MV 表示リストをレンダリングする役割を果たします。実際には、datas
のプロップ (datas
は常にArray<Object>
形式のデータである必要があります) を受け取り、datas
ページを通じてそれをレンダリングします。プロジェクトには、
CommonVideoMatrices
デザインに似たコンポーネントが多数あります。それらはすべて、datas
prop を介して独自のデータをレンダリングします。これらのコンポーネントは、src/cmoponents/content/tracks
にあります。datas prop を含むdatas
は 1 つだけです<rendering/>
src/cmoponents/content/tracks
およびsrc/component/content/matrices
の下にあります。
<Pagination/>
インタラクションを提供するためにページング コンポーネントをページ上にレンダリングします。このページング コンポーネントは、 prop
total
指定した場合にのみレンダリングされます。それ以外の場合はレンダリングされませんが<Pagination/>
ソース コードを参照してください。
上記では、 <Rendering/>
コンポーネントの内部構造と詳細を紹介していますが、少なくとも、 component
prop を介して<Rendering/>
を含むdatas
を渡すと、このコンポーネントのレンダリングに役立つことがわかります。しかし、このコンポーネントは誰が提供するのでしょうか。datas datas
はどのような方法でデータを渡しますか?
これにより、 <Rendering/>
コンポーネント内に別のプロップfilling
表示されます。
他のプロパティとは異なり、 filling
関数を渡す必要があります。この関数は必要に応じて自動的に呼び出され、Promise を返すために使用されます。
この機能がどのように実装されているかは MV ページで確認できます。
methods: {
filling ( offset , limit , first_load ) {
return new Promise ( resolve => {
mvs ( this . area , this . type , this . order , offset , limit )
. then ( result => {
if ( first_load ) this . total = result [ 'count' ]
resolve ( result [ 'data' ] )
} )
} )
}
}
この関数はパラメータとして
<rendering/>
に渡され、その内部関数は<pagination/>
に渡され、いつ呼び出すかを決定します。
mvs(area, type, order, offset, limit)
バックエンド mv データのインターフェイスです。最初の 3 つのパラメーターは、ページングに使用される mv のタイプ、offset
、およびlimit
決定するために使用されます。
<pagination/>
によってページ上にレンダリングされたページング コンポーネントがクリックされると、fill メソッドが内部で呼び出され、いくつかのパラメーターがmvs
インターフェイスによってページング パラメーターとして使用され、インターフェイス データが返されるときにリゾルブを介して渡されます。 <pagination/>
の内部に、今度はデータがキャッシュされ、データが正常にレンダリングできるように<Rendering/>
を通じてCommonVideoMatrices
にデータが渡されます。
fill は、ページが最初に読み込まれるときにも呼び出されます。
ユーザーが他のタグやカテゴリを選択した後も、ページは新しいデータをリロードする必要があることがわかります。 <simple-radio/>
のクリック イベントをリッスンしてから、何らかの方法で<pagination/>
呼び出しに通知することを考えるかもしれません。充填方法はデータを更新しますか?
必要ありません! ! この関数を実装するもっと簡単な方法があります
< rendering
...
:unique =" area + type + order "
/>
unique
最終的に<pagination/>
に渡されます。
area
type
order
これらはすべて、v-model
を介して 3 つの異なる<simple-radio/>
にバインドされています。
<rendering/>
コンポーネントにunique
unique
プロパティを追加し、データの更新に応答するために使用される値を渡すだけです。これは多くの場合、非常に便利です。このシナリオでは、たとえば、プレイリストの ID が変更された場合、新しいプレイリスト データがリロードされます。このとき、ID をunique
に渡し、ID が変更されたときに新しい曲を埋めるメソッドを実装するだけです。単一のデータが自動的にロードされます。
このページでは、 <Rendering/>
が非常に便利であることがわかります。このページを作成するときは、データの取得方法やロジックについては考えずに、 CommonVideoMatrices
の内容だけに集中できます。読み込み中... アニメーション効果が表示されます。これらも<Rendering/>
によって完了しますが、この部分はここに示すコード スニペットで合理化されています。
実は、バックエンドが同じ種類のデータを異なる場所に、異なるデータ構造で返すという問題を解決するために使用される
adapter
と呼ばれるものもありますが、ここでは紹介しません。
これは初心者向けのプロジェクトであり、フロントエンド/Vue に慣れていない学生にインスピレーションと参考になることを願っています。プロジェクトの多くの場所がこの方法で実装されていると思います。この部分を読むと、このプロジェクトのソース コードの一部をより明確に理解できるようになります。