Kocal / vue-web-extension

🛠️ A Vue CLI 3+ preset (previously a Vue CLI 2 boilerplate) for quickly starting a web extension with Vue, Babel, ESLint and more!
https://vue-web-extension.netlify.app/
MIT License
1.58k stars 167 forks source link

Can I have a vue app living inside the page? #383

Closed ralyodio closed 5 years ago

ralyodio commented 5 years ago

It seems the only vue app that is supported with this project is the options page and the popup.

I want a vue app inside the page itself. I have a control panel that I want to interact with the page, but it seems the only place to put the code is in background.js

Can I use vue.js inside background.js? How would I create an app or html?

Kocal commented 5 years ago

You can use content scripts to interact with your page.

ralyodio commented 5 years ago

Do we have an example of instantiating a vue app from a content script?

ralyodio commented 5 years ago

I've tried this but all i get is a red box. no vue app:

import Vue from 'vue';
import store from './store';
import App from './popup/App';
import router from './popup/router';

global.browser = require('webextension-polyfill');

const el = document.createElement('div');
el.style.border = '10px solid red';
el.style.width = '10rem';
el.style.height = '10rem';
el.id = 'lba-app';
document.body.appendChild(el);
// alert(`Hello ${store.getters.foo}!`);

/* eslint-disable no-new */
new Vue({
  el: '#lba-app',
  store,
  router,
  render: h => h(App),
});
Kocal commented 5 years ago

Weird, can you try to mount the Vue app directly on the component (and not with a selector):

new Vue({
  el: el,
  // ...
});

or shorter:

new Vue({
  el,
  //...
});
mathewcst commented 5 years ago

@chovy did you get it working or some updates that you can share? I'm trying to create a content script with Vue, just found this project and it would be nice to have some example on how to use this with content scripts.

ralyodio commented 5 years ago

The problem I see is you need to specify an html page like content.html which loads the app container, the app.js and the css. All we get is a javascript file for content scripts, no way to load html. So I think if you really wanted to make it work you need to add the css and js into the page using vanilla js. I haven't gotten that far yet.

emmanuelmcd commented 5 years ago

@chovy Any updates ?

ralyodio commented 5 years ago

yeah. i got it working by using js to add the <div id="app"> I have to use vanilla css though.

emmanuelmcd commented 5 years ago

@chovy Can you give me an example of the content script your using please ? I don't see how to properly mount vue App in the DOM thanks to content script.

emmanuelmcd commented 5 years ago

I finally got it working with that:

// content.js
import Vue from 'vue';
import store from './store';
import App from './popup/App';
import router from './popup/router';

const app = document.createElement('div');
app.id = 'app';
document.body.prepend(app);

/* eslint-disable no-new */
new Vue({
    el: '#app',
    store,
    router,
    render: h => h(App),
});

But at this point the style doesn't work so you just have to set this in your manifest.json:

"content_scripts": [{
    "js": ["content.js"],
    "css": ["content.css"]
  }],
ralyodio commented 5 years ago

i'm abandoning this chrome extension. Easier to use a bookmarklet.

jianwu commented 4 years ago

I finally got it working with that:

// content.js
import Vue from 'vue';
import store from './store';
import App from './popup/App';
import router from './popup/router';

const app = document.createElement('div');
app.id = 'app';
document.body.prepend(app);

/* eslint-disable no-new */
new Vue({
    el: '#app',
    store,
    router,
    render: h => h(App),
});

But at this point the style doesn't work so you just have to set this in your manifest.json:

"content_scripts": [{
    "js": ["content.js"],
    "css": ["content.css"]
  }],

That actually works for me. Could somebody file a PR to include this into the boilerplate?

jacobcoro commented 4 years ago

I finally got it working with that:

// content.js
import Vue from 'vue';
import store from './store';
import App from './popup/App';
import router from './popup/router';

const app = document.createElement('div');
app.id = 'app';
document.body.prepend(app);

/* eslint-disable no-new */
new Vue({
    el: '#app',
    store,
    router,
    render: h => h(App),
});

But at this point the style doesn't work so you just have to set this in your manifest.json:

"content_scripts": [{
    "js": ["content.js"],
    "css": ["content.css"]
  }],

That actually works for me. Could somebody file a PR to include this into the boilerplate?

but if you are doing this way, can you start the content script programmatically or just declaratively? The manifest is always declarative, no? I want to have a view app in a new window, so I want to only start it then. ---followup. To make it open programmatically I just set a v-if on the top element. This it working for me but the problem is CSS encapsulation. The page and app CSS are effecting each other. This is still an open issue