提交 9be8526b 编写于 作者: fxy060608's avatar fxy060608

feat(v3): keep-alive

上级 75234f8f
......@@ -3173,7 +3173,7 @@ var serviceContext = (function () {
return invokeVmMethodWithoutArgs(ctx, 'pause')
},
seek (ctx, args) {
return invokeVmMethod(ctx, 'seek', args)
return invokeVmMethod(ctx, 'seek', args.position)
},
stop (ctx) {
return invokeVmMethodWithoutArgs(ctx, 'stop')
......@@ -3182,7 +3182,7 @@ var serviceContext = (function () {
return invokeVmMethod(ctx, 'sendDanmu', args)
},
playbackRate (ctx, args) {
return invokeVmMethod(ctx, 'playbackRate', args)
return invokeVmMethod(ctx, 'playbackRate', args.rate)
},
requestFullScreen (ctx, args) {
return invokeVmMethod(ctx, 'requestFullScreen', args)
......@@ -7999,7 +7999,7 @@ var serviceContext = (function () {
createMapContext: createMapContext$1
});
const RATES = [0.5, 0.8, 1.0, 1.25, 1.5];
const RATES = [0.5, 0.8, 1.0, 1.25, 1.5, 2.0];
function operateVideoPlayer$3 (videoId, pageVm, type, data) {
invokeMethod('operateVideoPlayer', videoId, pageVm, type, data);
......@@ -8021,8 +8021,8 @@ var serviceContext = (function () {
operateVideoPlayer$3(this.id, this.pageVm, 'stop');
}
seek (position) {
operateVideoPlayer$3(this.id, this.pageVm, 'seek', {
position
operateVideoPlayer$3(this.id, this.pageVm, 'seek', {
position
});
}
sendDanmu (args) {
......@@ -8032,12 +8032,12 @@ var serviceContext = (function () {
if (!~RATES.indexOf(rate)) {
rate = 1.0;
}
operateVideoPlayer$3(this.id, this.pageVm, 'playbackRate', {
rate
operateVideoPlayer$3(this.id, this.pageVm, 'playbackRate', {
rate
});
}
requestFullScreen () {
operateVideoPlayer$3(this.id, this.pageVm, 'requestFullScreen');
requestFullScreen (args = {}) {
operateVideoPlayer$3(this.id, this.pageVm, 'requestFullScreen', args);
}
exitFullScreen () {
operateVideoPlayer$3(this.id, this.pageVm, 'exitFullScreen');
......
......@@ -695,7 +695,13 @@ var uid = 0;
* directives subscribing to it.
*/
var Dep = function Dep () {
this.id = uid++;
// fixed by xxxxxx (nvue vuex)
/* eslint-disable no-undef */
if(typeof SharedObject !== 'undefined'){
this.id = SharedObject.uid++;
} else {
this.id = uid++;
}
this.subs = [];
};
......@@ -708,8 +714,8 @@ Dep.prototype.removeSub = function removeSub (sub) {
};
Dep.prototype.depend = function depend () {
if (Dep.target) {
Dep.target.addDep(this);
if (Dep.SharedObject.target) { // fixed by xxxxxx
Dep.SharedObject.target.addDep(this);
}
};
......@@ -730,17 +736,20 @@ Dep.prototype.notify = function notify () {
// The current target watcher being evaluated.
// This is globally unique because only one watcher
// can be evaluated at a time.
Dep.target = null;
var targetStack = [];
// fixed by xxxxxx (nvue shared vuex)
/* eslint-disable no-undef */
Dep.SharedObject = typeof SharedObject !== 'undefined' ? SharedObject : {};
Dep.SharedObject.target = null;
Dep.SharedObject.targetStack = [];
function pushTarget (target) {
targetStack.push(target);
Dep.target = target;
Dep.SharedObject.targetStack.push(target);
Dep.SharedObject.target = target;
}
function popTarget () {
targetStack.pop();
Dep.target = targetStack[targetStack.length - 1];
Dep.SharedObject.targetStack.pop();
Dep.SharedObject.target = Dep.SharedObject.targetStack[Dep.SharedObject.targetStack.length - 1];
}
/* */
......@@ -1019,7 +1028,7 @@ function defineReactive$$1 (
configurable: true,
get: function reactiveGetter () {
var value = getter ? getter.call(obj) : val;
if (Dep.target) {
if (Dep.SharedObject.target) { // fixed by xxxxxx
dep.depend();
if (childOb) {
childOb.dep.depend();
......@@ -4843,7 +4852,7 @@ function createComputedGetter (key) {
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) {
if (Dep.SharedObject.target) { // fixed by xxxxxx
watcher.depend();
}
return watcher.value
......
此差异已折叠。
......@@ -70,6 +70,17 @@ describe('codegen', () => {
'<current-user v-slot="{ user }">{{ user.firstName }}</current-user>',
`with(this){return _c('current-user',{attrs:{"_i":0},scopedSlots:_u([{key:"default",fn:function({ user }){return [_v((_$s(0,'t0',_s(user.firstName))))]}}])})}`
)
})
it('generate keep-alive', () => {
assertCodegen(
`<keep-alive exclude="componentWithStatus1"><component is="componentWithStatus"/></keep-alive>`,
`with(this){return _c('keep-alive',{attrs:{"exclude":"componentWithStatus1","_i":0}},[_c("componentWithStatus",{tag:"component",attrs:{"_i":1}})],1)}`
)
assertCodegen(
`<keep-alive :exclude="componentWithStatus1"><component :is="'componentWithStatus'+index"/></keep-alive>`,
`with(this){return _c('keep-alive',{attrs:{"exclude":_$s(0,'a-exclude',componentWithStatus1),"_i":0}},[_c(_$s(1,'is','componentWithStatus'+index),{tag:"component",attrs:{"_i":1}})],1)}`
)
})
})
/* eslint-enable quotes */
......@@ -45,6 +45,16 @@ describe('codegen', () => {
'<current-user v-slot="{ user }">{{ user.firstName }}</current-user>',
`with(this){return _c('current-user',{attrs:{"_i":0},scopedSlots:_u([{key:"default",fn:function({ user }){return [_v((_$g(0,'t0')))]}}])})}`
)
})
it('generate keep-alive', () => {
assertCodegen(
`<keep-alive exclude="componentWithStatus1"><component is="componentWithStatus"/></keep-alive>`,
`with(this){return _c('keep-alive',{attrs:{"exclude":"componentWithStatus1","_i":0}},[_c("componentWithStatus",{tag:"component",attrs:{"_i":1}})],1)}`
)
assertCodegen(
`<keep-alive :exclude="componentWithStatus1"><component :is="'componentWithStatus'+index"/></keep-alive>`,
`with(this){return _c('keep-alive',{attrs:{"exclude":_$g(0,'a-exclude'),"_i":0}},[_c(_$g(1,'is'),{tag:"component",attrs:{"_i":1}})],1)}`
)
})
})
/* eslint-enable quotes */
......@@ -576,7 +576,7 @@ describe('codegen', () => {
)
assertCodegen(
'<div :is="component1"></div>',
`with(this){return _c(component1,{tag:"div"})}`
`with(this){return _c(_$s(0,'is',component1),{tag:"div"})}`
)
// maybe a component and normalize type should be 1
assertCodegen(
......
......@@ -576,7 +576,7 @@ describe('codegen', () => {
)
assertCodegen(
'<div :is="component1"></div>',
`with(this){return _c(component1,{tag:"v-uni-view",attrs:{"_i":0}})}`
`with(this){return _c(_$g(0,'is'),{tag:"v-uni-view",attrs:{"_i":0}})}`
)
// maybe a component and normalize type should be 1
assertCodegen(
......
const compiler = require('../lib')
const res = compiler.compile(
`
<div :id="'a'+b">A{{ d | e | f }}B{{text}}C</div>
<keep-alive exclude="componentWithStatus1"><component is="componentWithStatus"/></keep-alive>
`, {
resourcePath: '/User/fxy/Documents/test.wxml',
isReservedTag: function (tag) {
......
......@@ -14,7 +14,11 @@ function no (a, b, c) {
}
function isBuiltInTag (tag) {
if (tag === 'slot' || tag === 'component') {
if (
tag === 'slot' ||
tag === 'component' ||
tag === 'keep-alive'
) {
return true
}
}
......@@ -48,11 +52,11 @@ function markStatic (node) {
}
delete node.attrs
}
if (node.type === 1) {
if (node.type === 1) {
delete node.staticClass
delete node.staticStyle
if (node.attrs && !isComponent(node.tag)) { // 移除静态属性
if (node.attrs && !isComponent(node.tag) && node.tag !== 'keep-alive') { // 移除静态属性
node.attrs = node.attrs.filter(attr => attr.name === ID || isVar(attr.value))
}
......
const {
ID,
C_IS,
V_IF,
V_FOR,
V_ELSE_IF,
......@@ -8,6 +9,15 @@ const {
const parseTextExpr = require('./text-parser')
function parseIs (el, genVar) {
if (!el.component) {
return
}
if (isVar(el.component)) {
el.component = genVar(C_IS, el.component)
}
}
function parseIf (el, createGenVar) {
if (!el.if) {
return
......@@ -60,6 +70,7 @@ function parseText (el, parent, state) {
}
module.exports = {
parseIs,
parseIf,
parseFor,
parseText,
......
const {
ID,
hasOwn
ID
} = require('../util')
const tags = require('../../../../uni-cli-shared/lib/tags')
const {
isComponent
} = require('../../util')
// 仅限 view 层
module.exports = function parseComponent (el) {
// 需要把自定义组件的 attrs, props 全干掉
if (el.tag && !hasOwn(tags, el.tag.replace('v-uni-', ''))) {
if (el.tag && isComponent(el.tag)) {
// 仅保留 ID
el.attrs && (el.attrs = el.attrs.filter(attr => attr.name === ID))
}
......
......@@ -14,6 +14,7 @@ const {
} = require('../util')
const {
parseIs,
parseIf,
parseFor,
parseText,
......@@ -82,6 +83,7 @@ function transformNode (el, parent, state) {
const genVar = createGenVar(el.attrsMap[ID])
parseIs(el, genVar)
parseFor(el, createGenVar)
parseKey(el)
......
......@@ -9,6 +9,8 @@ const ITERATOR2 = '$2'
const ITERATOR3 = '$3'
const SET_DATA = '_$s'
const GET_DATA = '_$g'
const C_IS = 'is'
const V_FOR = 'f'
const V_IF = 'i'
......@@ -190,7 +192,8 @@ function addHandler (el, name, value, important) {
el.plain = false
}
module.exports = {
module.exports = {
C_IS,
V_FOR,
V_IF,
V_ELSE_IF,
......
......@@ -8,7 +8,8 @@ const {
traverseNode
} = require('./util')
const {
const {
parseIs,
parseIf,
parseFor,
parseText,
......@@ -74,6 +75,8 @@ function transformNode (el, parent, state) {
const genVar = createGenVar(el.attrsMap[ID])
parseIs(el, genVar)
if (parseFor(el, createGenVar)) {
if (el.alias[0] === '{') { // <div><li v-for=" { a, b } in items"></li></div>
el.alias = '$item'
......
......@@ -183,9 +183,13 @@ const {
} = require('./h5')
function isComponent (tagName) {
if (tagName === 'block' || tagName === 'template') {
if (
tagName === 'block' ||
tagName === 'template' ||
tagName === 'keep-alive'
) {
return false
}
}
return !hasOwn(tags, getTagName(tagName.replace('v-uni-', '')))
}
......
......@@ -17,7 +17,9 @@ const {
parseComponents
} = require('./util')
function getDefineComponents(components) {
function getDefineComponents({
components
}) {
return components.map(({
name,
source
......@@ -93,7 +95,7 @@ module.exports = function(source, map) {
return `
import 'uni-pages'
function initView(){
${getStylesCode(this)}
${getStylesCode(this)}
injectStyles()
${getDefineComponents(parseComponents(source, traverse)).join('\n')}
UniViewJSBridge.publishHandler('webviewReady')
......
......@@ -10,7 +10,7 @@ const {
parseComponents
} = require('./util')
function genComponentCode (components) {
function genComponentCode(components) {
const importCode = []
const componentsCode = []
components.forEach(({
......@@ -24,12 +24,20 @@ function genComponentCode (components) {
return [importCode.join('\n'), componentsCode.join(',\n')]
}
function genCode (components, css = []) {
function genCode({
components,
options
}, css = []) {
const optionsCode = []
Object.keys(options).forEach(name => {
options[name] !== null && optionsCode.push(`${name}:${options[name]}`)
})
const [importComponentCode, componentsCode] = genComponentCode(components)
// TODO js 内引用 css
return `
${importComponentCode}
export default {
${optionsCode.length?(optionsCode.join(',')+','):''}
data(){
return {}
},
......@@ -40,7 +48,7 @@ export default {
`
}
module.exports = function (content, map) {
module.exports = function(content, map) {
this.cacheable && this.cacheable()
content = preprocessor.preprocess(content, jsPreprocessOptions.context, {
......
const parser = require('@babel/parser')
function parseComponents (content, traverse) {
function parseComponents(content, traverse) {
const {
state: {
options,
components
}
} = traverse(parser.parse(content, {
......@@ -15,9 +16,16 @@ function parseComponents (content, traverse) {
'classProperties'
]
}), {
components: []
components: [],
options: {
name: null,
inheritAttrs: null
}
})
return components
return {
components,
options
}
}
module.exports = {
......
......@@ -6,10 +6,27 @@ const {
} = require('./util')
function handleObjectExpression (declaration, path, state) {
if (state.options) { // name,inheritAttrs
Object.keys(state.options).forEach(name => {
const optionProperty = declaration.properties.filter(prop => {
return t.isObjectProperty(prop) &&
t.isIdentifier(prop.key) &&
prop.key.name === name
})[0]
if (optionProperty) {
if (t.isStringLiteral(optionProperty.value)) {
state.options[name] = JSON.stringify(optionProperty.value.value)
} else {
state.options[name] = optionProperty.value.value
}
}
})
}
const componentsProperty = declaration.properties.filter(prop => {
return t.isObjectProperty(prop) &&
t.isIdentifier(prop.key) &&
prop.key.name === 'components'
t.isIdentifier(prop.key) &&
prop.key.name === 'components'
})[0]
if (componentsProperty && t.isObjectExpression(componentsProperty.value)) {
......@@ -27,7 +44,8 @@ function handleObjectExpression (declaration, path, state) {
module.exports = function (ast, state = {
type: 'Component',
components: []
components: [],
options: {}
}) {
babelTraverse(ast, {
ExportDefaultDeclaration (path) {
......@@ -35,15 +53,15 @@ module.exports = function (ast, state = {
if (t.isObjectExpression(declaration)) { // export default {components:{}}
handleObjectExpression(declaration, path, state)
} else if (t.isCallExpression(declaration) &&
t.isMemberExpression(declaration.callee) &&
declaration.arguments.length === 1) { // export default Vue.extend({components:{}})
t.isMemberExpression(declaration.callee) &&
declaration.arguments.length === 1) { // export default Vue.extend({components:{}})
if (declaration.callee.object.name === 'Vue' && declaration.callee.property.name ===
'extend') {
'extend') {
handleObjectExpression(declaration.arguments[0], path, state)
}
} else if (t.isClassDeclaration(declaration) &&
declaration.decorators &&
declaration.decorators.length) { // export default @Component({components:{}}) class MyComponent extend Vue
declaration.decorators &&
declaration.decorators.length) { // export default @Component({components:{}}) class MyComponent extend Vue
const componentDecorator = declaration.decorators[0]
if (t.isCallExpression(componentDecorator.expression)) {
const args = componentDecorator.expression.arguments
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册