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

feat(v3): mp runtime

上级 5e9f0482
......@@ -4181,6 +4181,9 @@ function updateChildComponent (
vm.$options.propsData = propsData;
}
// fixed by xxxxxx update properties(mp runtime)
vm._$updateProperties && vm._$updateProperties(vm);
// update listeners
listeners = listeners || emptyObject;
var oldListeners = vm.$options._parentListeners;
......
......@@ -13,7 +13,7 @@ migrate('/Users/fxy/Downloads/wa-vantui_1.1')
// transformTemplate
// } = require('../lib/mp-weixin/transform/template-transformer')
// console.log(transformTemplate(
// `<view wx:for="{{ columns }}" wx:for-item="item1" wx:key="title"/>`, {
// `<view wx:for="{{ columns }}" wx:for-item="item1" wx:key="item1"/>`, {
// filename: 'index'
// }
// ))
......@@ -24,7 +24,7 @@ describe('wxml:compiler', () => {
`<view v-for="(item1,index) in (isSimple(columns) ? [columns] : columns)" :key="item1.index"></view>`
)
assertCodegen(
'<view wx:for="{{ columns }}" wx:for-item="item1" wx:key="*this"/>',
'<view wx:for="{{ columns }}" wx:for-item="item1" wx:key="item1"/>',
`<view v-for="(item1,index) in (columns)" :key="item1"></view>`
)
assertCodegen(
......
......@@ -20,6 +20,7 @@ module.exports = function migrate(input, out, options = {
}
const [files, assets] = migrater.transform(input, out, options)
files.forEach(file => {
migrater.patch.vue(file)
console.log(`write: ${file.path}`)
fs.outputFileSync(file.path, file.content)
})
......@@ -30,7 +31,7 @@ module.exports = function migrate(input, out, options = {
if (typeof asset === 'string') {
const src = path.resolve(input, asset)
const dest = path.resolve(out, asset.replace(styleExtname, '.css'))
if (!migrater.patch(src, dest)) {
if (!migrater.patch.asset(src, dest)) {
if (
needCopy || (
asset.indexOf(styleExtname) !== -1 &&
......
......@@ -4,40 +4,52 @@ const {
normalizePath
} = require('./util')
const VANTS = [{ // wxs array.constructor
const VANT_ASSETS = [{ // wxs array.constructor
test(src) {
return src.indexOf('array.wxs') !== -1
},
source(code) {
return code.replace(`array.constructor === 'Array'`, 'Array.isArray(array)')
}
}, { // vue $options conflicts
test(src) {
return normalizePath(src).indexOf('mixins/observer/index.js') !== -1
},
source(code) {
return code.replace(`options.methods.$options`, `options.methods.$getVantOptions`)
}
}, { // vue $options conflicts
test(src) {
return normalizePath(src).indexOf('mixins/observer/behavior.js') !== -1
}]
const PATCH_ASSETS = [
...VANT_ASSETS
]
const VANT_VUES = [{
test(file) {
return normalizePath(file.path).indexOf('/image/index.vue') !== -1
},
source(code) {
return code.replace(`!this.$options`, `!this.$getVantOptions`)
.replace(`this.$options()`, `this.$getVantOptions()`)
// onLoad 与 onError 是生命周期函数名,需要替换为其他
return code.replace(/onLoad/g, 'onImageLoad')
.replace(/onError/g, 'onImageError')
}
}]
}]
const PATCHS = [
...VANTS
const PATCH_VUES = [
...VANT_VUES
]
module.exports = function patch(src, dest) {
const options = PATCHS.find(patch => patch.test(src))
function patchAsset(src, dest) {
const options = PATCH_ASSETS.find(patch => patch.test(src))
if (options) {
console.log(`write: ${dest}`)
fs.outputFileSync(dest, options.source(fs.readFileSync(src).toString()))
return true
}
return false
}
function patchVue(file) {
const options = PATCH_VUES.find(patch => patch.test(file))
if (options) {
file.content = options.source(file.content)
}
}
module.exports = {
vue: patchVue,
asset: patchAsset
}
......@@ -64,10 +64,14 @@ function transformFor(attribs) {
//处理 wx:for-item="index"
)
attribs['v-for'] = `(${vItem},${vIndex}) in (${parseMustache(vFor)})`
if (vKey) {
vKey === '*this' ? (vKey = vItem) : (vKey = vItem + '.' + vKey)
attribs[':key'] = vKey
attribs['v-for'] = `(${vItem},${vIndex}) in (${parseMustache(vFor)})`
if (vKey) {
if (vKey === '*this') {
vKey = vItem
} else if (vKey !== vItem) {
vKey = vItem + '.' + vKey
}
attribs[':key'] = vKey
}
delete attribs[FOR.for]
......
import Vue from 'vue';
function parseData (data, vueComponentOptions) {
if (!data) {
return
......@@ -397,6 +399,34 @@ function proxy (target, sourceKey, key) {
Object.defineProperty(target, key, sharedPropertyDefinition);
}
function setDataByExprPath (exprPath, value, data) {
const keys = exprPath.replace(/\[(\d+?)\]/g, '.$1').split('.');
keys.reduce((obj, key, idx) => {
if (idx === keys.length - 1) {
obj[key] = value;
} else {
if (typeof obj[key] === 'undefined') {
obj[key] = {};
}
return obj[key]
}
}, data);
return keys.length === 1
}
function setData (data, callback) {
if (!isPlainObject(data)) {
return
}
Object.keys(data).forEach(key => {
if (setDataByExprPath(key, data[key], this.data)) {
!hasOwn(this, key) && proxy(this, SOURCE_KEY, key);
}
});
this.$forceUpdate();
isFn(callback) && this.$nextTick(callback);
}
const PROP_DEFAULT_VALUES = {
String: '',
Number: 0,
......@@ -474,24 +504,24 @@ function initProperties (vm, instanceData) {
return value
},
set (newVal) {
const oldVal = value;
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
if (observer) {
const oldVal = value;
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
value = newVal;
observe(observer, vm, newVal, oldVal);
} else {
value = newVal;
}
// 触发渲染
vm.$forceUpdate();
}
});
}
}
function updateProperties (vm) {
const properties = vm.$options.mpOptions.properties;
const properties = vm.$options.mpOptions && vm.$options.mpOptions.properties;
const propsData = vm.$options.propsData;
if (propsData && properties) {
Object.keys(properties).forEach(key => {
......@@ -526,20 +556,7 @@ function initState (vm) {
properties: propertyDefinition
});
vm.setData = (data, callback) => {
// TODO data path: array[0].text,object.text
if (!isPlainObject(data)) {
return
}
Object.keys(data).forEach(key => {
vm.data[key] = data[key];
if (!hasOwn(vm, key)) {
proxy(vm, SOURCE_KEY, key);
}
});
vm.$forceUpdate();
isFn(callback) && vm.$nextTick(callback);
};
vm.setData = setData;
initProperties(vm, instanceData);
......@@ -568,6 +585,8 @@ function initMethods (vm) {
/* eslint-disable no-mixed-operators */
return vm._$relationNodes && vm._$relationNodes[relationKey] || []
};
vm._$updateProperties = updateProperties;
}
function initRelationHandlers (type, handler, target, ctx, handlerCtx) {
......@@ -696,9 +715,6 @@ var polyfill = {
mounted () {
handleObservers(this);
},
beforeUpdate () {
updateProperties(this);
},
beforeDestroy () {
handleRelations(this, 'unlinked');
}
......@@ -742,6 +758,9 @@ function Component (options) {
function Behavior (options) {
return options
}
}
const nextTick = Vue.nextTick;
export { Behavior, Component, Page, getDate, getRegExp };
export default uni;
export { Behavior, Component, Page, getDate, getRegExp, nextTick };
......@@ -21,8 +21,9 @@ const runtimePath = '@dcloudio/uni-mp-weixin/dist/mp.js'
function getProvides () {
return {
'__f__': [path.resolve(__dirname, '../format-log.js'), 'default'],
'wx': ['@dcloudio/uni-app-plus/dist/uni.js', 'default'],
'Page': [runtimePath, 'Page'],
'wx': [runtimePath, 'default'],
'wx.nextTick': [runtimePath, 'nextTick'],
'Page': [runtimePath, 'Page'],
'Component': [runtimePath, 'Component'],
'Behavior': [runtimePath, 'Behavior'],
'getDate': [runtimePath, 'getDate'],
......
import Vue from 'vue'
import {
parsePage
} from './parser/page-parser'
......@@ -30,4 +32,8 @@ export function Component (options) {
export function Behavior (options) {
return options
}
}
export const nextTick = Vue.nextTick
export default uni
......@@ -13,11 +13,7 @@ import {
import {
handleObservers
} from './observers'
import {
updateProperties
} from './state/properties'
} from './observers'
export default {
beforeCreate () {
......@@ -31,9 +27,6 @@ export default {
mounted () {
handleObservers(this)
},
beforeUpdate () {
updateProperties(this)
},
beforeDestroy () {
handleRelations(this, 'unlinked')
}
......
import {
updateProperties
} from './state/properties'
export function initMethods (vm) {
const oldEmit = vm.$emit
vm.triggerEvent = (eventName, detail, options) => {
......@@ -18,4 +22,6 @@ export function initMethods (vm) {
/* eslint-disable no-mixed-operators */
return vm._$relationNodes && vm._$relationNodes[relationKey] || []
}
vm._$updateProperties = updateProperties
}
import {
isFn,
hasOwn,
isPlainObject
} from 'uni-shared'
import {
proxy
} from './proxy'
import {
SOURCE_KEY
} from '../../constants'
function setDataByExprPath (exprPath, value, data) {
const keys = exprPath.replace(/\[(\d+?)\]/g, '.$1').split('.')
keys.reduce((obj, key, idx) => {
if (idx === keys.length - 1) {
obj[key] = value
} else {
if (typeof obj[key] === 'undefined') {
obj[key] = {}
}
return obj[key]
}
}, data)
return keys.length === 1
}
export function setData (data, callback) {
if (!isPlainObject(data)) {
return
}
Object.keys(data).forEach(key => {
if (setDataByExprPath(key, data[key], this.data)) {
!hasOwn(this, key) && proxy(this, SOURCE_KEY, key)
}
})
this.$forceUpdate()
isFn(callback) && this.$nextTick(callback)
}
import {
isFn,
hasOwn,
isPlainObject
} from 'uni-shared'
import {
SOURCE_KEY
} from '../../constants'
......@@ -12,6 +6,10 @@ import {
proxy
} from './proxy'
import {
setData
} from './data'
import {
initProperties
} from './properties'
......@@ -35,20 +33,7 @@ export function initState (vm) {
properties: propertyDefinition
})
vm.setData = (data, callback) => {
// TODO data path: array[0].text,object.text
if (!isPlainObject(data)) {
return
}
Object.keys(data).forEach(key => {
vm.data[key] = data[key]
if (!hasOwn(vm, key)) {
proxy(vm, SOURCE_KEY, key)
}
})
vm.$forceUpdate()
isFn(callback) && vm.$nextTick(callback)
}
vm.setData = setData
initProperties(vm, instanceData)
......
......@@ -80,24 +80,24 @@ export function initProperties (vm, instanceData) {
return value
},
set (newVal) {
const oldVal = value
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
if (observer) {
const oldVal = value
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
value = newVal
observe(observer, vm, newVal, oldVal)
} else {
value = newVal
}
// 触发渲染
vm.$forceUpdate()
}
})
}
}
export function updateProperties (vm) {
const properties = vm.$options.mpOptions.properties
const properties = vm.$options.mpOptions && vm.$options.mpOptions.properties
const propsData = vm.$options.propsData
if (propsData && properties) {
Object.keys(properties).forEach(key => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册