cari
Rumahhujung hadapan webtutorial cssCara membina aplikasi mudah alih penuh dengan Flutter, Fauna, dan Graphql

Cara membina aplikasi mudah alih penuh dengan Flutter, Fauna, dan Graphql

Flutter adalah rangka kerja UI Google untuk mewujudkan aplikasi mudah alih yang fleksibel dan ekspresif. Ia adalah salah satu rangka kerja yang paling pesat untuk pembangunan aplikasi mudah alih. Fauna, sebaliknya, adalah pangkalan data pelayan tanpa urus niaga, pemaju yang menyokong GraphQL asli. Flutter Fauna adalah perlawanan sempurna yang dibuat oleh syurga. Sekiranya anda ingin membina dan melepaskan aplikasi lengkap yang kaya dengan ciri-ciri dalam masa rekod, Flutter dan Fauna adalah alat yang betul. Dalam artikel ini, kami akan membimbing anda melalui pembinaan aplikasi flutter pertama anda menggunakan backends Fauna dan GraphQL.

Anda boleh mencari kod penuh untuk artikel ini di GitHub.

Objektif pembelajaran

Selepas membaca artikel ini, anda harus tahu bagaimana untuk:

  1. Sediakan contoh fauna,
  2. Tulis corak graphql untuk fauna,
  3. Sediakan klien GraphQL dalam aplikasi Flutter, dan
  4. Lakukan pertanyaan dan mutasi pada backend GraphQL Fauna.

Fauna vs AWS Amplify vs. Firebase : Apakah masalah yang diselesaikan oleh Fauna? Bagaimana ia berbeza dengan penyelesaian tanpa pelayan lain? Jika anda tidak biasa dengan Fauna dan ingin mengetahui lebih lanjut mengenai perbandingan Fauna dengan penyelesaian lain, saya cadangkan anda membaca artikel ini.

Apa yang kita bina?

Kami akan membina aplikasi mudah alih mudah yang membolehkan pengguna menambah, memadam dan mengemas kini filem kegemaran mereka dan siri TV.

Sediakan Fauna

Pergi ke fauna.com dan buat akaun baru. Selepas log masuk, anda sepatutnya dapat membuat pangkalan data baru.

Namakan pangkalan data anda. Saya menamakan saya flutter_demo. Seterusnya, kita boleh memilih kumpulan rantau. Untuk demo ini, kami akan memilih Klasik. Fauna adalah pangkalan data tanpa pelayan di seluruh dunia. Ia adalah satu-satunya pangkalan data yang menyokong akses membaca dan menulis latensi rendah dari mana-mana sahaja. Fikirkannya sebagai CDN (rangkaian pengedaran kandungan), tetapi ia adalah untuk pangkalan data anda. Untuk mengetahui lebih lanjut mengenai kumpulan rantau ini, ikuti panduan ini.

Menjana kunci pentadbir

Sebaik sahaja pangkalan data dibuat, pergi ke tab Keselamatan. Klik butang kunci baru dan buat kekunci baru untuk pangkalan data anda. Sila simpan kunci ini dengan betul kerana kami memerlukannya untuk operasi GraphQL.

Kami akan membuat kunci pentadbir untuk pangkalan data kami. Kunci dengan peranan pentadbir digunakan untuk menguruskan pangkalan data yang berkaitan, termasuk penyedia akses pangkalan data, subdatabase, dokumen, fungsi, indeks, kunci, token, dan peranan yang ditentukan oleh pengguna. Anda boleh mengetahui lebih lanjut mengenai pelbagai kunci keselamatan Fauna dan peranan akses dalam pautan di bawah.

Kami akan membina aplikasi mudah yang membolehkan pengguna menambah, mengemas kini dan memadam watak TV kegemaran mereka.

Buat projek Flutter baru

Mari buat projek Flutter baru dengan menjalankan arahan berikut.

 <code>flutter create my_app</code>

Dalam direktori projek, kami akan membuat fail baru bernama Graphql/schema.graphql.

Dalam fail skema, kami akan menentukan struktur koleksi. Koleksi di fauna adalah serupa dengan jadual dalam SQL. Kami hanya memerlukan satu set sekarang. Kami namakan wataknya.

 <code>### schema.graphql type Character { name: String! description: String! picture: String } type Query { listAllCharacters: [Character] }</code>

Seperti yang ditunjukkan di atas, kami menentukan jenis yang dipanggil watak yang mempunyai pelbagai sifat (iaitu, nama, keterangan, gambar, dll.). Hartanah boleh dianggap sebagai lajur pangkalan data SQL atau pasangan nilai utama pangkalan data NoSQL. Kami juga menentukan pertanyaan. Pertanyaan ini mengembalikan senarai peranan.

Sekarang mari kita kembali ke papan pemuka Fauna. Klik GraphQL dan klik Mod Import untuk memuat naik mod kami ke Fauna.

Selepas import selesai, kami akan melihat Fauna menghasilkan pertanyaan dan mutasi GraphQL.

Tidak suka generasi graphql automatik? Ingin mempunyai kawalan yang lebih baik terhadap logik perniagaan anda? Dalam kes ini, Fauna membolehkan anda menentukan parser GraphQL tersuai. Untuk mengetahui lebih lanjut, klik pautan ini.

Menyediakan pelanggan Graphql dalam Aplikasi Flutter

Mari buka fail pubspec.yaml dan tambahkan kebergantungan yang diperlukan.

 <code>... dependencies: graphql_flutter: ^4.0.0-beta hive: ^1.3.0 flutter: sdk: flutter ...</code>

Kami telah menambah dua kebergantungan di sini. Graphql_flutter adalah Perpustakaan Pelanggan Graphql Flutter. Ia mengintegrasikan semua ciri moden klien GraphQL ke dalam satu pakej yang mudah digunakan. Kami juga menambah pakej sarang sebagai kebergantungan kami. HIVE adalah pangkalan data nilai utama yang ditulis dalam Pure Dart untuk penyimpanan tempatan. Kami menggunakan sarang untuk cache pertanyaan graphql kami.

Seterusnya, kami akan membuat fail baru lib/client_provider.dart. Kami akan membuat kelas penyedia dalam fail yang akan mengandungi konfigurasi Fauna kami.

Untuk menyambung ke API GraphQL Fauna, kita perlu membuat GraphQLClient terlebih dahulu. GraphqlClient memerlukan cache dan pautan untuk dimulakan. Mari lihat kod di bawah.

 <code>// lib/client_provider.dart import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:flutter/material.dart'; ValueNotifier<graphqlclient> clientFor({ @required String uri, String subscriptionUri, }) { final HttpLink httpLink = HttpLink( uri, ); final AuthLink authLink = AuthLink( getToken: () async => 'Bearer fnAEPAjy8QACRJssawcwuywad2DbB6ssrsgZ2-2', ); Link link = authLink.concat(httpLink); return ValueNotifier<graphqlclient> ( GraphQLClient( cache: GraphQLCache(store: HiveStore()), link: link, ), ); }</graphqlclient></graphqlclient></code>

Dalam kod di atas, kami mencipta Valuenotifier untuk membungkus GraphqlClient. Perhatikan bahawa kami mengkonfigurasi authLink pada baris 13-15 (diserlahkan). Pada baris 14, kami menambah kunci pentadbir dari Fauna sebagai sebahagian daripada token. Di sini, saya mengikat kunci admin. Walau bagaimanapun, dalam aplikasi pengeluaran, kita mesti mengelakkan kekunci keselamatan fauna.

Terdapat beberapa cara untuk menyimpan kekunci dalam aplikasi berkilauan. Sila periksa blog ini untuk rujukan.

Kami mahu dapat memanggil pertanyaan dan mutasi dari mana -mana widget dalam aplikasi. Untuk melakukan ini, kita perlu membungkus widget kita menggunakan widget GraphQLProvider.

 <code>// lib/client_provider.dart .... /// 使用`graphql_flutter`客户端包装根应用程序。 /// 我们使用缓存进行所有状态管理。 class ClientProvider extends StatelessWidget { ClientProvider({ @required this.child, @required String uri, }) : client = clientFor( uri: uri, ); final Widget child; final ValueNotifier<graphqlclient> client; @override Widget build(BuildContext context) { return GraphQLProvider( client: client, child: child, ); } }</graphqlclient></code>

Seterusnya, kami pergi ke fail main.dart dan bungkus widget utama kami dengan widget ClientProvider. Mari lihat kod di bawah.

 <code>// lib/main.dart ... void main() async { await initHiveForFlutter(); runApp(MyApp()); } final graphqlEndpoint = 'https://graphql.fauna.com/graphql'; class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ClientProvider( uri: graphqlEndpoint, child: MaterialApp( title: 'My Character App', debugShowCheckedModeBanner: false, initialRoute: '/', routes: { '/': (_) => AllCharacters(), '/new': (_) => NewCharacter(), } ), ); } }</code>

Pada ketika ini, semua widget hiliran kami akan dapat menjalankan pertanyaan dan fungsi mutasi dan boleh berinteraksi dengan API GraphQL.

Halaman permohonan

Permohonan demo mestilah mudah dan mudah difahami. Mari kita teruskan dan buat widget senarai mudah yang akan memaparkan senarai semua peranan. Mari buat fail lib/skrin/list characters.dart baru. Dalam fail ini, kami akan menulis widget baru yang dipanggil AllCharacters.

 <code>// lib/screens/character-list.dart.dart class AllCharacters extends StatelessWidget { const AllCharacters({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: CustomScrollView( slivers: [ SliverAppBar( pinned: true, snap: false, floating: true, expandedHeight: 160.0, title: Text( 'Characters', style: TextStyle( fontWeight: FontWeight.w400, fontSize: 36, ), ), actions:<widget> [ IconButton( padding: EdgeInsets.all(5), icon: const Icon(Icons.add_circle), tooltip: 'Add new entry', onPressed: () { Navigator.pushNamed(context, '/new'); }, ), ], ), SliverList( delegate: SliverChildListDelegate([ Column( children: [ for (var i = 0; i _CharacterTileeState(); } class _CharacterTileState extends State<charactertile> { @override Widget build(BuildContext context) { return Container( child: Text("Character Tile"), ); } }</charactertile></widget></code>

Seperti yang ditunjukkan dalam kod di atas, [baris 37] kami mempunyai gelung yang mengisi senarai dengan beberapa data palsu. Akhirnya, kami akan melakukan pertanyaan GraphQL pada backend Fauna dan dapatkan semua peranan dari pangkalan data. Sebelum kita melakukan ini, mari kita cuba menjalankan permohonan kita. Kami boleh menjalankan aplikasi kami menggunakan arahan berikut

 <code>flutter run</code>

Pada ketika ini, kita harus dapat melihat skrin berikut.

Laksanakan pertanyaan dan mutasi

Sekarang kita mempunyai beberapa widget asas yang kita boleh terus menyambung ke pertanyaan GraphQL. Kami mahu mendapatkan semua peranan dari pangkalan data dan bukannya rentetan keras dan melihatnya dalam widget AllCharacters.

Mari kembali ke taman permainan GraphQL Fauna. Perhatikan bahawa kami boleh menjalankan pertanyaan berikut untuk menyenaraikan semua peranan.

 <code>query ListAllCharacters { listAllCharacters(_size: 100) { data { _id name description picture } after } }</code>

Untuk melakukan pertanyaan ini dari widget kami, kami perlu membuat beberapa perubahan kepadanya.

 <code>import 'package:flutter/material.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:todo_app/screens/Character-tile.dart'; String readCharacters = ";";"; query ListAllCharacters { listAllCharacters(_size: 100) { data { _id name description picture } after } } ";";";; class AllCharacters extends StatelessWidget { const AllCharacters({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: CustomScrollView( slivers: [ SliverAppBar( pinned: true, snap: false, floating: true, expandedHeight: 160.0, title: Text( 'Characters', style: TextStyle( fontWeight: FontWeight.w400, fontSize: 36, ), ), actions:<widget> [ IconButton( padding: EdgeInsets.all(5), icon: const Icon(Icons.add_circle), tooltip: 'Add new entry', onPressed: () { Navigator.pushNamed(context, '/new'); }, ), ], ), SliverList( delegate: SliverChildListDelegate([ Query(options: QueryOptions( document: gql(readCharacters), // 我们要执行的graphql查询pollInterval: Duration(seconds: 120), // 重新获取间隔), builder: (QueryResult result, { VoidCallback refetch, FetchMore fetchMore }) { if (result.isLoading) { return Text('Loading'); } return Column( children: [ for (var item in result.data\['listAllCharacters'\]['data']) CharacterTile(Character: item, refetch: refetch), ], ); }) ]) ) ], ), ); } }</widget></code>

Pertama, kami menentukan rentetan pertanyaan untuk mendapatkan semua peranan dari pangkalan data [baris 5 hingga 17]. Kami membungkus widget senarai menggunakan widget pertanyaan di flutter_graphql.

Jangan ragu untuk melihat dokumentasi rasmi Perpustakaan Flutter_Graphql.

Dalam parameter pilihan pertanyaan, kami menyediakan rentetan pertanyaan GraphQL itu sendiri. Kita boleh lulus sebarang nombor titik terapung untuk parameter pollinterval. Selang Poll Menentukan berapa lama kita mahu memulihkan data dari backend. Widget juga mempunyai fungsi pembina standard. Kami boleh menggunakan fungsi pembina untuk lulus hasil pertanyaan, dapatkan semula fungsi panggil balik, dan dapatkan lebih banyak fungsi panggil balik ke dalam pokok widget.

Seterusnya, saya akan mengemas kini widget Watak untuk memaparkan data aksara pada skrin.

 <code>// lib/screens/character-tile.dart ... class CharacterTile extends StatelessWidget { final Character; final VoidCallback refetch; final VoidCallback updateParent; const CharacterTile({ Key key, @required this.Character, @required this.refetch, this.updateParent, }) : super(key: key); @override Widget build(BuildContext context) { return InkWell( onTap: () { }, child: Padding( padding: const EdgeInsets.all(10), child: Row( children: [ Container( height: 90, width: 90, decoration: BoxDecoration( color: Colors.amber, borderRadius: BorderRadius.circular(15), image: DecorationImage( fit: BoxFit.cover, image: NetworkImage(Character['picture']) ) ), ), SizedBox(width: 10), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( Character['name'], style: TextStyle( color: Colors.black87, fontWeight: FontWeight.bold, ), ), SizedBox(height: 5), Text( Character['description'], style: TextStyle( color: Colors.black87, ), maxLines: 2, ), ], ) ) ], ), ), ); } }</code>

Tambah data baru

Kami boleh menambah peranan baru ke pangkalan data kami dengan menjalankan mutasi berikut.

 <code>mutation CreateNewCharacter($data: CharacterInput!) { createCharacter(data: $data) { _id name description picture } }</code>

Untuk menjalankan mutasi ini dari widget kami, kami perlu menggunakan widget mutasi dari perpustakaan Flutter_Graphql. Mari buat widget baru dengan bentuk mudah untuk pengguna berinteraksi dan memasukkan data. Selepas menyerahkan borang, mutasi createcharacter akan dipanggil.

 <code>// lib/screens/new.dart ... String addCharacter = ";";"; mutation CreateNewCharacter(\$data: CharacterInput!) { createCharacter(data: \$data) { _id name description picture } } ";";";; class NewCharacter extends StatelessWidget { const NewCharacter({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Add New Character'), ), body: AddCharacterForm() ); } } class AddCharacterForm extends StatefulWidget { AddCharacterForm({Key key}) : super(key: key); @override _AddCharacterFormState createState() => _AddCharacterFormState(); } class _AddCharacterFormState extends State<addcharacterform> { String name; String description; String imgUrl; @override Widget build(BuildContext context) { return Form( child: Padding( padding: EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextField( decoration: const InputDecoration( icon: Icon(Icons.person), labelText: 'Name *', ), onChanged: (text) { name = text; }, ), TextField( decoration: const InputDecoration( icon: Icon(Icons.post_add), labelText: 'Description', ), minLines: 4, maxLines: 4, onChanged: (text) { description = text; }, ), TextField( decoration: const InputDecoration( icon: Icon(Icons.image), labelText: 'Image Url', ), onChanged: (text) { imgUrl = text; }, ), SizedBox(height: 20), Mutation( options: MutationOptions( document: gql(addCharacter), onCompleted: (dynamic resultData) { print(resultData); name = ''; description = ''; imgUrl = ''; Navigator.of(context).push( MaterialPageRoute(builder: (context) => AllCharacters()) ); }, ), builder: ( RunMutation runMutation, QueryResult result, ) { return Center( child: ElevatedButton( child: const Text('Submit'), onPressed: () { runMutation({ 'data': { ";picture";: imgUrl, ";name";: name, ";description";: description, } }); }, ), ); } ) ], ), ), ); } }</addcharacterform></code>

Seperti yang dapat dilihat dari kod di atas, widget mutasi berfungsi dengan sangat sama dengan widget pertanyaan. Di samping itu, widget mutasi memberikan kita fungsi oncomplete. Fungsi ini mengembalikan hasil kemas kini dalam pangkalan data selepas mutasi selesai.

Padam data

Kita boleh memadam peranan dari pangkalan data dengan menjalankan mutasi DeleteCharacter. Kita boleh menambah mutan ini ke watak kita dan mencetuskannya apabila butang ditekan.

 <code>// lib/screens/character-tile.dart ... String deleteCharacter = ";";"; mutation DeleteCharacter(\$id: ID!) { deleteCharacter(id: \$id) { _id name } } ";";";; class CharacterTile extends StatelessWidget { final Character; final VoidCallback refetch; final VoidCallback updateParent; const CharacterTile({ Key key, @required this.Character, @required this.refetch, this.updateParent, }) : super(key: key); @override Widget build(BuildContext context) { return InkWell( onTap: () { showModalBottomSheet( context: context, builder: (BuildContext context) { print(Character['picture']); return Mutation( options: MutationOptions( document: gql(deleteCharacter), onCompleted: (dynamic resultData) { print(resultData); this.refetch(); }, ), builder: ( RunMutation runMutation, QueryResult result, ) { return Container( height: 400, padding: EdgeInsets.all(30), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children:<widget> [ Text(Character['description']), ElevatedButton( child: Text('Delete Character'), onPressed: () { runMutation({ 'id': Character['_id'], }); Navigator.pop(context); }, ), ], ), ), ); } ); } ); }, child: Padding( padding: const EdgeInsets.all(10), child: Row( children: [ Container( height: 90, width: 90, decoration: BoxDecoration( color: Colors.amber, borderRadius: BorderRadius.circular(15), image: DecorationImage( fit: BoxFit.cover, image: NetworkImage(Character['picture']) ) ), ), SizedBox(width: 10), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( Character['name'], style: TextStyle( color: Colors.black87, fontWeight: FontWeight.bold, ), ), SizedBox(height: 5), Text( Character['description'], style: TextStyle( color: Colors.black87, ), maxLines: 2, ), ], ) ) ], ), ), ); } }</widget></code>

Edit data

Data pengeditan adalah sama seperti menambah dan memadam. Ia hanya mutasi lain dalam API GraphQL. Kami boleh membuat widget bentuk role edit yang serupa dengan widget bentuk peranan baru. Satu -satunya perbezaan ialah penyuntingan borang akan menjalankan mutasi updatecharacter. Untuk mengedit, saya mencipta widget baru lib/skrin/edit.dart. Berikut adalah kod untuk widget ini.

 <code>// lib/screens/edit.dart String editCharacter = """ mutation EditCharacter(\$name: String!, \$id: ID!, \$description: String!, \$picture: String!) { updateCharacter(data: { name: \$name description: \$description picture: \$picture }, id: \$id) { _id name description picture } } """; class EditCharacter extends StatelessWidget { final Character; const EditCharacter({Key key, this.Character}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Edit Character'), ), body: EditFormBody(Character: this.Character), ); } } class EditFormBody extends StatefulWidget { final Character; EditFormBody({Key key, this.Character}) : super(key: key); @override _EditFormBodyState createState() => _EditFormBodyState(); } class _EditFormBodyState extends State<editformbody> { String name; String description; String picture; @override Widget build(BuildContext context) { return Container( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( initialValue: widget.Character['name'], decoration: const InputDecoration( icon: Icon(Icons.person), labelText: 'Name *', ), onChanged: (text) { name = text; } ), TextFormField( initialValue: widget.Character['description'], decoration: const InputDecoration( icon: Icon(Icons.person), labelText: 'Description', ), minLines: 4, maxLines: 4, onChanged: (text) { description = text; } ), TextFormField( initialValue: widget.Character['picture'], decoration: const InputDecoration( icon: Icon(Icons.image), labelText: 'Image Url', ), onChanged: (text) { picture = text; }, ), SizedBox(height: 20), Mutation( options: MutationOptions( document: gql(editCharacter), onCompleted: (dynamic resultData) { print(resultData); Navigator.of(context).push( MaterialPageRoute(builder: (context) => AllCharacters()) ); }, ), builder: ( RunMutation runMutation, QueryResult result, ) { print(result); return Center( child: ElevatedButton( child: const Text('Submit'), onPressed: () { runMutation({ 'id': widget.Character['_id'], 'name': name != null ? name : widget.Character['name'], 'description': description != null ? description : widget.Character['description'], 'picture': picture != null ? picture : widget.Character['picture'], }); }, ), ); } ), ] ) ), ); } }</editformbody></code>

Anda boleh melihat kod penuh artikel ini seperti berikut.

Ada soalan mengenai fauna atau berkibar? Anda boleh menghubungi saya di Twitter @Haqueshadid

Github ### Langkah seterusnya

Tujuan utama artikel ini adalah untuk membuat anda bermula dengan Flutter dan Fauna. Kami hanya menyentuh permukaan di sini. Ekosistem Fauna menyediakan aplikasi mudah alih anda dengan backend yang lengkap, automatik, pemaju yang lengkap sebagai perkhidmatan. Sekiranya matlamat anda adalah untuk melepaskan aplikasi mudah alih rentas platform yang boleh digunakan untuk pengeluaran dalam masa rekod, cuba Fauna dan Flutter .

Saya sangat mengesyorkan anda menyemak laman web dokumentasi rasmi Fauna. Jika anda berminat untuk mempelajari lebih lanjut mengenai klien GraphQL Dart/Flutter, lihat repositori GitHub rasmi Graphql_flutter.

Saya mengucapkan selamat datang kepada anda, sampai jumpa lagi.

Atas ialah kandungan terperinci Cara membina aplikasi mudah alih penuh dengan Flutter, Fauna, dan Graphql. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Bekerja dengan Caching GraphqlBekerja dengan Caching GraphqlMar 19, 2025 am 09:36 AM

Sekiranya anda baru -baru ini mula bekerja dengan GraphQL, atau mengkaji semula kebaikan dan keburukannya, anda tidak akan ragu -ragu mendengar perkara seperti "Graphql tidak menyokong caching" atau

CSS Scrollbars Custom Custom: PameranCSS Scrollbars Custom Custom: PameranMar 10, 2025 am 11:37 AM

Dalam artikel ini kita akan menyelam ke dunia scrollbars. Saya tahu, ia tidak terdengar terlalu glamor, tetapi percayalah, halaman yang direka dengan baik

Menjadikan Peralihan Svelte Khas pertama andaMenjadikan Peralihan Svelte Khas pertama andaMar 15, 2025 am 11:08 AM

API Peralihan Svelte menyediakan cara untuk menghidupkan komponen apabila mereka memasuki atau meninggalkan dokumen, termasuk peralihan svelte adat.

Tunjukkan, jangan beritahuTunjukkan, jangan beritahuMar 16, 2025 am 11:49 AM

Berapa banyak masa yang anda habiskan untuk merancang persembahan kandungan untuk laman web anda? Semasa anda menulis catatan blog baru atau membuat halaman baru, adakah anda memikirkan

Membina aplikasi Ethereum menggunakan redwood.js dan faunaMembina aplikasi Ethereum menggunakan redwood.js dan faunaMar 28, 2025 am 09:18 AM

Dengan pendakian harga bitcoin baru -baru ini lebih dari 20k $ USD, dan baru -baru ini melanggar 30k, saya fikir ia patut mengambil menyelam yang mendalam kembali ke dalam mewujudkan Ethereum

Apa yang ada perintah npm?Apa yang ada perintah npm?Mar 15, 2025 am 11:36 AM

Perintah NPM menjalankan pelbagai tugas untuk anda, sama ada sebagai satu-satunya atau proses berjalan terus untuk perkara seperti memulakan pelayan atau menyusun kod.

Mari kita gunakan (x, x, x, x) untuk bercakap mengenai kekhususanMari kita gunakan (x, x, x, x) untuk bercakap mengenai kekhususanMar 24, 2025 am 10:37 AM

Saya hanya berbual dengan Eric Meyer pada hari yang lain dan saya teringat cerita Eric Meyer dari tahun -tahun pembentukan saya. Saya menulis catatan blog mengenai kekhususan CSS, dan

Bagaimana anda menggunakan CSS untuk membuat kesan teks, seperti bayang -bayang teks dan kecerunan?Bagaimana anda menggunakan CSS untuk membuat kesan teks, seperti bayang -bayang teks dan kecerunan?Mar 14, 2025 am 11:10 AM

Artikel ini membincangkan menggunakan CSS untuk kesan teks seperti bayang -bayang dan kecerunan, mengoptimumkannya untuk prestasi, dan meningkatkan pengalaman pengguna. Ia juga menyenaraikan sumber untuk pemula. (159 aksara)

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ialah aplikasi web PHP/MySQL yang sangat terdedah. Matlamat utamanya adalah untuk menjadi bantuan bagi profesional keselamatan untuk menguji kemahiran dan alatan mereka dalam persekitaran undang-undang, untuk membantu pembangun web lebih memahami proses mengamankan aplikasi web, dan untuk membantu guru/pelajar mengajar/belajar dalam persekitaran bilik darjah Aplikasi web keselamatan. Matlamat DVWA adalah untuk mempraktikkan beberapa kelemahan web yang paling biasa melalui antara muka yang mudah dan mudah, dengan pelbagai tahap kesukaran. Sila ambil perhatian bahawa perisian ini

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

SublimeText3 versi Inggeris

SublimeText3 versi Inggeris

Disyorkan: Versi Win, menyokong gesaan kod!

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.