Вы когда-нибудь испытывали страх оставить позади свои любимые библиотеки JS, стоит ли включать Dart в свой стек разработчика? Что ж, не бойтесь больше, потому что команда Dart предоставила средства для включения ваших любимых библиотек JavaScript!
Решение представлено в виде пакета js, который предоставляет прокси для вызова методов JavaScript API. В этой статье мы рассмотрим несколько примеров с объектом window
и реальный пример с jQuery.
Вот исходный код, содержащий решение.
→ Продолжить чтение в моем блоге
Предварительное условие
Прежде чем мы начнем, давайте воспользуемся рабочим сцены, чтобы создать наш веб-проект:
mkdir new_project && cd new_project stagehand web-simple
Добавьте следующее в pubspec.yaml
под зависимостями:
dependencies: js: ^0.6.0
И запустите pub get
. Также убедитесь, что у вас установлено webdev (pub global activate webdev
)
Теперь мы готовы перейти к примерам!
Пример с объектом window
При установке пакета js аннотация @JS()
используется как средство доступа к API JavaScript на объекте хоста window
.
Вот фрагмент, который можно использовать в web/main.dart
для вызова window.console.log()
:
@JS() // sets the context, in this case being `window` library main; // required library declaration import 'package:js/js.dart'; // Pull in our dependency @JS('console.log') // annotates `log` function to call `console.log` external void log(dynamic str); void main() { log('Hello world!'); // invokes console.log() in JavaScript land }
Запустите webdev serve
и посетите URL-адрес localhost, чтобы увидеть результат. Чтобы увидеть обновления, просто сохраните файл и перезагрузите страницу.
Аннотированный файл должен начинаться с объявления библиотеки, которая также имеет аннотацию @JS()
, которую мы видим в строках 1–2. Поскольку первая аннотация не имеет аргументов, она устанавливает контекст других аннотаций относительно глобального объекта window
. Таким образом, переход к этой строке @JS('console.log')
описывает переход от window
к свойству console
, имеющему метод log
.
Вот еще один пример установки контекста на window.console
:
@JS('console') // Our `console` namespace library main; // library name can be whatever you want import 'package:js/js.dart'; @JS('log') // Setting the proxy to the `console.log` method external void log(dynamic str); void main() { log('Hello world!'); }
Поскольку файл начинается с пространства имен console
, следующая аннотация для метода log
исключает префикс console
. Ключевое слово external
для метода log
используется для обозначения этого метода вне Dart, иначе ожидается тело функции. Кроме того, поскольку наша функция названа с тем же именем, что и метод на console
, мы можем полностью удалить указанную выше аннотацию.
// @JS('log') // remove external void log(dynamic str);
Обратите внимание: вам не нужен этот пакет взаимодействия, если вам нужен только доступ к встроенным свойствам на window
. Для этого используйте dart:html
библиотеку Дарта. Приведенный выше фрагмент предназначен только для иллюстрации, поэтому пакет js
может использоваться при использовании внешних библиотек.
Реальный пример с jQuery
Чтобы использовать jQuery, давайте импортируем его в web/index.html
перед тегом скрипта, запрашивающим main.dart.js
:
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Теперь создайте файл с именем web/jquery.dart
, содержащий приведенный ниже фрагмент:
@JS() library jquery; import 'package:js/js.dart'; // new jQuery invokes JavaScript `new jQuery()` @JS() class jQuery { external factory jQuery(String selector); external int get length; // we get this from jQuery instance }
Давайте проведем рефакторинг main.dart
, чтобы проверить это:
import './jquery.dart'; void main() { print(jQuery('#output')); // [object Object] print(jQuery('#output').length); // 1 }
Давайте сделаем что-нибудь более интригующее, используя методы css()
и animate()
:
@JS() class jQuery { external factory jQuery(String selector); external int get length; external jQuery css(Map options); external jQuery animate(Map options); }
Вызов обоих методов вернет экземпляр jQuery так же, как и API на основе JS.
Теперь это не сработает должным образом, поскольку options
параметры ожидают тип Map
. Мы не можем передать объект Dart Map
, потому что он «непрозрачен» в JavaScript. Другими словами, вы получите объект, не содержащий того, что вы ожидаете.
Чтобы это заработало, нам нужно определить конструктор фабрики с ключами, которые нам понадобятся:
@JS() @anonymous // needed along with factory constructor class CssOptions { external factory CssOptions({ backgroundColor, height, position, width }); external String get backgroundColor; external String get position; external num get height; external num get width; }
И измените объявление внешнего метода css()
следующим образом:
external jQuery css(CssOptions options);
Сделаем то же самое для метода animate:
@JS() @anonymous class AnimateOptions { external factory AnimateOptions({ left, top }); external dynamic get left; external dynamic get top; }
И измените объявление внешнего метода animate()
следующим образом:
external jQuery animate(AnimateOptions options);
Теперь мы можем вызывать наши методы в web/main.dart
как таковые:
import './jquery.dart'; void main() { jQuery('#output') .css(CssOptions( backgroundColor: 'green', height: 100, position: 'relative', width: 100)) .animate(AnimateOptions(left: 100, top: 100)); }
И ожидайте результата ниже:
Заключение
Зная, что вы можете оставаться продуктивным в качестве разработчика Dart, сохраняя при этом доступ к экосистеме библиотек JavaScript, все меняется к лучшему, поскольку любая новая библиотека, которая появится, все еще находится в пределах вашей досягаемости.
Это решение работает для любой библиотеки JavaScript, имеющей пространство имен под объектом window
, что охватывает 99% случаев.
Как всегда, я надеюсь, что это было проницательно, и вы узнали что-то новое сегодня. И вот суть полного решения.
дальнейшее чтение
Делиться заботой 🤗
Если вам понравилось читать эту статью, поделитесь ею в различных социальных сетях. Кроме того, проверьте и подписывайтесь на мой канал YouTube (также нажмите значок колокольчика) для видео на Dart.
Подпишитесь на мою электронную рассылку, чтобы загрузить мою бесплатную 35-страничную электронную книгу Начать работу с Dart и получать уведомления о выходе нового содержания.
Поставьте лайк, поделитесь и подписывайтесь на меня 😍, чтобы узнать больше о Dart.