diff --git a/package.json b/package.json
index 83f4979..9756a7b 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,15 @@
"env": {
"browser": true
},
- "extends": "plugin:vue-libs/recommended"
+ "extends": "plugin:vue-libs/recommended",
+ "overrides": [
+ {
+ "files": ["test/*"],
+ "env": {
+ "jest": true
+ }
+ }
+ ]
},
"gitHooks": {
"pre-commit": "lint-staged"
diff --git a/src/index.js b/src/index.js
index 4409bd7..f2dd776 100644
--- a/src/index.js
+++ b/src/index.js
@@ -136,10 +136,14 @@ export default function wrap (Vue, Component) {
if (!wrapper._isMounted) {
// initialize attributes
const syncInitialAttributes = () => {
- wrapper.props = getInitialProps(camelizedPropsList)
- hyphenatedPropsList.forEach(key => {
- syncAttribute(this, key)
- })
+ const initialProps = getInitialProps(camelizedPropsList, this)
+ const isUndefined = key => initialProps[camelize(key)] === undefined
+ wrapper.props = initialProps
+ hyphenatedPropsList
+ .filter(key => this.hasAttribute(key) || isUndefined(key))
+ .forEach(key => {
+ syncAttribute(this, key)
+ })
}
if (isInitialized) {
diff --git a/src/utils.js b/src/utils.js
index 0834f03..f2f2601 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -8,10 +8,10 @@ export const hyphenate = str => {
return str.replace(hyphenateRE, '-$1').toLowerCase()
}
-export function getInitialProps (propsList) {
+export function getInitialProps (propsList, el) {
const res = {}
propsList.forEach(key => {
- res[key] = undefined
+ res[key] = el[key]
})
return res
}
diff --git a/test/fixtures/mounting-manually.html b/test/fixtures/mounting-manually.html
new file mode 100644
index 0000000..7ce426e
--- /dev/null
+++ b/test/fixtures/mounting-manually.html
@@ -0,0 +1,23 @@
+
+
diff --git a/test/test.js b/test/test.js
index 9423d7a..e098cb6 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,5 +1,7 @@
const launchPage = require('./setup')
+/* global el, els, MyElement */
+
test('properties', async () => {
const { page } = await launchPage(`properties`)
@@ -16,9 +18,9 @@ test('properties', async () => {
el.foo = 234
el.someProp = 'lol'
})
- const newFoo = await page.evaluate(() => el.vueComponent.foo)
+ const newFoo = await page.evaluate(() => el.vueComponent.foo)
expect(newFoo).toBe(234)
- const newBar = await page.evaluate(() => el.vueComponent.someProp)
+ const newBar = await page.evaluate(() => el.vueComponent.someProp)
expect(newBar).toBe('lol')
})
@@ -130,3 +132,26 @@ test('async', async () => {
return document.querySelectorAll('my-element')[2].shadowRoot.textContent
})).toMatch(`456 bar`)
})
+
+test('mounting manually', async () => {
+ const { page, logs } = await launchPage(`mounting-manually`)
+
+ // mounting programmatically
+ await page.evaluate(() => {
+ window.el = new MyElement()
+ window.el.foo = 234
+ window.el.setAttribute('some-prop', 'lol')
+ window.el.someProp = 'ignored as attribute takes precedence'
+ document.body.appendChild(window.el)
+ })
+
+ // props
+ const foo = await page.evaluate(() => el.vueComponent.foo)
+ expect(foo).toBe(234)
+ const bar = await page.evaluate(() => el.vueComponent.someProp)
+ expect(bar).toBe('lol')
+
+ // lifecycle
+ expect(logs).toContain('mounted with foo: 234')
+ expect(logs).toContain('mounted with someProp: lol')
+})