هذا تطبيق ويب يحاكي جانب الكمبيوتر الشخصي في NetEase Cloud Music، وهو مبني على واجهة المستخدم Vue + Element. النمط العام للصفحة بسيط نسبيًا. تم تصميم النص الرئيسي لصفحة الويب ليكون مشابهًا لفتح تطبيق النافذة سطح مكتب Windows الجزء الرئيسي من التطبيق عبارة عن نافذة، والتي يمكن الوصول إليها من خلال سحب الزاوية اليمنى السفلية لتغيير حجم النافذة. على الرغم من أنه قد يكون من الغريب بعض الشيء أن يتم تصميم تطبيق ويب بهذه الطريقة، إلا أنه ليس كذلك ربما يمكن استخلاص سطح مكتب ويب في المستقبل، على غرار الشعور بسطح المكتب السحابي.
يبدو أنها فكرة جيدة جدًا، ربما في المستقبل، يمكنك محاولة إنشاء سطح مكتب الويب هذا، وتوفير منصة أساسية لإدارة دورة حياة كل نافذة، ثم تطوير تطبيقات الويب بناءً على هذه المنصة ووضع تطبيقاتك الخاصة. تطبيقات الويب عليه.
تأتي الواجهة الخلفية للمشروع من إصدار 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
تحت ماك/لينكس
$ 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
يحتوي هذا المشروع على مكون إضافي لحزمة الويب مكتوب ذاتيًا، وتتمثل وظيفته في تحميل الملفات المضمنة تلقائيًا إلى الخادم بعد اكتمال الإنشاء، ومع ذلك، نظرًا لتكوين ملف
.env.local
، فإنه لا يمكن أن يكون صحيحًا إلا عند البناء عليه جهاز الكمبيوتر الخاص بي، ابحث عن الخادم وقم بتحميل الملف، لذلك سيتم الإبلاغ عن خطأ عند الإنشاء على جهاز الكمبيوتر الخاص بك، لكن هذا لن يؤثر على إنشاء المشروع.
إذا كنت تقوم بتشغيله محليًا فقط، فما عليك سوى الاحتفاظ بجميع التكوينات كإعداد افتراضي.
سيقدم لك هذا الجزء عنصر <Rendering/>
، وهو مكون أساسي في المشروع. يُستخدم هذا المكون في عدد كبير من الصفحات في المشروع. يعد فهم كيفية عمل هذا المكون طريقة مهمة لفهم معظم الكود المصدري لهذا مشروع.
يعد مكون
<Rendering/>
مسؤولاً عن عرض جميع البيانات الموجودة في المشروع والتي يمكن استخلاصها بتنسيقArray<Object>
. يحتوي المشروع على كمية كبيرة من هذه البيانات، مثل قوائم الأغاني وقوائم المغنيين وقوائم الألبومات وقوائم التعليقات. إلخ. البيانات المطابقة لتنسيقArray<Object>
.وسيتولى مكون
<Rendering/>
أيضًا تحميل هذه البيانات ومعالجة الترحيل وما إلى ذلك. ما عليك فعله بسيط جدًا، ما عليك سوى تنفيذ طريقةfilling
وتمريرها إلى مكون<Rendering/>
من خلاله الدعائم.
وسنقدم هذا المكون من خلال صفحة بسيطة في المشروع.
هذه صفحة تصنيف MV. من خلال تبديل علامات التصنيف المختلفة، ستعرض لك الصفحة قائمة 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 >
تم طي بعض المحتوى الذي لا يتطلب الاهتمام هنا للحصول على كود المصدر الكامل، يرجى الاطلاع هنا.
يمكنك أن ترى أن جزء القالب من الصفحة بسيط نسبيًا. الأول هو مكونات <simple-radio/>
الثلاثة، ووظائفها بسيطة للغاية. يتم عرض التسميات المقابلة من خلال صفائف الملصقات الثلاثة المحددة في data
يتم النقر على الملصقات ثم قم بتحديث الخصائص المرتبطة المقابلة من خلال v-model
، ثم مكون <rendering/>
مع العديد من الدعائم المرتبطة به.
<rendering/>
تفاصيل المكون يبدو أن <rendering/>
لديه الكثير من الخاصيات، لكن الأمر ليس كذلك. <rendering/>
لديه خاصيتين فقط، وسيتم تمرير الخاصيات الأخرى إلى <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
في صفحة MV هذه، أقوم بتمرير مكون CommonVideoMatrices
ديناميكيًا إلى component
من خلال require([path]).default
. component
ويمكنك أن ترى أنني أقوم بتوكيل الأحداث داخل CommonVideoMatrices
من خلال v-on="$listeners"
، مما يعني أنه يمكنك الاستماع مباشرة إلى الحدث $emit
داخل CommonVideoMatrices
على <rendering/>
CommonVideoMatrices
هو المسؤول عن عرض قائمة عرض MV الفعلية، وهو مسؤول فعليًا عن عرض البيانات على هذه الصفحة، ويقبل داخليًا خاصيةdatas
(يجب أن تكونdatas
دائمًا بتنسيقArray<Object>
) ويعرضها من خلال صفحةdatas
هناك العديد من المكونات في المشروع المشابهة لتصميم
CommonVideoMatrices
، وجميعها تعرض بياناتها الخاصةsrc/cmoponents/content/tracks
خلال خاصيةdatas
. يمكن تمرير مكون واحد فقط يحتوي على خاصيةdatas
في<rendering/>
src/cmoponents/content/tracks
وتحتsrc/component/content/matrices
<Pagination/>
مكون ترحيل الصفحات على الصفحة لتوفير التفاعلسيتم عرض مكون الترحيل هذا فقط عند توفير
total
الخاصية. وإلا، فلن يتم عرضه، ولكن لا يزال بإمكانك إدارة تحميل البيانات. لمزيد من التفاصيل حول<Pagination/>
يمكنك عرض الكود المصدري.
يقدم ما سبق البنية الداخلية وبعض التفاصيل الخاصة بمكون <Rendering/>
، على الأقل نعلم أنه من خلال خاصية component
، يمكننا تمرير مكون يحتوي على datas
<Rendering/>
إليه. ولكن من سيعطي هذا المكون خاصية datas
لتمرير البيانات من خلال أي طريقة؟
يؤدي هذا إلى ظهور filling
أخرى للدعائم داخل مكون <Rendering/>
.
على عكس الدعائم الأخرى، filling
تحتاج إلى تمرير دالة إليها، وسيتم استخدامها لتحميل البيانات.
يمكننا أن نرى كيف يتم تنفيذ هذه الوظيفة في صفحة 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 الخلفية، يتم استخدام المعلمات الثلاثة الأولى لتحديد نوع mvoffset
limit
المستخدم للترحيل.
عند النقر على مكون الترحيل الذي يتم عرضه على الصفحة بواسطة <pagination/>
، يتم استدعاء طريقة التعبئة داخليًا ويتم تمرير بعض المعلمات. يتم استخدام هذه المعلمات كمعلمات ترحيل بواسطة واجهة mvs
ويتم تمريرها من خلال الحل عند إرجاع بيانات الواجهة بنجاح إلى داخل <pagination/>
، سيتم تخزين البيانات مؤقتًا هذه المرة، وسيتم تمرير البيانات إلى CommonVideoMatrices
من خلال <Rendering/>
بحيث يمكن عرض البيانات بشكل طبيعي.
سيتم أيضًا استدعاء التعبئة عند تحميل الصفحة لأول مرة.
يمكنك أن ترى أن صفحتنا تحتاج أيضًا إلى إعادة تحميل البيانات الجديدة بعد أن يحدد المستخدم علامات أو فئات أخرى. قد تفكر في الاستماع إلى حدث النقر الخاص بـ <simple-radio/>
ثم إخطار استدعاء <pagination/>
بطريقة ما. طريقة ملء تحديثات البيانات؟
لا حاجة! ! لدينا طريقة أبسط لتنفيذ هذه الوظيفة
< rendering
...
:unique =" area + type + order "
/>
unique
سيتم تمريره في النهاية إلى<pagination/>
order
type
area
كلها مرتبطة بثلاثة<simple-radio/>
مختلفة من خلالv-model
أحتاج فقط إلى إضافة خاصية unique
إلى مكون <rendering/>
وتمرير قيمة تُستخدم للرد على تحديثات البيانات، عندما يتم تمرير القيمة إلى تغييرات unique
، سيكون هذا مفيدًا جدًا مواجهة في هذا السيناريو، على سبيل المثال، عند تغيير معرف قائمة التشغيل، تتم إعادة تحميل بيانات قائمة التشغيل الجديدة. في هذا الوقت، نحتاج فقط إلى تمرير المعرف إلى طريقة تعبئة unique
وتنفيذها سيتم تحميل البيانات الفردية تلقائيًا.
يمكنك أن ترى أن <Rendering/>
مناسب جدًا للاستخدام في هذه الصفحة. عند كتابة هذه الصفحة، يمكننا التركيز فقط على محتوى CommonVideoMatrices
دون التفكير في طريقة الحصول على البيانات ومنطقها سيتم عرض تأثير التحميل... المتحرك، ويتم إكماله أيضًا بواسطة <Rendering/>
، ولكن تم تبسيط هذا الجزء في مقتطف الكود الموضح هنا.
في الواقع، هناك شيء آخر يسمى
adapter
يستخدم لحل مشكلة الواجهة الخلفية التي تعيد نفس النوع من البيانات في أماكن مختلفة ولكن بهياكل بيانات مختلفة، لكنني لن أعرضه هنا.
أعتقد أن هذا مشروع للمبتدئين أنه بعد قراءة هذا الجزء، يمكن أن يكون لديك فهم أوضح لجزء من الكود المصدري لهذا المشروع