Эта структура представляет собой внутреннюю структуру разработки Tencent, основанную на небольших программах.Идеи дизайна в основном относятся к VUE, и более 80% режима разработки и стиля кодирования близки к VUE.
Преимущество
разработка компонента
Хотя апплет имеет теги для реализации повторного использования компонентов, он ограничен повторным использованием уровня фрагмента шаблона, а бизнес-код и события взаимодействия по-прежнему необходимо обрабатывать на странице. Эффект компонентной слабой связи и повторного использования не может быть достигнут. пример компонента wepy
// index.wpy
<template>
<view>
<panel>
<h1 slot="title"></h1>
</panel>
<counter1 :num="myNum"></counter1>
<counter2 :num.sync="syncNum"></counter2>
<list :item="items"></list>
</view>
</template>
<script>
import wepy from 'wepy';
import List from '../components/list';
import Panel from '../components/panel';
import Counter from '../components/counter';
export default class Index extends wepy.page {
config = {
"navigationBarTitleText": "test"
};
components = {
panel: Panel,
counter1: Counter,
counter2: Counter,
list: List
};
data = {
myNum: 50,
syncNum: 100,
items: [1, 2, 3, 4]
}
}
</script>
Поддержка загрузки внешних пакетов NPM
Недостатки небольшой программы не поддерживаются пакетами NPM, которые не могут напрямую использовать много отличного контента с открытым исходным кодом.Wepy находится в процессе компиляции, рекурсивно обходит Require в коде обхода и копирует соответствующий файл зависимостей из Node_Modules и модифицирует запрашивать как относительный путь, тем самым поддерживая поддержку внешних пакетов NPM
Однофайловый режим, делающий структуру каталогов более четкой
Официальная структура каталогов Мини-программы требует, чтобы в приложении было три файла app.json, app.js, app.wxss, а на странице — четыре файла index.json, index.js, index.wxml, index.wxss. И файлы должны иметь одинаковое имя. Поэтому сравнение каталога разработки до и после использования wepy выглядит следующим образом: Официальная DEMO:
project
├── pages
| ├── index
| | ├── index.json index 页面配置
| | ├── index.js index 页面逻辑
| | ├── index.wxml index 页面结构
| | └── index.wxss index 页面样式表
| └── log
| ├── log.json log 页面配置
| ├── log.wxml log 页面逻辑
| ├── log.js log 页面结构
| └── log.wxss log 页面样式表
├── app.js 小程序逻辑
├── app.json 小程序公共设置
└── app.wxss 小程序公共样式表
Структура каталогов после использования фреймворка wepy:
project
└── src
├── pages
| ├── index.wpy index 页面配置、结构、样式、逻辑
| └── log.wpy log 页面配置、结构、样式、逻辑
└──app.wpy 小程序配置项(全局样式配置、声明钩子等)
как развивать
быстрый старт
- Установить
npm install wepy-cli -g
Инструмент командной строки wepy framework для апплетов - Создать проект
wepy new myproject - Перейдите в каталог проекта
cd myproject - Своевременная компиляция
сборка wepy --watch
Структура каталогов ├── dist Каталог, указанный инструментом разработчика WeChat.
├── node_modules
├── src 代码编写的目录
| ├── components 组件文件夹(非完整页面)
| | ├── com_a.wpy 可复用组件 a
| | └── com_b.wpy 可复用组件 b
| ├── pages 页面文件夹(完整页面)
| | ├── index.wpy 页面 index
| | └── page.wpy 页面 page
| └── app.wpy 小程序配置项(全局样式配置、声明钩子等)
└── package.json package 配置
Основное отличие wepy от VUE
1. Оба поддерживают props,data,computed,components,methods,watch(watcher в wepy), но методы в wepy можно использовать только для привязки событий страницы, остальные пользовательские методы нужно размещать во внешнем слое, а в VUE все методы помещаются в методы
2. Передача реквизита в wepy требует добавления модификатора .sync (аналогичного VUE1.x) для реализации динамического обновления реквизита, и после того, как родительский компонент изменен и передан реквизитам дочернего компонента, this.$apply( ) метод должен быть выполнен для обновления
3. Wepy поддерживает двустороннюю привязку данных, а подкомпоненты могут изменять данные родительского компонента, добавляя значение атрибута twoway:true при определении свойств.
4. VUE2.x рекомендует использовать eventBus для связи компонентов, а в wepy это делается черезemit, $invoke три метода для достижения связи
· 首先事件监听需要写在events属性下:
``` bash
import wepy from 'wepy';
export default class Com extends wepy.component {
components = {};
data = {};
methods = {};
events = {
'some-event': (p1, p2, p3, $event) => {
console.log(`${this.name} receive ${$event.name} from ${$event.source.name}`);
}
};
// Other properties
}
```
· $broadcast:父组件触发所有子组件事件
· $emit:子组件触发父组件事件
· $invoke:子组件触发子组件事件
5. Жизненный цикл VUE включает созданные, смонтированные и т.д., wepy поддерживает только жизненный цикл небольших программ: onLoad, onReady и т.д.
6. Wepy не поддерживает технологии функций VUE, такие как фильтры, поддержка активности, ссылка, переход, глобальные плагины, управление маршрутизацией, рендеринг на стороне сервера и т. д.
Продвижение введение
Описание файла .wpy
Файл .wpy можно разделить на три части, каждая из которых соответствует тегу:
- Сценарную часть, содержимое тега, можно разделить на две части:
Логическая часть , кроме объекта конфига, соответствует нативному .js файлу;
Часть конфигурации , объект конфигурации, соответствует собственному файлу .json. - Структурная часть, часть шаблона, соответствует собственному файлу .wxml.
- Раздел стиля, раздел стиля, соответствует родному файлу .wxss.
Три тега script, template и style в файле .wpy поддерживают атрибуты lang и src.lang определяет процесс компиляции кода, а src определяет, следует ли встраивать код.Если атрибут src существует и является допустимым, встроенный код будет игнорироваться.
Этикетка | язык по умолчанию | значение поддержки языка |
---|---|---|
style | css | css, меньше, sass, стилус |
template | wxml | wxml, xml, pug (оригинальный нефрит) |
script | babel | Бабель, TypeScript |
ссылка на обычный компонент
Когда странице необходимо импортировать компонент или компоненту необходимо импортировать подкомпонент, он должен быть в файле .wpy.
<template>
<!-- 以`<script>`脚本部分中所声明的组件ID为名命名自定义标签,从而在`<template>`模板部分中插入组件 -->
<child></child>
</template>
<script>
import wepy from 'wepy';
//引入组件文件
import Child from '../components/child';
export default class Index extends wepy.component {
//声明组件,分配组件id为child
components = {
child: Child
};
}
</script>
Следует отметить, что компоненты в WePY являются статическими компонентами, которые однозначно идентифицируются идентификатором компонента. Каждый идентификатор соответствует экземпляру компонента. Когда на страницу вводятся два компонента с одинаковым идентификатором, два компонента используют один и тот же , Экземпляр и данные, когда один из данных компонента изменяется, другой также будет меняться. Если вам нужно избежать этой проблемы, вам необходимо назначить несколько идентификаторов компонентов и экземпляров.
Круговой рендеринг компонентов
1.4.6 Новое Когда вам нужно отображать компоненты WePY в цикле (аналогично отображению собственных тегов wxml через цикл wx:for), вы должны использовать вспомогательные теги, определенные WePY.
<template>
<!-- 注意,使用for属性,而不是使用wx:for属性 -->
<repeat for="{{list}}" key="index" index="index" item="item">
<!-- 插入<script>脚本部分所声明的child组件,同时传入item -->
<child :item="item"></child>
</repeat>
</template>
вычисляемые свойства
Вычисляемое свойство — это функция с возвращаемым значением, которое можно использовать непосредственно в качестве связанных данных. Следовательно, подобно свойству данных, на код можно ссылаться по этому имени вычисляемого свойства, а шаблон также можно связать с данными по {{ имя вычисляемого свойства }}. Обратите внимание, что все вычисляемые свойства будут пересчитываться всякий раз, когда какие-либо данные в компоненте изменяются.
data = {
a: 1
}
// 计算属性aPlus,在脚本中可通过this.aPlus来引用,在模板中可通过{{ aPlus }}来插值
computed = {
aPlus () {
return this.a + 1
}
}
наблюдатель
Обновление значения любого свойства значения можно отслеживать с помощью прослушивателя-наблюдателя. Слушатель объявлен в объекте наблюдения, типом является функция, а имя функции имеет то же имя, что и числовое свойство в отслеживаемом объекте данных.Всякий раз, когда отслеживаемое числовое свойство изменяется, функция прослушивателя будет автоматически вызываться и выполняться однажды. Слушатели полезны, когда требуется дополнительная обработка при изменении числового свойства.
data = {
num: 1
}
// 监听器函数名必须跟需要被监听的data对象中的数值属性num同名,
// 其参数中的newValue为数值属性改变后的新值,oldValue为改变前的旧值
watch = {
num (newValue, oldValue) {
console.log(`num value: ${oldValue} -> ${newValue}`)
}
}
// 每当被监听的数值属性num改变一次,对应的同名监听器函数num()就被自动调用执行一次
onLoad () {
setInterval(() => {
this.num++;
this.$apply();
}, 1000)
}
реквизиты передаются по значению
- статическое значение прохода
Статическое значение передачи передает постоянные данные от родительского компонента к дочернему компоненту, поэтому может передаваться только тип String.
В теге компонента раздела шаблона шаблона родительского компонента используйте имя свойства, объявленное в объекте реквизита дочернего компонента, в качестве имени его свойства, чтобы получить значение, переданное родительским компонентом.
<child title="mytitle"></child>
// child.wpy
props = {
title: String
};
onLoad () {
console.log(this.title); // mytitle
}
- Динамическая передача по значению
Динамическая передача по значению означает, что родительский компонент передает содержимое динамических данных дочернему компоненту, а данные родительского и дочернего компонентов полностью независимы и не мешают друг другу. Однако вы можете использовать модификатор .sync для привязки данных родительского компонента к дочернему компоненту, или вы можете установить twoWay: true реквизитов дочернего компонента, чтобы привязать данные дочернего компонента к родительскому компоненту. Затем, если вы используете модификатор .sync и добавляете twoWay: true в реквизиты подкомпонента, вы можете добиться двусторонней привязки данных.
Примечание. Когда значение twoWay в приведенном ниже примере равно true, это означает, что дочерний компонент динамически передает значения родительскому компоненту в одном направлении, а когда значение twoWay равно false (значение по умолчанию, не может быть записано), это означает, что дочерний компонент не передает значения родительскому компоненту. Это несовместимо с Vue, и причина, по которой twoWay все еще используется здесь, заключается в том, чтобы поддерживать максимально возможную согласованность с Vue в именовании идентификаторов.
В теге дочернего компонента, вставленном в раздел шаблона шаблона родительского компонента, используйте атрибут :prop (эквивалентный атрибуту v-bind:prop в Vue) для динамической передачи значений.
// parent.wpy
<child :title="parentTitle" :syncTitle.sync="parentTitle" :twoWayTitle="parentTitle"></child>
data = {
parentTitle: 'p-title'
};
// child.wpy
props = {
// 静态传值
title: String,
// 父向子单向动态传值
syncTitle: {
type: String,
default: 'null'
},
twoWayTitle: {
type: Number,
default: 50,
twoWay: true
}
};
onLoad () {
console.log(this.title); // p-title
console.log(this.syncTitle); // p-title
console.log(this.twoWayTitle); // 50
this.title = 'c-title';
console.log(this.$parent.parentTitle); // p-title.
this.twoWayTitle = 60;
this.$apply();
console.log(this.$parent.parentTitle); // 60. --- twoWay为true时,子组件props中的属性值改变时,会同时改变父组件对应的值
this.$parent.parentTitle = 'p-title-changed';
this.$parent.$apply();
console.log(this.title); // 'p-title';
console.log(this.syncTitle); // 'p-title-changed' --- 有.sync修饰符的props属性值,当在父组件中改变时,会同时改变子组件对应的值。
}
Компонентная коммуникация и взаимодействие
Обработчики событий для мониторинга событий связи и взаимодействия между компонентами должны быть написаны в объекте событий компонентов и страниц.
- Широковещательное событие инициируется родительским компонентом, и все дочерние компоненты получат это широковещательное событие, если только событие не будет отменено вручную. Порядок трансляции событий — это порядок поиска в ширину
- излучать сизлучать событие.
- Invoke — это прямой вызов страницы или компонента к методу в другом компоненте, поиск соответствующего компонента путем передачи пути к компоненту, а затем вызов его метода.
Например, вы хотите вызвать метод компонента ComA на странице Page_Index:
this.$invoke('ComA', 'someMethod', 'someArgs');
Если вы хотите вызвать метод компонента ComG в компоненте ComA:
this.$invoke('./../ComB/ComG', 'someMethod', 'someArgs');
Пользовательский обработчик событий компонента
Вы можете привязывать события к пользовательским компонентам с помощью модификатора .user, например: @customEvent.user="myFn"
Среди них @ представляет модификатор события, customEvent представляет имя события, а .user представляет суффикс события.
В настоящее время существует три суффикса событий:
.default: 绑定小程序冒泡型事件,如bindtap,.default后缀可省略不写;
.stop: 绑定小程序捕获型事,如catchtap;
.user: 绑定用户自定义组件事件,通过$emit触发。
// index.wpy
<template>
<child @childFn.user="parentFn"></child>
</template>
<script>
import wepy from 'wepy'
import Child from '../components/child'
export default class Index extends wepy.page {
components = {
child: Child
}
methods = {
parentFn (num, evt) {
console.log('parent received emit event, number is: ' + num)
}
}
}
</script>
// child.wpy
<template>
<view @tap="tap">Click me</view>
</template>
<script>
import wepy from 'wepy'
export default class Child extends wepy.component {
methods = {
tap () {
console.log('child is clicked')
this.$emit('childFn', 100)
}
}
}
</script>
слот распределения содержимого компонента слота
Слот в WePY используется в качестве метки занятости пространства метки распространения контента, что облегчает более гибкое и удобное распространение контента подкомпонентов за счет «подключения и отключения» метки распространения контента, эквивалентной плате расширения в родительском компоненте. . . .
Конкретный метод использования заключается в том, чтобы сначала объявить тег слота в качестве слота содержимого в части шаблона шаблона подкомпонента, и в то же время имя слота должно быть указано в его атрибуте имени, и содержимое тега по умолчанию также может быть set; Тег распространения содержимого для «pluggable» объявляется в разделе шаблона шаблона родительского компонента дочернего компонента.
Обратите внимание, что теги распространения контента в этих родительских компонентах должны иметь атрибут слота, а его значением является имя соответствующего слота в дочернем компоненте, чтобы контент в теге распространения контента родительского компонента переопределял контент по умолчанию в соответствующий слот дочернего компонента.
在Panel组件中有以下模板:
<view class="panel">
<slot name="title">默认标题</slot>
<slot name="content">默认内容</slot>
</view>
在父组件中使用Pannel子组件时,可以这样使用:
<panel>
<view slot="title">新的标题</view>
<view slot="content">
<text>新的内容</text>
</view>
</panel>
смешивание
- смесь по умолчанию
Для данных данных компонентов, компонентов компонентов, событий событий и других пользовательских методов используется смешивание по умолчанию, то есть, если компонент не объявляет данные, компоненты, события, пользовательские методы и т. д., то параметры в смешанном объекте будут внедряться в компонент. Параметры, объявленные для компонента, не будут затронуты.
// mixins/test.js
import wepy from 'wepy';
export default class TestMixin extends wepy.mixin {
data = {
foo: 'foo defined by page',
bar: 'bar defined by testMix'
};
methods: {
tap () {
console.log('mix tap');
}
}
}
// pages/index.wpy
import wepy from 'wepy';
import TestMixin from './mixins/test';
export default class Index extends wepy.page {
data = {
foo: 'foo defined by index'
};
mixins = [TestMixin ];
onShow() {
console.log(this.foo); // foo defined by index.
console.log(this.bar); // foo defined by testMix.
}
}
- Совместимый гибрид
Совместимое микширование будет использоваться для событий ответа методов компонента и событий страницы апплета, то есть сначала сам компонент отвечает на события, а затем смешанный объект отвечает на события.
// mixins/test.js
import wepy from 'wepy';
export default class TestMixin extends wepy.mixin {
methods = {
tap () {
console.log('mix tap');
}
};
onShow() {
console.log('mix onshow');
}
}
// pages/index.wpy
import wepy from 'wepy';
import TestMixin from './mixins/test';
export default class Index extends wepy.page {
mixins = [TestMixin];
methods = {
tap () {
console.log('index tap');
}
};
onShow() {
console.log('index onshow');
}
}
// index onshow
// mix onshow
// ----- when tap
// index tap
// mix tap
перехватчик
Вы можете использовать глобальный перехватчик для настройки методов конфигурации, сбоя, успеха и завершения API. См. пример:
import wepy from 'wepy';
export default class extends wepy.app {
constructor () {
this.intercept('request', {
config (p) {
p.timestamp = +new Date();
return p;
},
success (p) {
console.log('request success');
return p;
},
fail (p) {
console.log('request error');
return p;
}
});
}
}
Метод привязки данных WePY
WePY использует проверку грязных данных для инкапсуляции setData и выполняет проверку грязных данных в конце цикла выполнения функции.Во-первых, вам не нужно заботиться о том, будут ли у страницы проблемы с производительностью при многократном setData.Во-вторых, это может быть более кратким, чтобы изменить данные для достижения привязки.Нет необходимости повторно писать метод setData.
this.title = 'this is title';
Изменение данных в функциях вне цикла выполнения функции требует ручного вызова метода $apply.
setTimeout(() => {
this.title = 'this is title';
this.$apply();
}, 3000);
Оптимизация передачи параметров события
// 官方
<view data-id="{{index}}" data-title="wepy" data-other="otherparams" bindtap="tapName"> Click me! </view>
Page({
tapName: function(event) {
console.log(event.currentTarget.dataset.id)// output: 1
console.log(event.currentTarget.dataset.title)// output: wepy
console.log(event.currentTarget.dataset.other)// output: otherparams
}
});
// WePY 1.1.8以后的版本,只允许传string。
<view bindtap="tapName({{index}}, 'wepy', 'otherparams')"> Click me! </view>
methods: {
tapName (id, title, other, event) {
console.log(id, title, other)// output: 1, wepy, otherparams
}
}
Изменить метод привязки данных
Сохраните метод setData, но не рекомендуется использовать setData для выполнения привязки, исправления ошибки передачи в undefined и изменения поддержки входных параметров: this.setData(target, value) this.setData(object)
// 官方
<view> {{ message }} </view>
onLoad: function () {
this.setData({message: 'hello world'});
}
// WePY
<view> {{ message }} </view>
onLoad () {
this.message = 'hello world';
}
Важное напоминание
- Используйте Инструменты разработчика WeChat -> Добавить проект, выберите каталог dist для каталога проекта.
- Инструменты разработчика WeChat -> Проект -> Отключить ES6 на ES5. Важно: пропуск этого приведет к ошибке.
- Инструменты разработчика Wechat -> Проект -> Отключить автодополнение стиля при загрузке кода. ВАЖНО: в некоторых случаях отсутствие этого также приведет к ошибке.
- Инструменты разработчика WeChat -> проект -> закрыть загрузку сжатия кода. Важно: после открытия это приведет к сбою вычисления реальной машины, props.sync и других свойств. (Примечание. Функцию сжатия можно заменить командой сборки, предоставляемой WePY. Подробности см. в соответствующем введении позже и в файлах wepy.config.js и package.json в корневом каталоге демо-проекта.)
- Запустите wepy build –watch в корневом каталоге локального проекта, чтобы включить компиляцию в реальном времени. (Примечание: Если при этом в WeChat Developer Tools -> Settings -> Editor можно автоматически скомпилировать апплет при сохранении файла, то можно предварительно просмотреть его в реальном времени, что очень удобно.)
Уведомление
- Атрибут методов в WePY может объявлять только события связывания и перехвата тега wxml страницы, но не может объявлять пользовательские методы.
Справочная статья
Пишите мини-программы WeChat, такие как VUE — глубокое погружение в Wepy Framework
Сводка ресурсов
Среда разработки компонентов апплета WeChat — wepyjs
Среда разработки компонентных апплетов WeChat Официальная документация WePY
Официальная документация Vue