Примечания к апплету WeChat

Апплет WeChat

Эта структура представляет собой внутреннюю структуру разработки 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           小程序配置项(全局样式配置、声明钩子等)

как развивать

быстрый старт

Структура каталогов ├── 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 это делается черезbroadcast,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属性值,当在父组件中改变时,会同时改变子组件对应的值。
}

Компонентная коммуникация и взаимодействие

Обработчики событий для мониторинга событий связи и взаимодействия между компонентами должны быть написаны в объекте событий компонентов и страниц.
- broadcastШироковещательное событие инициируется родительским компонентом, и все дочерние компоненты получат это широковещательное событие, если только событие не будет отменено вручную. Порядок трансляции событий — это порядок поиска в ширину
- emitизлучать сbroadcast正好相反,事件发起组件的所有祖先组件会依次接收到излучать событие.
- invokeInvoke — это прямой вызов страницы или компонента к методу в другом компоненте, поиск соответствующего компонента путем передачи пути к компоненту, а затем вызов его метода.
Например, вы хотите вызвать метод компонента 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