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

feat(h5): createSelectorQuery支持 in方法

上级 f7344c53
......@@ -4,7 +4,7 @@
"scripts": {
"lint": "eslint --fix --config package.json --ext .js --ext .vue --ignore-path .eslintignore build src",
"dev:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=true UNI_PLATFORM=h5 node build/build.js",
"build:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=false UNI_PLATFORM=h5 node build/build.js",
"build:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=false UNI_PLATFORM=h5 node build/build.js",
"build:app-plus": "npm run lint && cross-env UNI_PLATFORM=app-plus rollup -c build/rollup.config.js",
"build:mp-weixin": "npm run lint && cross-env UNI_PLATFORM=mp-weixin rollup -c build/rollup.config.js",
"build:mp-baidu": "npm run lint && cross-env UNI_PLATFORM=mp-baidu rollup -c build/rollup.config.js",
......
......@@ -277,33 +277,53 @@ function initMocks (vm) {
});
}
function initHooks (mpOptions, hooks) {
function initHooks (mpOptions, hooks, delay = false) {
hooks.forEach(hook => {
mpOptions[hook] = function (args) {
this.$vm.__call_hook(hook, 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]) {
......@@ -416,6 +444,20 @@ function initRefs (vm) {
return $refs
}
});
}
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 = [
......@@ -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._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
onUnload () {
this.$vm.__call_hook('onUnload');
this.$vm.$destroy();
{
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,50 +589,39 @@ function createComponent (vueOptions) {
multipleSlots: true,
addGlobalClass: true
},
data: getData(vueOptions.data),
data: getData(vueOptions),
properties,
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
};
lifetimes: {
attached () {
initVueComponent(this, VueComponent);
},
ready () {
initVueComponent(this, VueComponent); // 目前发现部分情况小程序 attached 不触发
initRefs(this.$vm);
initMocks(this.$vm);
{
this.triggerEvent('__l', this.$vm); // TODO 百度仅能传递 json 对象
}
// 初始化渲染数据
this.$vm.$mount();
},
ready () {
this.triggerEvent('__l', this.$vm);
const eventId = this.dataset.eventId;
if (eventId) {
const listeners = this.$vm.$parent.$mp.listeners;
if (listeners) {
const listenerOpts = listeners[eventId];
Object.keys(listenerOpts).forEach(eventType => {
listenerOpts[eventType].forEach(handler => {
this.$vm[handler.once ? '$once' : '$on'](eventType, handler);
const eventId = this.dataset.eventId;
if (eventId) {
const listeners = this.$vm.$parent.$mp.listeners;
if (listeners) {
const listenerOpts = listeners[eventId];
Object.keys(listenerOpts).forEach(eventType => {
listenerOpts[eventType].forEach(handler => {
this.$vm[handler.once ? '$once' : '$on'](eventType, handler);
});
});
});
}
}
}
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
detached () {
this.$vm.$destroy();
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
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": {
......
......@@ -404,7 +404,7 @@ function initHooks (mpOptions, hooks, delay = false) {
});
}
function getData (vueOptions) {
function getData (vueOptions) {
let data = vueOptions.data || {};
const methods = vueOptions.methods || {};
......@@ -412,7 +412,9 @@ function getData (vueOptions) {
try {
data = data();
} catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
}
......@@ -677,7 +679,8 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args);
},
onReady () {
this.$vm._isMounted = true;
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": {
......
......@@ -449,7 +449,7 @@ function initHooks (mpOptions, hooks, delay = false) {
});
}
function getData (vueOptions) {
function getData (vueOptions) {
let data = vueOptions.data || {};
const methods = vueOptions.methods || {};
......@@ -457,7 +457,9 @@ function getData (vueOptions) {
try {
data = data();
} catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
}
......@@ -699,7 +701,8 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args);
},
onReady () {
this.$vm._isMounted = true;
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": {
......
......@@ -291,7 +291,7 @@ function initHooks (mpOptions, hooks, delay = false) {
});
}
function getData (vueOptions) {
function getData (vueOptions) {
let data = vueOptions.data || {};
const methods = vueOptions.methods || {};
......@@ -299,7 +299,9 @@ function getData (vueOptions) {
try {
data = data();
} catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
}
......@@ -541,7 +543,8 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args);
},
onReady () {
this.$vm._isMounted = true;
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": {
......
......@@ -42,7 +42,8 @@ export function createPage (vueOptions) {
this.$vm.__call_hook('onLoad', args)
},
onReady () {
this.$vm._isMounted = true
this.$vm._isMounted = true
this.$vm.__call_hook('mounted')
this.$vm.__call_hook('onReady')
},
onUnload () {
......
......@@ -28,7 +28,7 @@ export function initHooks (mpOptions, hooks, delay = false) {
})
}
export function getData (vueOptions) {
export function getData (vueOptions) {
let data = vueOptions.data || {}
const methods = vueOptions.methods || {}
......@@ -36,7 +36,9 @@ export function getData (vueOptions) {
try {
data = data()
} catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data)
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data)
}
}
}
......
......@@ -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) {
......@@ -129,4 +130,4 @@ export default function requestComponentInfo ({
reqId,
res: result
}, pageVm.$page.id)
}
}
......@@ -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.
先完成此消息的编辑!
想要评论请 注册