1.node 的安装
节点网官下载
推荐左边的安装方式,因为右边的最新版本在有些电脑上运行不稳定。
下载到本地一直继续就好。
安装好后就可以直接在命令行运行查看结果
2.快速入门
WePY 是一款让小程序支持组件化开发的框架,通过预编译的手段让开发者可以选择自己喜欢的开发风格去开发小程序。框架的细节优化,无极,异步功能的引入都是为了能让开发小程序项目变得更加简单,高效。
同时 WePY 也是一款成长中的框架,大量吸收借鉴了一些优化前端工具以及框架的设计理念和思想。如果 WePY 有不足地方,或者你有更好的想法,欢迎提交发行或者 PR。
安装(更新)wepy 命令行工具。
npm install wepy-cli -g
在开发目录生成开发 DEMO。
wepy new demo
切换至项目目录。
cd demo
打开目录
窗口
dir
项目目录结构
├── dist 微信开发者工具指定的目录
├── node_modules
├── src 代码编写的目录
| ├── components 组件文件夹(非完整页面)
| | ├── com_a.wpy 可复用组件 a
| | └── com_b.wpy 可复用组件 b
| ├── pages 页面文件夹(完整页面)
| | ├── index.wpy 页面 index
| | └── page.wpy 页面 page
| └── app.wpy 小程序配置项(全局样式配置、声明钩子等)
└── package.json package 配置
开发使用说明
- 使用
微信开发者工具
新建项目,开发本地选择dist
目录。 微信开发者工具
- >项目 - >关闭 ES6 转 ES5。- 本地项目根目录运行
wepy build --watch
,开启实时编译。
代码高亮
VScode 下代码高亮
先下载
配置展示进入设置
在 settings.js 文件下添加如下代码
"files.associations": {
"*.vue": "vue",
"*.wpy": "vue",
"*.wxml": "html",
"*.wxss": "css"
},
"emmet.syntaxProfiles": {
"vue-html": "html",
"vue": "html"
}
后就保存在可以中页面看待.wpy
后缀代码高亮
Sublime 下载码高亮
文件后缀为.wpy,可共用 vue 高亮,但需要手动安装。
打开 Sublime-> Preferences-> Browse Packages ..进入用户包文件夹。
在此文件夹下打开 cmd,运行 git clone git@github.com:vuejs / VUE -句法- highlight.git,无 GIT 用户可以直接下载拉链包解压至当前文件夹。
关闭.wpy 文件重新打开即可高亮。WebStorm 下代码高亮
打开首选项,搜索插件,搜索 Vue.js 插件并安装。
打开首选项,搜索文件类型,找到 Vue.js 模板,在注册模式添加* .wpy,即可高亮。Atom 下代码高亮
在 Atom 里先安装 vue 的语法高亮 - language-vue,如果装过了就忽略这一步。
打开 Atom - >配置菜单。在 core 键下添加:
customFileTypes:
"text.html.vue": [
"wpy"
]
3,代码规范
- 变量与方法使用尽量使用驼峰式命名,避免使用$开头。
- 入口,页面,组件的命名后缀为.wpy。外链的文件可以是其它后缀。
- 使用 ES6 语法开发。框架在 ES6 下开发,因此也需要使用 ES6 开发小程序,ES6 中有大量的语法糖可以让我们的代码更加简洁高效。
- 甚至可以直接使用异步/等待等新特性进行开发。
- 事件绑定语法使用优化语法代替:原 bindtap =“click”替换为@ tap =“click”,原 catchtap =“click”替换为@ tap.stop =“click”。更多@符用法
- 事件传参使用优化后语法代替:原 bindtap =“click”data-index = { {index}}替换为@ tap =“click({ {index}})”。
- 自定义组件命名应避开微信原生组件以及功能标签。不可以使用输入,按钮,查看,重复等命名自定义组件。
4.优点
- 支持组件化开发。
- 支持加载外部 NPM 包。
- 单文件模式,使得目录结构更加清晰。
- 默认使用巴别编译,支持 ES6 / 7 的一些新特性。
- 针对原生 API 进行优化。
5.wpy 文件说明
一个.wpy
文件分为三个部分:
1 .样式对应原有 wxss。2.
模板对应原有 wxml。3.
代码对应原有 js。
其中入口文件 app.wpy 不需要模板,所以编译时会被忽略。这三个标签都支持郎和 SRC 属性,郎决定了其代码编译过程,SRC 决定是否外联代码,存在 SRC 属性且有效时,忽略内联代码,示例如下:
<style lang="less" src="page1.less">style>
<template lang="wxml" src="page1.wxml">template>
<script>
// some code
script>
标签对应 lang 值如下表所示:
标签
郎默认值
郎支持值
样式
CSS
CSS,少,上海社会科学院,手写笔
模板
wxml
wxml,XML,哈巴狗(原玉)
脚本
巴布尔
巴布尔,打字稿
演示
index.wpy
<style lang="less">
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
style>
<template>
<view class="container">
<view class="userinfo" @tap="handleViewTap">
<image class="userinfo-avatar" src="{ { userInfo.avatarUrl }}" background-size="cover" />
<view class="userinfo-nickname">{ { userInfo.nickName }}view>
view>
<panel>
<view>{ { datas }}'111'view>
<view @tap="doLogin" class="item">
<view class="item-inner">登录view>
view>
<view @tap="enevts" class="item">
<view class="item-inner">用户信息view>
view>
panel>
<panel>
<view class="title" slot="title">测试数据绑定view>
<text class="info">{ {normalTitle}}text>
<text class="info">{ {setTimeoutTitle}}text>
<text class="info">{ {mixin}}text>
<text class="info">{ {mynum}}text>
<text class="info">{ {now}}text>
<button @tap="plus('a')" size="mini"> + button>
panel>
<panel>
<view class="title" slot="title">其它测试view>
<button @tap="toast" size="mini">第三方组件button>
<button @tap="communicate" size="mini">组件通信button>
<button @tap="tap" size="mini">混合TAP事件button>
panel>
<panel>
<view class="title" slot="title">测试并发网络请求view>
<view>返回结果:
<text>{ {netrst}}text>
view>
<button @tap="request" size="mini"> 点我发起10个请求 button>
panel>
<panel>
<view class="title" slot="title">测试组件view>
<text class="testcounter">计数组件1: text>
<view class="counterview">
<counter1 @index-emit="counterEmit" />
view>
<text class="testcounter">计数组件2: text>
<view class="counterview">
<counter2 :num.sync="mynum">counter2>
view>
panel>
<panel>
<view class="title" slot="title">测试组件Repeatview>
<repeat for="{ {groupList}}" index="index" item="item" key="key">
<group :grouplist="item" :indexa="index">group>
repeat>
panel>
<panel>
<view class="title" slot="title">测试列表view>
<list>list>
panel>
<toast />
view>
template>
<script>
import wepy from 'wepy'
import List from '../components/list'
import Panel from '../components/panel'
import Counter from '../components/counter'
import Group from '../components/group'
import Toast from 'wepy-com-toast'
import testMixin from '../mixins/test'
// 引入 QCloud 小程序增强 SDK
import qcloud from '../assets/qcloud-weapp-client-sdk/index'
export default class Index extends wepy.page {
config = {
navigationBarTitleText: 'test'
}
components = {
panel: Panel,
counter1: Counter,
counter2: Counter,
list: List,
group: Group,
toast: Toast
}
mixins = [testMixin]
data = {
datas: '',
mynum: 20,
userInfo: {
nickName: '加载中...'
},
normalTitle: '原始标题',
setTimeoutTitle: '标题三秒后会被修改',
count: 0,
netrst: '',
groupList: [
{
id: 1,
name: '点击改变',
list: [
{
childid: '1.1',
childname: '子项,点我改变'
}, {
childid: '1.2',
childname: '子项,点我改变'
}, {
childid: '1.3',
childname: '子项,点我改变'
}
]
},
{
id: 2,
name: '点击改变',
list: [
{
childid: '2.1',
childname: '子项,点我改变'
}, {
childid: '2.2',
childname: '子项,点我改变'
}, {
childid: '2.3',
childname: '子项,点我改变'
}
]
},
{
id: 3,
name: '点击改变',
list: [
{
childid: '3.1',
childname: '子项,点我改变'
}
]
}
]
}
computed = {
now() {
return +new Date()
}
}
methods = {
doLogin() {
qcloud.setLoginUrl('https://66280981.qcloud.la/api/user/login');
qcloud.login({
success: function (userInfo) {
console.log('登录成功', userInfo);
},
fail: function (err) {
console.log('登录失败', err);
}
});
},
enevts() {
qcloud.request({
url: `https://66280981.qcloud.la/api/user/info`,
login: true,
success: (response) => {
console.log(response.data.data.userInfo)
// this.me = response.data.data.userInfo;
// this.connect();
}
});
},
plus() {
this.mynum++
},
toast() {
let promise = this.$invoke('toast', 'show', {
title: '自定义标题',
img: 'https://raw.githubusercontent.com/kiinlam/wetoast/master/images/star.png'
})
promise.then((d) => {
console.log('toast done')
})
},
tap() {
console.log('do noting from ' + this.$name)
},
communicate() {
console.log(this.$name + ' tap')
this.$invoke('counter2', 'minus', 45, 6)
this.$invoke('counter1', 'plus', 45, 6)
this.$broadcast('index-broadcast', 1, 3, 4)
},
request() {
let self = this
let i = 10
let map = ['MA==', 'MQo=', 'Mg==', 'Mw==', 'NA==', 'NQ==', 'Ng==', 'Nw==', 'OA==', 'OQ==']
while (i--) {
wepy.request({
url: 'https://www.madcoder.cn/tests/sleep.php?time=1&t=css&c=' + map[i] + '&i=' + i,
success: function (d) {
self.netrst += d.data + '.'
self.$apply()
}
})
}
},
counterEmit(...args) {
let $event = args[args.length - 1]
console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`)
}
}
events = {
'index-emit': (...args) => {
let $event = args[args.length - 1]
console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`)
}
}
onLoad() {
let self = this
this.$parent.getUserInfo(function (userInfo) {
if (userInfo) {
self.userInfo = userInfo
}
self.normalTitle = '标题已被修改'
self.setTimeoutTitle = '标题三秒后会被修改'
setTimeout(() => {
self.setTimeoutTitle = '到三秒了'
self.$apply()
}, 3000)
self.$apply()
})
}
}
script>