提交 2d30a925 编写于 作者: fxy060608's avatar fxy060608

feat(app-plus-nvue): add route

上级 e8cf7689
...@@ -6,7 +6,7 @@ root = true ...@@ -6,7 +6,7 @@ root = true
[*] [*]
charset = utf-8 charset = utf-8
indent_style = space indent_style = space
indent_size = 4 indent_size = 2
end_of_line = lf end_of_line = lf
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
......
import { createUniInstance } from './uni'; import { createUniInstance } from './uni';
function getWebviewStyle () { const ANI_SHOW = 'pop-in';
const ANI_DURATION = 300;
let id = 0;
function getId () {
return id++
}
function parseWebviewStyle (path) {
return { return {
titleNView: { titleNView: {
autoBackButton: true, autoBackButton: true,
titleText: 'titleText' titleText: 'titleText'
},
uniNView: {
path
} }
} }
} }
class Router {
constructor (routes, plus) { function initNavigateTo ({
this.routes = routes; plus,
this.plus = plus; __registerPage
this.id = 0; }) {
return function navigateTo (path, {
this.aniShow = plus.os.name === 'Android' ? 'slide-in-right' : 'pop-in'; animationType,
this.aniClose = 'pop-out'; animationDuration
this.aniDuration = 300; }) {
} const webview = plus.webview.open(
push ({
type,
path
} = {}) {
this.plus.webview.open(
'', '',
String(this.id++), String(getId()),
getWebviewStyle(), parseWebviewStyle(path),
this.aniShow, animationType || ANI_SHOW,
this.aniDuration, animationDuration || ANI_DURATION,
() => { () => {
console.log('show.callback'); console.log('show.callback');
}); });
__registerPage({
path,
webview
});
} }
}
function initRedirectTo () {
return function redirectTo (path) {
replace ({ }
type, }
path
} = {}) { let firstBackTime = 0;
function initNavigateBack ({
plus,
getCurrentPages
}) {
return function navigateBack (delta, {
animationType,
animationDuration
}) {
const pages = getCurrentPages();
const len = pages.length - 1;
const page = pages[len];
if (page.$meta.isQuit) {
if (!firstBackTime) {
firstBackTime = Date.now();
plus.nativeUI.toast('再按一次退出应用');
setTimeout(() => {
firstBackTime = null;
}, 2000);
} else if (Date.now() - firstBackTime < 2000) {
plus.runtime.quit();
}
} else {
pages.splice(len, 1);
if (animationType) {
page.$getAppWebview().close(animationType, animationDuration || ANI_DURATION);
} else {
page.$getAppWebview().close('auto');
}
}
}
}
function initSwitchTab (path) {
return function switchTab () {
} }
}
function initReLaunch () {
return function reLaunch (path) {
go (delta) { }
}
function initRouter (instanceContext) {
return {
navigateTo: initNavigateTo(instanceContext),
redirectTo: initRedirectTo(instanceContext),
navigateBack: initNavigateBack(instanceContext),
switchTab: initSwitchTab(instanceContext),
reLaunch: initReLaunch(instanceContext)
}
}
class Router {
constructor (instanceContext) {
this.router = initRouter(instanceContext);
}
push ({
type,
path,
animationType,
animationDuration
} = {}) {
this.router[type](path, {
animationType,
animationDuration
});
}
go (delta, {
animationType,
animationDuration
} = {}) {
delta = Math.abs(parseInt(delta) || 1);
this.router.navigateBack(delta, {
animationType,
animationDuration
});
} }
} }
...@@ -52,15 +143,27 @@ function getApp () { ...@@ -52,15 +143,27 @@ function getApp () {
return appCtx return appCtx
} }
function registerApp (appVm, routes, plus) { function initListeners ({
plus
}) {
plus.key.addEventListener('backbutton', () => {
appCtx.$router.go(-1);
});
}
function registerApp (appVm, instanceContext) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] registerApp`);
}
appCtx = appVm; appCtx = appVm;
appCtx.$router = new Router(routes, plus); appCtx.$router = new Router(instanceContext);
initListeners(instanceContext);
} }
const pageVms = []; const pages = [];
function getCurrentPages () { function getCurrentPages () {
return pageVms return pages
} }
/** /**
* @param {Object} pageVm * @param {Object} pageVm
...@@ -80,55 +183,78 @@ function getCurrentPages () { ...@@ -80,55 +183,78 @@ function getCurrentPages () {
* *
* *
*/ */
function registerPage (pageVm) {
pageVms.push(pageVm); function registerPage ({
vm,
path,
webview
}, instanceContext) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] registerPage`, path, webview.id);
}
pages.push({
route: path.slice(1),
$getAppWebview () {
return webview
},
$meta: instanceContext.__uniRoutes.find(route => route.path === path).meta,
$vm: vm
});
} }
const uniConfig = Object.create(null); const uniConfig = Object.create(null);
const uniRoutes = []; const uniRoutes = [];
function parseRoutes (config) { function parseRoutes (config) {
uniRoutes.length = 0; uniRoutes.length = 0;
/* eslint-disable no-mixed-operators */ /* eslint-disable no-mixed-operators */
const tabBarList = (config.tabBar && config.tabBar.list || []).map(item => item.pagePath); const tabBarList = (config.tabBar && config.tabBar.list || []).map(item => item.pagePath);
Object.keys(config.page).forEach(function (pagePath) { Object.keys(config.page).forEach(function (pagePath) {
const isTabBar = tabBarList.indexOf(pagePath) !== -1;
const isQuit = isTabBar || (config.pages[0] === pagePath);
uniRoutes.push({ uniRoutes.push({
path: '/' + pagePath, path: '/' + pagePath,
meta: { meta: {
isTabBar: tabBarList.indexOf(pagePath) !== -1 isQuit,
isTabBar
} }
}); });
}); });
} }
function registerConfig (config) { function registerConfig (config) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] registerConfig`);
}
Object.assign(uniConfig, config); Object.assign(uniConfig, config);
parseRoutes(uniConfig); parseRoutes(uniConfig);
} }
function createInstanceContext ({ function createInstanceContext (instanceContext) {
weex, const {
WeexPlus weex,
}) { WeexPlus
} = instanceContext;
const plus = new WeexPlus(weex); const plus = new WeexPlus(weex);
return { return {
__uniConfig: uniConfig, __uniConfig: uniConfig,
__uniRoutes: uniRoutes, __uniRoutes: uniRoutes,
__registerConfig (config) { __registerConfig (config) {
registerConfig(config); registerConfig(config, instanceContext);
}, },
__registerApp (appVm) { __registerApp (appVm) {
registerApp(appVm, uniRoutes, plus); registerApp(appVm, instanceContext);
}, },
__registerPage (pageVm) { __registerPage (page) {
registerPage(pageVm); registerPage(page, instanceContext);
}, },
plus,
uni: createUniInstance( uni: createUniInstance(
weex, weex,
plus, plus,
__uniConfig, uniConfig,
__uniRoutes, uniRoutes,
getApp, getApp,
getCurrentPages getCurrentPages
), ),
......
...@@ -1136,24 +1136,54 @@ function createValidator (type) { ...@@ -1136,24 +1136,54 @@ function createValidator (type) {
} }
} }
function createProtocol (type) { function createProtocol (type, extras = {}) {
return { return Object.assign({
url: { url: {
type: String, type: String,
required: true, required: true,
validator: createValidator(type) validator: createValidator(type)
} }
}, extras)
}
function createAnimationProtocol (animationTypes) {
return {
animationType: {
type: String,
validator (type) {
if (type && animationTypes.indexOf(type) === -1) {
return '`' + type + '` is not supported for `animationType` (supported values are: `' + animationTypes.join(
'`|`') + '`)'
}
}
},
animationDuration: {
type: Number
}
} }
} }
const redirectTo = createProtocol('redirectTo'); const redirectTo = createProtocol('redirectTo');
const reLaunch = createProtocol('reLaunch'); const reLaunch = createProtocol('reLaunch');
const navigateTo = createProtocol('navigateTo'); const navigateTo = createProtocol('navigateTo', createAnimationProtocol(
[
'slide-in-right',
'slide-in-left',
'slide-in-top',
'slide-in-bottom',
'fade-in',
'zoom-out',
'zoom-fade-out',
'pop-in',
'none'
]
));
const switchTab = createProtocol('switchTab'); const switchTab = createProtocol('switchTab');
const navigateBack = { const navigateBack = Object.assign({
delta: { delta: {
type: Number, type: Number,
validator (delta, params) { validator (delta, params) {
...@@ -1161,7 +1191,19 @@ const navigateBack = { ...@@ -1161,7 +1191,19 @@ const navigateBack = {
params.delta = Math.min(getCurrentPages().length - 1, delta); params.delta = Math.min(getCurrentPages().length - 1, delta);
} }
} }
}; }, createAnimationProtocol(
[
'slide-out-right',
'slide-out-left',
'slide-out-top',
'slide-out-bottom',
'fade-out',
'zoom-in',
'zoom-fade-in',
'pop-out',
'none'
]
));
var require_context_module_0_19 = /*#__PURE__*/Object.freeze({ var require_context_module_0_19 = /*#__PURE__*/Object.freeze({
redirectTo: redirectTo, redirectTo: redirectTo,
...@@ -1735,6 +1777,8 @@ function hasLifecycleHook (vueOptions = {}, hook) { ...@@ -1735,6 +1777,8 @@ function hasLifecycleHook (vueOptions = {}, hook) {
function onAppRoute (type, { function onAppRoute (type, {
url, url,
delta, delta,
animationType,
animationDuration,
from = 'navigateBack', from = 'navigateBack',
detail detail
} = {}) { } = {}) {
...@@ -1749,7 +1793,9 @@ function onAppRoute (type, { ...@@ -1749,7 +1793,9 @@ function onAppRoute (type, {
case 'navigateTo': case 'navigateTo':
router.push({ router.push({
type, type,
path: url path: url,
animationType,
animationDuration
}); });
break break
case 'navigateBack': case 'navigateBack':
...@@ -1767,7 +1813,10 @@ function onAppRoute (type, { ...@@ -1767,7 +1813,10 @@ function onAppRoute (type, {
if (delta > 1) { if (delta > 1) {
router._$delta = delta; router._$delta = delta;
} }
router.go(-delta); router.go(-delta, {
animationType,
animationDuration
});
} }
break break
case 'reLaunch': case 'reLaunch':
......
...@@ -75,24 +75,54 @@ function createValidator (type) { ...@@ -75,24 +75,54 @@ function createValidator (type) {
} }
} }
function createProtocol (type) { function createProtocol (type, extras = {}) {
return { return Object.assign({
url: { url: {
type: String, type: String,
required: true, required: true,
validator: createValidator(type) validator: createValidator(type)
} }
}, extras)
}
function createAnimationProtocol (animationTypes) {
return {
animationType: {
type: String,
validator (type) {
if (type && animationTypes.indexOf(type) === -1) {
return '`' + type + '` is not supported for `animationType` (supported values are: `' + animationTypes.join(
'`|`') + '`)'
}
}
},
animationDuration: {
type: Number
}
} }
} }
export const redirectTo = createProtocol('redirectTo') export const redirectTo = createProtocol('redirectTo')
export const reLaunch = createProtocol('reLaunch') export const reLaunch = createProtocol('reLaunch')
export const navigateTo = createProtocol('navigateTo') export const navigateTo = createProtocol('navigateTo', createAnimationProtocol(
[
'slide-in-right',
'slide-in-left',
'slide-in-top',
'slide-in-bottom',
'fade-in',
'zoom-out',
'zoom-fade-out',
'pop-in',
'none'
]
))
export const switchTab = createProtocol('switchTab') export const switchTab = createProtocol('switchTab')
export const navigateBack = { export const navigateBack = Object.assign({
delta: { delta: {
type: Number, type: Number,
validator (delta, params) { validator (delta, params) {
...@@ -100,4 +130,16 @@ export const navigateBack = { ...@@ -100,4 +130,16 @@ export const navigateBack = {
params.delta = Math.min(getCurrentPages().length - 1, delta) params.delta = Math.min(getCurrentPages().length - 1, delta)
} }
} }
} }, createAnimationProtocol(
[
'slide-out-right',
'slide-out-left',
'slide-out-top',
'slide-out-bottom',
'fade-out',
'zoom-in',
'zoom-fade-in',
'pop-out',
'none'
]
))
...@@ -5,6 +5,8 @@ import { ...@@ -5,6 +5,8 @@ import {
function onAppRoute (type, { function onAppRoute (type, {
url, url,
delta, delta,
animationType,
animationDuration,
from = 'navigateBack', from = 'navigateBack',
detail detail
} = {}) { } = {}) {
...@@ -19,7 +21,9 @@ function onAppRoute (type, { ...@@ -19,7 +21,9 @@ function onAppRoute (type, {
case 'navigateTo': case 'navigateTo':
router.push({ router.push({
type, type,
path: url path: url,
animationType,
animationDuration
}) })
break break
case 'navigateBack': case 'navigateBack':
...@@ -37,7 +41,10 @@ function onAppRoute (type, { ...@@ -37,7 +41,10 @@ function onAppRoute (type, {
if (delta > 1) { if (delta > 1) {
router._$delta = delta router._$delta = delta
} }
router.go(-delta) router.go(-delta, {
animationType,
animationDuration
})
} }
break break
case 'reLaunch': case 'reLaunch':
......
function getWebviewStyle () {
return {
titleNView: {
autoBackButton: true,
titleText: 'titleText'
}
}
}
export default class Router {
constructor (routes, plus) {
this.routes = routes
this.plus = plus
this.id = 0
this.aniShow = plus.os.name === 'Android' ? 'slide-in-right' : 'pop-in'
this.aniClose = 'pop-out'
this.aniDuration = 300
}
push ({
type,
path
} = {}) {
this.plus.webview.open(
'',
String(this.id++),
getWebviewStyle(),
this.aniShow,
this.aniDuration,
() => {
console.log('show.callback')
})
}
replace ({
type,
path
} = {}) {
}
go (delta) {
}
}
import initNavigateTo from './navigate-to'
import initRedirectTo from './redirect-to'
import initNavigateBack from './navigate-back'
import initSwitchTab from './switch-tab'
import initReLaunch from './re-launch'
function initRouter (instanceContext) {
return {
navigateTo: initNavigateTo(instanceContext),
redirectTo: initRedirectTo(instanceContext),
navigateBack: initNavigateBack(instanceContext),
switchTab: initSwitchTab(instanceContext),
reLaunch: initReLaunch(instanceContext)
}
}
export default class Router {
constructor (instanceContext) {
this.router = initRouter(instanceContext)
}
push ({
type,
path,
animationType,
animationDuration
} = {}) {
this.router[type](path, {
animationType,
animationDuration
})
}
go (delta, {
animationType,
animationDuration
} = {}) {
delta = Math.abs(parseInt(delta) || 1)
this.router.navigateBack(delta, {
animationType,
animationDuration
})
}
}
import {
ANI_DURATION
} from './util'
let firstBackTime = 0
export default function initNavigateBack ({
plus,
getCurrentPages
}) {
return function navigateBack (delta, {
animationType,
animationDuration
}) {
const pages = getCurrentPages()
const len = pages.length - 1
const page = pages[len]
if (page.$meta.isQuit) {
if (!firstBackTime) {
firstBackTime = Date.now()
plus.nativeUI.toast('再按一次退出应用')
setTimeout(() => {
firstBackTime = null
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
plus.runtime.quit()
}
} else {
pages.splice(len, 1)
if (animationType) {
page.$getAppWebview().close(animationType, animationDuration || ANI_DURATION)
} else {
page.$getAppWebview().close('auto')
}
}
}
}
import {
getId,
ANI_SHOW,
ANI_DURATION,
parseWebviewStyle
} from './util'
export default function initNavigateTo ({
plus,
__registerPage
}) {
return function navigateTo (path, {
animationType,
animationDuration
}) {
const webview = plus.webview.open(
'',
String(getId()),
parseWebviewStyle(path),
animationType || ANI_SHOW,
animationDuration || ANI_DURATION,
() => {
console.log('show.callback')
})
__registerPage({
path,
webview
})
}
}
export default function initReLaunch () {
return function reLaunch (path) {
}
}
export default function initRedirectTo () {
return function redirectTo (path) {
}
}
export default function initSwitchTab (path) {
return function switchTab () {
}
}
export const ANI_SHOW = 'pop-in'
export const ANI_DURATION = 300
let id = 0
export function getId () {
return id++
}
export function parseWebviewStyle (path) {
return {
titleNView: {
autoBackButton: true,
titleText: 'titleText'
},
uniNView: {
path
}
}
}
import Router from 'uni-platform/service/uni/router' import Router from 'uni-platform/service/uni/router/index'
let appCtx let appCtx
...@@ -6,7 +6,19 @@ export function getApp () { ...@@ -6,7 +6,19 @@ export function getApp () {
return appCtx return appCtx
} }
export function registerApp (appVm, routes, plus) { function initListeners ({
plus
}) {
plus.key.addEventListener('backbutton', () => {
appCtx.$router.go(-1)
})
}
export function registerApp (appVm, instanceContext) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] registerApp`)
}
appCtx = appVm appCtx = appVm
appCtx.$router = new Router(routes, plus) appCtx.$router = new Router(instanceContext)
initListeners(instanceContext)
} }
...@@ -2,21 +2,27 @@ export const uniConfig = Object.create(null) ...@@ -2,21 +2,27 @@ export const uniConfig = Object.create(null)
export const uniRoutes = [] export const uniRoutes = []
function parseRoutes (config) { function parseRoutes (config) {
uniRoutes.length = 0 uniRoutes.length = 0
/* eslint-disable no-mixed-operators */ /* eslint-disable no-mixed-operators */
const tabBarList = (config.tabBar && config.tabBar.list || []).map(item => item.pagePath) const tabBarList = (config.tabBar && config.tabBar.list || []).map(item => item.pagePath)
Object.keys(config.page).forEach(function (pagePath) { Object.keys(config.page).forEach(function (pagePath) {
const isTabBar = tabBarList.indexOf(pagePath) !== -1
const isQuit = isTabBar || (config.pages[0] === pagePath)
uniRoutes.push({ uniRoutes.push({
path: '/' + pagePath, path: '/' + pagePath,
meta: { meta: {
isTabBar: tabBarList.indexOf(pagePath) !== -1 isQuit,
isTabBar
} }
}) })
}) })
} }
export function registerConfig (config) { export function registerConfig (config) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] registerConfig`)
}
Object.assign(uniConfig, config) Object.assign(uniConfig, config)
parseRoutes(uniConfig) parseRoutes(uniConfig)
} }
...@@ -18,28 +18,30 @@ import { ...@@ -18,28 +18,30 @@ import {
createUniInstance createUniInstance
} from './uni' } from './uni'
export function createInstanceContext ({ export function createInstanceContext (instanceContext) {
weex, const {
WeexPlus weex,
}) { WeexPlus
} = instanceContext
const plus = new WeexPlus(weex) const plus = new WeexPlus(weex)
return { return {
__uniConfig: uniConfig, __uniConfig: uniConfig,
__uniRoutes: uniRoutes, __uniRoutes: uniRoutes,
__registerConfig (config) { __registerConfig (config) {
registerConfig(config) registerConfig(config, instanceContext)
}, },
__registerApp (appVm) { __registerApp (appVm) {
registerApp(appVm, uniRoutes, plus) registerApp(appVm, instanceContext)
}, },
__registerPage (pageVm) { __registerPage (page) {
registerPage(pageVm) registerPage(page, instanceContext)
}, },
plus,
uni: createUniInstance( uni: createUniInstance(
weex, weex,
plus, plus,
__uniConfig, uniConfig,
__uniRoutes, uniRoutes,
getApp, getApp,
getCurrentPages getCurrentPages
), ),
......
const pageVms = [] const pages = []
export function getCurrentPages () { export function getCurrentPages () {
return pageVms return pages
} }
/** /**
* @param {Object} pageVm * @param {Object} pageVm
...@@ -21,6 +21,21 @@ export function getCurrentPages () { ...@@ -21,6 +21,21 @@ export function getCurrentPages () {
* *
* *
*/ */
export function registerPage (pageVm) {
pageVms.push(pageVm) export function registerPage ({
vm,
path,
webview
}, instanceContext) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] registerPage`, path, webview.id)
}
pages.push({
route: path.slice(1),
$getAppWebview () {
return webview
},
$meta: instanceContext.__uniRoutes.find(route => route.path === path).meta,
$vm: vm
})
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册