提交 6d6bdf84 编写于 作者: fxy060608's avatar fxy060608

feat(h5): createSelectorQuery支持 in方法

上级 f7344c53
......@@ -277,33 +277,53 @@ function initMocks (vm) {
});
}
function initHooks (mpOptions, hooks) {
function initHooks (mpOptions, hooks, delay = false) {
hooks.forEach(hook => {
mpOptions[hook] = function (args) {
if (delay) {
setTimeout(() => this.$vm.__call_hook(hook, args));
} else {
this.$vm.__call_hook(hook, args);
}
};
});
}
function getData (data) {
function getData (vueOptions) {
let data = vueOptions.data || {};
const methods = vueOptions.methods || {};
if (typeof data === 'function') {
try {
return data()
data = data();
} catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。');
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
return {}
}
return data || {}
return Object.assign(data, methods)
}
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver (name) {
return function observer (newVal, oldVal) {
if (this.$vm) {
this.$vm[name] = newVal; // 为了触发其他非 render watcher
}
}
}
function getProperties (props) {
const properties = {};
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = null;
properties[key] = {
type: null,
observer: createObserver(key)
};
});
} else if (isPlainObject(props)) { // {title:{type:String,default:''},content:String}
Object.keys(props).forEach(key => {
......@@ -315,10 +335,14 @@ function getProperties (props) {
}
properties[key] = {
type: PROP_TYPES.includes(opts.type) ? opts.type : null,
value
value,
observer: createObserver(key)
};
} else { // content:String
properties[key] = PROP_TYPES.includes(opts) ? opts : null;
properties[key] = {
type: PROP_TYPES.includes(opts) ? opts : null,
observer: createObserver(key)
};
}
});
}
......@@ -331,6 +355,7 @@ function wrapper$1 (event) {
event.target = event.target || {};
event.detail = event.detail || {};
// TODO 又得兼容 mpvue 的 mp 对象
event.mp = event;
event.target = Object.assign({}, event.target, event.detail);
......@@ -379,6 +404,9 @@ function handleEvent (event) {
if (eventsArray && eventType === type) {
eventsArray.forEach(eventArray => {
const handler = this.$vm[eventArray[0]];
if (!isFn(handler)) {
throw new Error(` _vm.${eventArray[0]} is not a function`)
}
if (isOnce) {
if (handler.once) {
return
......@@ -400,12 +428,12 @@ function initRefs (vm) {
Object.defineProperty(vm, '$refs', {
get () {
const $refs = Object.create(null);
const components = mpInstance.selectAllComponents('.__ref__');
const components = mpInstance.selectAllComponents('.vue-ref');
components.forEach(component => {
const ref = component.dataset.ref;
$refs[ref] = component.$vm;
});
const forComponents = mpInstance.selectAllComponents('.__ref-in-for__');
const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for');
forComponents.forEach(component => {
const ref = component.dataset.ref;
if (!$refs[ref]) {
......@@ -418,6 +446,20 @@ function initRefs (vm) {
});
}
function initChildren (vm) {
const mpInstance = vm.$mp[vm.mpType];
Object.defineProperty(vm, '$children', {
get () {
const $children = [];
const components = mpInstance.selectAllComponents('.vue-com');
components.forEach(component => {
$children.push(component.$vm);
});
return $children
}
});
}
const hooks = [
'onShow',
'onHide',
......@@ -427,20 +469,41 @@ const hooks = [
function createApp (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
Vue.mixin({
beforeCreate () {
if (!this.$options.mpType) {
return
}
this.mpType = this.$options.mpType;
this.$mp = {
data: {},
[this.mpType]: this.$options.mpInstance
};
delete this.$options.mpType;
delete this.$options.mpInstance;
if (this.mpType !== 'app') {
initRefs(this);
initMocks(this);
initChildren(this);
}
}
});
const appOptions = {
onLaunch (args) {
this.$vm = new Vue(vueOptions);
this.$vm.mpType = 'app';
this.$vm.$mp = {
app: this
};
this.$vm = new Vue(Object.assign(vueOptions, {
mpType: 'app',
mpInstance: this
}));
this.$vm.$mount();
this.$vm.__call_hook('onLaunch', args);
setTimeout(() => this.$vm.__call_hook('onLaunch', args));
}
};
initHooks(appOptions, hooks);
initHooks(appOptions, hooks, true); // 延迟执行,因为 App 的注册在 main.js 之前,可能导致生命周期内 Vue 原型上开发者注册的属性无法访问
App(appOptions);
......@@ -466,28 +529,27 @@ const hooks$1 = [
function createPage (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
const pageOptions = {
data: getData(vueOptions.data),
data: getData(vueOptions),
onLoad (args) {
this.$vm = new Vue(vueOptions);
this.$vm.mpType = 'page';
this.$vm.$mp = {
data: {},
page: this
};
initRefs(this.$vm);
initMocks(this.$vm);
this.$vm = new Vue(Object.assign(vueOptions, {
mpType: 'page',
mpInstance: this
}));
this.$vm.$mount();
this.$vm.__call_hook('onLoad', args);
},
onReady () {
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
onUnload () {
this.$vm.__call_hook('onUnload');
{
this.$vm.$destroy();
}
},
__e: handleEvent,
__l: handleLink
......@@ -498,6 +560,23 @@ function createPage (vueOptions) {
return Page(pageOptions)
}
function initVueComponent (mpInstace, VueComponent) {
if (mpInstace.$vm) {
return
}
const options = {
mpType: 'component',
mpInstance: mpInstace,
propsData: mpInstace.properties
};
// 初始化 vue 实例
mpInstace.$vm = new VueComponent(options);
// 初始化渲染数据
mpInstace.$vm.$mount();
}
function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
......@@ -510,30 +589,18 @@ function createComponent (vueOptions) {
multipleSlots: true,
addGlobalClass: true
},
data: getData(vueOptions.data),
data: getData(vueOptions),
properties,
lifetimes: {
attached () {
// props的处理,一个是直接 与 mp 的 properties 对接,另一个是要做成 reactive,且排除掉 render watch
const options = {
propsData: this.properties,
$component: this
};
// 初始化 vue 实例
this.$vm = new VueComponent(options);
this.$vm.mpType = 'component';
this.$vm.$mp = {
data: {},
component: this
};
initRefs(this.$vm);
initMocks(this.$vm);
// 初始化渲染数据
this.$vm.$mount();
initVueComponent(this, VueComponent);
},
ready () {
this.triggerEvent('__l', this.$vm);
initVueComponent(this, VueComponent); // 目前发现部分情况小程序 attached 不触发
{
this.triggerEvent('__l', this.$vm); // TODO 百度仅能传递 json 对象
}
const eventId = this.dataset.eventId;
if (eventId) {
......@@ -554,6 +621,7 @@ function createComponent (vueOptions) {
},
detached () {
this.$vm.$destroy();
}
},
pageLifetimes: {
show (args) {
......
{
"name": "@dcloudio/uni-app-plus",
"version": "0.0.2",
"version": "0.0.201",
"description": "uni-app app-plus",
"main": "dist/index.js",
"scripts": {
......
......@@ -412,9 +412,11 @@ function getData (vueOptions) {
try {
data = data();
} catch (e) {
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
}
return Object.assign(data, methods)
}
......@@ -678,6 +680,7 @@ function createPage (vueOptions) {
},
onReady () {
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
onUnload () {
......
{
"name": "@dcloudio/uni-mp-baidu",
"version": "0.0.804",
"version": "0.0.806",
"description": "uni-app mp-baidu",
"main": "dist/index.js",
"scripts": {
......
......@@ -457,9 +457,11 @@ function getData (vueOptions) {
try {
data = data();
} catch (e) {
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
}
return Object.assign(data, methods)
}
......@@ -700,6 +702,7 @@ function createPage (vueOptions) {
},
onReady () {
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
onUnload () {
......
{
"name": "@dcloudio/uni-mp-toutiao",
"version": "0.0.301",
"version": "0.0.303",
"description": "uni-app mp-toutiao",
"main": "dist/index.js",
"scripts": {
......
......@@ -299,9 +299,11 @@ function getData (vueOptions) {
try {
data = data();
} catch (e) {
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
}
return Object.assign(data, methods)
}
......@@ -542,6 +544,7 @@ function createPage (vueOptions) {
},
onReady () {
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
onUnload () {
......
{
"name": "@dcloudio/uni-mp-weixin",
"version": "0.0.905",
"version": "0.0.907",
"description": "uni-app mp-weixin",
"main": "dist/index.js",
"scripts": {
......
......@@ -43,6 +43,7 @@ export function createPage (vueOptions) {
},
onReady () {
this.$vm._isMounted = true
this.$vm.__call_hook('mounted')
this.$vm.__call_hook('onReady')
},
onUnload () {
......
......@@ -36,9 +36,11 @@ export function getData (vueOptions) {
try {
data = data()
} catch (e) {
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data)
}
}
}
return Object.assign(data, methods)
}
......
......@@ -84,7 +84,7 @@ class SelectorQuery {
}
['in'] (component) {
console.error('Unsupported method:SelectorQuery.in')
this._component = component
return this
}
......
......@@ -74,7 +74,8 @@ function getNodeInfo (el, fields) {
}
function getNodesInfo (pageVm, component, selector, single, fields) {
const $el = pageVm.$el
/* eslint-disable no-mixed-operators */
const $el = component && component.$el || pageVm.$el
if (single) {
const node = $el && ($el.matches(selector) ? $el : $el.querySelector(selector))
if (node) {
......
......@@ -1784,10 +1784,14 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000940:
caniuse-lite@^1.0.0:
version "1.0.30000940"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000940.tgz#19f2b1497fbfa5b96b615963097c3757f27989ce"
caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000940:
version "1.0.30000948"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000948.tgz#793ed7c28fe664856beb92b43fc013fc22b81633"
case-sensitive-paths-webpack-plugin@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e"
......@@ -2698,8 +2702,8 @@ ejs@^2.6.1:
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
electron-to-chromium@^1.3.113:
version "1.3.113"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz#b1ccf619df7295aea17bc6951dc689632629e4a9"
version "1.3.116"
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.116.tgz#1dbfee6a592a0c14ade77dbdfe54fef86387d702"
elliptic@^6.0.0:
version "6.4.1"
......@@ -4953,8 +4957,8 @@ node-pre-gyp@^0.10.0:
tar "^4"
node-releases@^1.1.8:
version "1.1.9"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.9.tgz#70d0985ec4bf7de9f08fc481f5dae111889ca482"
version "1.1.10"
resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.10.tgz#5dbeb6bc7f4e9c85b899e2e7adcc0635c9b2adf7"
dependencies:
semver "^5.3.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册