配音圈配音
最后更新时间:
配音圈配音的模块化
ES6的Class 类
在传统的js
语法当中,如果我们想创建一个实例对象的时候一般会先定义一个构造函数,然后通过new
运算符来创建一个实例对象,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.showName = function(){
console.log(this.name)
}
Person.prototype.showAge = function(){
console.log(this.age)
}
var person = new Person('xz',21)
person.showName()//'xz'
person.showAge()//21
我们定义一个Person
的构造函数,然后通过new Person()
来创建一个实例对象。一般我们向构造函数的原型上添加方法,表示实例要继承的方法,这个方法是公共的,不是某个实例自己特有的方法。这样我们就可以完成一个具体的实例了。
而在ES6
中,为我们提供了一个叫Class
的一个方法,让我们能够更容易理解和创建一个实例对象。例如:
1 |
|
注意:
- 如果使用es6的class类语法要注意一点就是 `constructor`方法是类默认方法,通过`new`命令生成对象实例时自动调用该方法。一个类必须有一个`constructor`方法,如果没有显示定义,那么一个空的`constructor`方法会被默认添加。
- 类的声明不存在变量提升
1 |
|
js类的继承
根据ES6的语法,super关键字,extends来进行类的继承操作
我们可以通过extends
关键字来实现子类对父类的继承。子类必须在constructor
方法中调用super
方法,否则新建的实例会报错。原因在于子类没有自己的this
对象,而是继承父类的this
对象,然后进行加工,如果不调用super
关键字,那么子类就拿不到this
对象,而super
在其中表示的其实是父类的构造函数
1 |
|
配音圈配音的utils里有6个文件,模块化的大致思路是一样的。举例:
config.js
1
2
3
4
5
6
7
8
9
10class Config{
constructor(){
}
}
Config.restUrl = 'https://dub.wuhanzhuangxiu01.cn';
Config.onPay = true; //是否启用支付
........
export {Config};base.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74/**
* 自定义基类
*/
import {
Config
} from './config.js';
var app = getApp();
class Base {
constructor() {
this.baseRequestUrl = Config.restUrl;
}
/**
* 封装request请求
*/
request(params, noRefetch) {
var url = this.baseRequestUrl + params.url;
var that = this;
/* 判断请求方式 默认为'POST' */
if (!params.type) {
params.type = 'POST';
}
wx.request({
url: url,
data: params.data,
header: {
'content-type': 'application/json',
'token': wx.getStorageSync('token'),
},
method: params.type,
dataType: 'json',
responseType: 'text',
success: function (res) {
// res.data.param.disable == 1? wx.setStorageSync('disable', 1): wx.setStorageSync('disable', 0);
var code = res.statusCode.toString();
var startChar = code.charAt(0);
if (startChar == '2') {
params.sCallback && params.sCallback(res.data);
} else {
that._processError(res);
params.eCallback && params.eCallback(res.data);
}
},
fail: function (res) {
that._processError(res);
},
})
}
/**
* 消息提示
*/
showToast(title, icon) {
if (!icon) {
icon = 'none';
}
wx.showToast({
title: title,
icon: icon,
duration: 2000,
})
}
........
}
export {
Base
};public.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31/**
* Home
* 自定义类
*/
import {
Base
} from '../../utils/base.js';
class Public extends Base {
constructor() {
/* 必须: 调用基类的构造函数 */
super();
}
/**获取金牌推荐 */
gold_recommend(data, callback) {
var params = {
url: '/gold_list',
data: data,
sCallback: function (res) {
callback && callback(res);
},
}
this.request(params);
}
........
}
/* 输出类HOME */
export {
Public
};使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import {
Public
} from '../tpls/public.js';
var pub = new Public();
Page({
onLoad(){
pub.gold_recommend({
'page': 1,
'limit': 5
}, (res) => {
if (res.code == 200) {
that.setData({
GlodList: res.data
})
}
});
}
})
登录模块
小程序的生命周期
onReady 生命周期函数–监听页面初次渲染完成
onShow 生命周期函数–监听页面显示
onHide 生命周期函数–监听页面隐藏
onUnload 生命周期函数–监听页面卸载
onPullDownRefresh 页面相关事件处理函数–监听用户下拉动作
onReachBottom 页面上拉触底事件的处理函数
onShareAppMessage 用户点击右上角转发
onPageScroll 页面滚动触发事件的处理函数
onTabItemTap 当前是 tab 页时,点击 tab 时触发
配音圈配音因为是用原生微信小程序进行编写的,没有watch,没有vuex,所以看似很简单的方式就很难实现。就比如进入到小程序里面先进行登录获取头像以及openid,在通过拿到的openid进行身份判断。这里的身份判断要在首页里展示,所以写在首页的onload里,而登录这个东西最早用,并且很多地方用。所以写在小程序的onlaunch函数里。但是因为onlaunch里执行的登录获取openid是个请求,有异步效果。所以在小程序执行完页面的生命周期函数的时候,可能还没有拿到openid。而配音圈配音通过一个回调函数解决了这个问题。
总结来说就是微信小程序app.js的onLaunch中的异步请求执行完之后再执行Page的onLoad
app.js
1 |
|
index.js
1 |
|
这里执行的流程是当微信小程序运行时,首先进入到了onLaunch进行执行,因为onLaunch里面有request是异步请求,所以压力来到了index.js的onload里面,在onload里去判断app.js里的数据状态是什么样的,是true就拿request里的数据,如果没有就对app,js的app对象进行添加一个回调函数属性,在这个回调函数属性里需要传入一个true就能操作index.js的page对象里的data,给onlaunch里请求的值赋值给index.js的page对象里的data。这个时候因为之前在onLaunch写的调用自己的在index.js里写的回调,并传入true,对index.js中data中的数据进行赋值。
h5上传文件模块
参考资料
Uniapp 内嵌H5跳转内嵌小程序页面
uniapp h5项目点击跳转小程序,h5传参到小程序
微信小程序与h5通过web-view传值
[填坑手册]小程序web-view组件实战与踩坑
首先因为微信小程序无法打开本地资源管理器。所以都是通过微信的wx.chooseMessageFile
进行在本地聊天记录中选取文件。(这种方法也是目前大部分小程序采取上传文件的方式优点是:速度快、兼容性好。缺点:用户需要提前把文件发送给自己聊天列表中的随便一个人)wx.chooseMessageFile
代码实现
1 |
|
现在需要直接通过微信小程序去访问本地的资源管理器。我的解决思路的是,通过微信小程序使用webview去调用一个h5页面。在通过h5页面去调用本地资源。选取后将资源上传服务器,在返回到小程序。这里比较困难的是小程序向webview传值以及webview跳回小程序,以及返回参数到小程序。
这里首先需要写一个h5的页面进行上传文件,这里需要引入小程序的一个sdk,uniapp使用 npm install --save-dev weixin-js-sdk
。然后在main.js里进行全局引入let jweixin = require('jweixin-module')
Vue.prototype.$wx = jweixin
。
1 |
|
这里从webview的网页跳回小程序有个问题。就是只能用navigateBack
进行返回。文档上说的是navigateTo、navigateBack、switchTab、reLaunch、redirectTo都能使用,但是在我的环境下只能使用navigateBack
进行返回。传值我是通过webview的bindmessage属性进行传值。首先在webview定义好属性写好回调。在h5页面,使用wx.miniProgram.postMessage来进行传值。传的值会在 bindmessage定义好的函数里形参里。
因为之前我是使用 navigateBack
进行返回的。所以返回的值一直在webview页面。我需要传值给我的返回的这个界面。我在app.js里面定义一个属性进行页面之间的通信。在webview页面接受传回来的值,存放在app.js上面的属性。在跳转的页面进行拿取传过来的值。就能完成从webview传值给微信小程序。
微信小程序webview示例代码:
1 |
|
这部分代码中的wxml部分,src部分写的很复杂。只有这么写,才能带参数,访问这个h5页面。之前我是先将url合并之后一块给src,但是这个h5会在链接自动生成#
在路径里。然后微信这边会自动将#号过滤掉。这个#号是因为路由器的两种工作模式之一的hash模式造成的。
详解可见 Uniapp发布为H5版本时如何隐藏访问路径的#符号
原型与原型链
所有函数都有一个特别的属性:
**prototype**
** : 显式原型属性**- 每个函数都有一个prototype属性, 它默认指向一个Object空对象
- 原型对象中有一个属性constructor, 它指向函数对象
- 作用: 函数的所有实例对象自动拥有原型中的属性(方法)
1
2
3
4
5
6
7
8
9
10
11//fun的prototype默认指向一个Object空对象
console.log(Fun.prototype);
// 原型对象中有一个属性constructor, 它指向函数对象
console.log(Fun.prototype.constructor == Fun)
Fun.prototype.test = function(){
console.log('我是Fun原型上的一个方法');
}
let fun = new Fun()
// 给原型对象添加的属性 ==> 实例对象可以访问
fun.test()
所有实例对象都有一个特别的属性:
**__proto__**
** : 隐式原型属性**- 对象的隐式原型的值为其对应构造函数的显式原型的值
1
2
3
4
5
6function Fun(){
}
let fun = new Fun()
console.log(Fun.prototype === fun.__proto__)
// 返回结果是true
- 对象的隐式原型的值为其对应构造函数的显式原型的值
在function Fun(){}
就相当于在内部 this.prototype = {}
在let fun = new Fun()
就相当于在内部 this.__proto__ = Fn.prototype
- 显示原型与隐式原型在堆和栈上的结构图
1
2
3function Fn(){};
var fn = new Fn();
console.log(fn.__proto__===Fn.prototype);
- 原型链
所有的实例对象都有__proto__
属性, 它指向的就是原型对象。这样通过__proto__
属性就形成了一个链的结构—->原型链- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
- 别名: 隐式原型链
- 作用: 查找对象的属性(方法)
代码
1 |
|
图解
- 注意:
函数的显示原型指向的对象默认是空Object实例对象(但Object不满足)
1
2
3console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false
console.log(Function.prototype instanceof Object) // true所有函数都是Function的实例(包含Function)
1 |
|
- Object的原型对象是原型链尽头
1
console.log(Object.prototype.__proto__) // null