В области технологии малых программ существует несколько загадочных явлений: WeChatWXS, АлипайSJS, БайдуFilter.
Многие разработчики не понимают, для чего сделаны колеса этого языкового скрипта, а многие разработчики даже не знают об их существовании.
На самом деле несколько больших и малых программных платформ создали их для решения проблем с производительностью, но я должен пожаловаться, дизайн действительно сложен в использовании, а документация неясна.
uni-appподдержка будетWXS,SJS,FilterСкомпилировано для этих трех небольших программных платформ, а также реализовано в App и H5.WXSанализ. Зачем это делать? Также для производительности.
Напримерuni-uiбиблиотека компонентовswiperactionКомпонент представляет собой кнопку меню, которая вызывает несколько сжатий, когда элемент списка прокручивается влево.Эта плавная анимация рук в руки точно основана на помощиWXSреализован механизм.
Почему WeChat создал WXS?
WXS (WeiXin Script) — это язык сценариев, созданный WeChat. Его официальное заявление гласит: «WXS и JavaScript — разные языки и имеют собственный синтаксис, несовместимый с JavaScript».
Тогда почему WeChat отделился от JavaScript и создал отдельный язык? Это начинается с базовой логики (рабочей среды) апплета WeChat.
Рабочая среда апплета разделена на уровень логики и уровень представления, которые управляются двумя потоками соответственно, среди которых:
- Шаблоны WXML и стили WXSS работают на уровне представления, а интерфейс визуализируется с помощью WebView.
- Код JavaScript работает на логическом уровне, работает в JsCore или v8.
Апплет обеспечивает передачу данных и систему событий между двумя потоками уровня представления и уровня логики. Такая конструкция разделения приносит очевидные преимущества:
- Разделение логики и представления, даже если расчет бизнес-логики очень занят, это не будет блокировать рендеринг и взаимодействие с пользователем на слое представления
Но это также приносит очевидные недостатки:
- Уровень представления (веб-просмотр) не может запускать JS, а уровень логики JS не может напрямую изменять DOM страницы.Система обновления данных и событий может полагаться только на межпотоковую связь, но стоимость межпоточной связи чрезвычайно высока, особенно в сценариях, требующих частого общения
Какие сценарии требуют частого общения? Наиболее типичным примером является случай непрерывного взаимодействия с пользователем, такого как касание, прокрутка и т. д. Возьмем в качестве примера боковое скользящее меню. Предположим, что элемент А скользит по странице, а элемент Б должен следовать за движением. Процесс отклика на скользящую операцию (touchmove) выглядит следующим образом:
- Событие touchmove передается с уровня представления (Webview) на уровень логики и будет ретранслироваться клиентом WeChat (Native) посередине.
- Логический уровень обрабатывает событие touchmove, вычисляет положение для перемещения, а затем передает его на уровень представления через setData, который также будет ретранслироваться клиентом WeChat (Native) посередине.
Ответ touchmove должен пройти два полных цикла обмена данными между уровнем представления, собственным уровнем и логическим уровнем.Обмен данными требует много времени и средств, а взаимодействие с пользователем будет отложено и зависнет.
В дополнение к взаимодействию прокрутки и перетаскивания изменение формата данных в цикле for также приведет к частому взаимодействию между логическим уровнем и уровнем представления.
На самом деле, эта проблема потери связи имеет долгую историю в отрасли. React Native и weex имеют схожие проблемы. Weex предоставляет Bindingx для ее решения.
Но для небольших программ такие задачи решаются проще. Потому что на самом деле веб-просмотр уровня представления имеет среду js, но в прошлом она не была открыта для разработчиков.
Если js на уровне представления напрямую обрабатывает взаимодействия с прокруткой или перетаскиванием, а также напрямую обрабатывает форматы данных, можно избежать многих потерь связи.
Однако для платформы апплета большое количество открытых js, написанных в веб-просмотре, нарушает его первоначальное намерение, например, разработчики будут напрямую управлять dom, что влияет на производительность. Поэтому платформа апплета предлагает новую спецификацию, чтобы ограничить возможности js, которые можно запускать в веб-просмотре. Это источник wxs, sjs и filter.
По сути, wxs, sjs и filter — это js с ограниченным доступом, которые запускаются в веб-представлении уровня представления. На самом деле это не изобретает новый язык.
Функции WXS и применимые сценарии
WXS имеет следующие характеристики:
- WXS — это JS, который может работать на уровне представления (веб-просмотр).
- WXS не может напрямую изменять бизнес-данные, он может только установить текущий компонент.
classа такжеstyleили отформатируйте данные. Чтобы изменить данные логического слоя, вам нужно передать параметры логическому слою через callMethod - WXS — это ограниченный JavaScript, который может выполнять некоторые простые логические операции.
- WXS может прослушивать сенсорные события и обрабатывать взаимодействия с прокруткой и перетаскиванием.
Следовательно, можно сделать вывод, что применимые сценарии WXS в основном включают:
- Сценарии, которые требуют частого взаимодействия с пользователем и требуют только изменения стилей компонентов (например, позиций макета) без изменения содержимого данных, таких как боковые меню, индексные списки, градиенты прокрутки и т. д.
- Форматирование данных, например текст, формат даты или интернационализация. Фреймворк Vue можно смоделировать через WXSфильтр, ниже приведен пример использования заглавной буквы через wxs:
<wxs module="m1">
//首字母大写
var capitalize = function(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
module.exports = {
capitalize: capitalize
}
</wxs>
<view class="content">
<view class="text-area">
<!-- title 为当前页面 data 中定义的初始数据 -->
<text class="title">{{m1.capitalize(title)}}</text>
</view>
</view>
Как uni-app поддерживает WXS
uni-appследитьСпецификация однофайлового компонента Vue (SFC), компоненты/стили/скрипты написаны на.vueфайл, но апплет WeChat разделен несколькими файлами (wxml/wxss/js/json), поэтому основная работа на стороне WeChat заключается в расширенииvue-template-compiler, разборtemplate/style/scriptузел, и правильно сгенерированный к соответствующемуwxml/wxss/jsВ файле конкретная работа по компиляции выглядит следующим образом:
Советы-1: О<wxs>Этикетка изменена на<script lang="wxs">инструкция:
потому что.vueв файле<wxs>В основных инструментах разработки интерфейса (vscode/HBuilderX и т. д.) синтаксические подсказки, подсветка кода и форматирование не могут быть реализованы в тегах и встроенном коде WXS.uni-appБуду<wxs module="m1">преобразован в<script module="m1" lang="wxs">, который удобно реализует синтаксические подсказки, подсветку кода и т. д., как показано ниже для vscode/HBuilderX для<wxs>Сравнение подсветки кода до и после рефакторинга тегов, очевидно, переработано как<script lang="wxs">После этого опыт разработки лучше:
Советы 2: Учитывая спецификацию пользовательских тегов Vue, мы рекомендуем поместить<wxs>(<script lang="wxs">)а такжеtemplateуровень письма
Конкретный анализ и работа по расширению компилятора здесь не подробно описаны, а только даныwxsСгенерированный пример кода дает вам интуитивное понимание:
createFilterTag (filterTag, {
content,
attrs
}) {
content = content.trim()
if (content) { //<wxs>标签内直接编写 wxs 代码
return `<${filterTag} module="${attrs.module}">
${content}
</${filterTag}>`
} else if (attrs.src) { //外联 .wxs 文件
return `<${filterTag} src="${attrs.src}" module="${attrs.module}"></${filterTag}>`
}
}
При условии правильной компиляции апплет WeChat будет правильно проанализирован и выполнен во время работы.WXSСкрипт, рамкиruntimeВмешательства не требуется.
Пример реализации улучшения производительности на основе WXS
Контент, показанный на гифке ниже, является реализацией WXS.swipeactionПример компонента, когда элемент списка смахивается влево, выдвигаются несколько связанных кнопок меню, что естественно и плавно с анимацией руки и анимацией отскока.
Вот краткий обзор основных идей реализации:
- Ссылка на файл wxs в vue и привязка события касания
<template>
<view class="uni-swipe_content">
<!-- 可滑动的菜单项容器,绑定touch事件 -->
<view :data-position="pos" class="move-hock"
@touchstart="swipe.touchstart" @touchmove="swipe.touchmove" @touchend="swipe.touchend" @change="change">
<view class="uni-swipe_box">
<slot />
</view>
<view class="uni-swipe_button-group move-hock">
<!-- 滑动后,右侧挤压式的联动菜单按钮-->
<view v-for="(item,index) in options" :data-button="btn" :key="index" class="button-hock">
{{ item.text }}
</view>
</view>
</view>
</view>
</template>
<script module="swipe" lang="wxs" src="./index.wxs"></script>
- В файле wxs обработайте логику сенсорного события и переместите позицию элемента через translateX.
function touchstart(e, ins) {
//记录开始位置及动画状态
var pageX = e.touches[0].pageX;
....
}
function touchmove(e, ownerInstance) {
var instance = e.instance;
var pageX = e.touches[0].pageX;//获取当前移动位置
//计算偏移位置
var x = Math.max(-instance.getState().position[1].width, Math.min((value), 0));
//设置左侧元素移动位置
instance.setStyle({transform: 'translateX(' + x + 'px)'})
//循环右侧挤压式联动菜单
var btnIns = ownerInstance.selectAllComponents('.button-hock');
for (var i = 0; i < btnIns.length; i++) {
...
//设置每个联动菜单的移动位置
btnIns[i].setStyle({transform: 'translateX(' + (arr[i - 1] + value * (arr[i - 1] / position[1].width)) + 'px)'})
...
}
}
function touchend(e, ownerInstance) {
var instance = e.instance;
var state = instance.getState()
//根据当前移动位置,实现菜单项的自动展开或回弹
move(state.left, -40, instance, ownerInstance)
}
Полная ссылка на источник для этого примераgithub
В этом коде реакция на жесты и перемещение меню осуществляется непосредственно в слое представления. Без традиционного метода записи wxs реализовать эту функцию будет очень сложно.
- Во-первых, уровень представления получает событие касания, а затем передает его логическому уровню;
- js логического слоя реагирует на событие касания и оценивает расстояние перемещения;
- Затем уведомите слой представления об обновлении положения элемента интерфейса.
Во время непрерывного процесса перетаскивания слой представления и слой логики продолжают взаимодействовать и обмениваться данными, что не может быть гладким.
Хотя мы понимаем принцип работы wxs, честно говоря, wxs довольно сложен в использовании, и до сих пор большинство разработчиков до сих пор его не используют. Более целесообразно инкапсулировать его некоторыми авторами фреймворка.uni-appкоторый предоставилuni-uiБиблиотека компонентов делает это, разработчикам нужно только обратиться к стандартным компонентам vue.uni uiизswiperactionкомпонент, вы можете получить плавное скользящее меню.
Совместимость с большим количеством платформ
uni-appСторона приложения также представляет собой небольшой программный движок.Чтобы добиться плавного перетаскивания руками на стороне приложения, он также реализует и совместим с wxs.
На самом деле, платформа H5 не имеет проблемы потери связи между логическим уровнем и уровнем представления, но ради совместимости платформы,uni-appМеханизм wxs также реализован на стороне H5.
Напишите такой код wxs, вuni-appОн может работать одновременно на стороне приложения, на стороне H5 и на стороне апплета WeChat.
Апплет BaiduФильтри апплет AlipaySJS, зрелость все еще относительно низкая, и в настоящее время он может обрабатывать только базовую фильтрацию формата данных и не может реагировать на интерактивные события, такие как прикосновение.
Что касается Toutiao и апплета QQ, механизм, подобный WXS, пока не поддерживается.
Мы с нетерпением ждем других небольших программных платформ, чтобы как можно скорее завершить эту важную функцию, чтобы улучшить опыт.
uni-appВ настоящее время он также поддерживает независимое написание фильтра фильтра апплета Baidu и SJS апплета Alipay.Эти два скрипта не могут пересекать несколько терминалов и поддерживают только свои собственные платформы. Если разработчикам нужно использовать, они могут написать отдельноwxs/filter/sjsскрипт, затем по очереди черезscriptЦитировать,uni-appКомпилятор будет компилироваться и выпускаться отдельно в соответствии с целевой платформой.Ниже приведен пример кода:Пример кода должен быть условно скомпилирован
<!-- App/H5/微信小程序平台调用wxs脚本 -->
<script module="utils" lang="wxs" src="./utils.wxs"></script>
<!-- 百度小程序平台调用filter.js脚本 -->
<script module="utils" lang="filter" src="./utils.filter.js"></script>
<!-- 支付宝小程序平台调用sjs脚本 -->
<script module="utils" lang="sjs" src="./utils.sjs"></script>
следовать за
Многие люди могут не осознавать, что блокировка связи решается с помощью js, работающего на уровне представления. Я надеюсь, что эта статья поможет вам разгадать загадку и разгадать тайну WXS.
На самом деле, есть еще много возможностей для оптимизации производительности апплета. Команда DCloud обучалась в этой области в течение 6 лет и знает о преимуществах архитектуры технологии малых программ и текущих проблемах. Мы продолжим делиться этими проблемами и соответствующими решениями, чтобы внести свой вклад в развитие индустрии мини-программ.
эта статья посвященаuni-uiизswiperactionкомпоненты, код с открытым исходным кодом вGitHub.com/Открыто много раз/UN…,uni-appКод фреймворка является открытым исходным кодом вGitHub.com/Открыто много раз/UN…, добро пожаловать, чтобы пометить или отправить pr.