I created a bundled myproject.min.js file using rollup, now I am using this in other frameworks(aurelia and angular).
Now my concern is how to pass data as props to this vue bundle from other frameworks:
in script file:
Vue.use(window.VueMainComponent);
new Vue({}).$mount('#app');
in HTML file:
<div id="app">
<vue-main-component :data="somedata"></vue-main-component>
</div>
I am trying above approach, but obviously getting the error somedata is not defined.
Okay I have figured this out, I made use of Vue.prototype.
in script file:
Vue.prototype.$somedata = {};
Vue.use(window.VueMainComponent);
new Vue({}).$mount('#app');
in HTML file:
<div id="app">
<vue-main-component :data="$somedata"></vue-main-component>
</div>
Related
I'm trying to avoid Vue from compiling script tag inside root element. Here is a code example:
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.5/vue.global.js"></script>
<script>const app = Vue.createApp({});</script>
<script type="application/javascript" src="global_component_bundled.js"></script>
<div id="app">
<script type="application/javascript" src="myJsFile.js"></script>
<global-component></global-component>
</div>
<script>app.mount("#app");</script>
</body>
I was trying to do something like this:
<script>app.config.isCustomElement = tag => tag.startsWith('script');</script>
but that doesn't work unfortunately for script tag.
The Problem is the warnings what i'm getting on browser console. Maybe is there any way to disable the warnings for script tag or to disable Vue from compiling this tag?
I know that i can do something like this:
<script>app.config.warnHandler = () => null;</script>
But i just want to disable this warning if is not possible vue to ignore compiling script tag:
Template compilation error: Tags with side effect (script and style) are ignored in client component templates.
But i prefer a way to ignore the script tag instead of disabling the warning.
I managed to get rid of the warning by using type="application/javascript" in all of the <script> tags.
I'd like to use Vue.js within one page of a large legacy application. The idea is to replace the old JS+jQuery hodge-podge within a single page -- but leave the rest of the app (many other pages) untouched. So, not interested in using NPM, Node, Vue CLI, Webpack, Babel, etc., just yet.
This is a proof-of-concept before we invest in refactoring the entire frontend of the application.
The approach we followed was to include vue.js via as explained here: https://v2.vuejs.org/v2/guide/installation.html#Direct-lt-script-gt-Include in that one page, and the use Vue only within that one page. This is the general page layout:
<html>
<head>
...
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
...
</head>
<body>
<div id="el">
... vue template ...
</div>
<script>
...
var vm = new Vue({
el : '#el',
data : {
config : <% config.json %> // this is server-rendered, using server templating
...
},
...
});
...
</script>
</body>
</html>
The page does work. However, I get the following error/warning within the Vue console:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed.
Although I'd rather not, I can certainly move the page-specific JS to its own separate file (and that does eliminate the warning/error). However, I wouldn't be able to set vm.config with server-provided data along with the loaded page by using server-side template, e.g. config : <% config.json %>. I know I could GET it using JS separately, after pageload, via an AJAX call directly from the server, but for practical reasons I'd like to avoid doing that here.
I'd greatly appreciate any suggestions on how to get this to work nicely. I'm also open to other suggestions with regard to this general pattern, that don't involve retooling the front-end just yet.
And perhaps the answer is to ignore the warning, or somehow disable it, given the page does work as intended...
Thank you!
One simple solution here is to write it to the global window object. IIRC SSR frameworks like Angular universal/Nuxt/Next/... all use this approach.
window.__STATE__ = <% config.json %>
In your JS file you can then refer to the window.__STATE__ object.
var vm = new Vue({
el: '#el',
data: {
config: window.__STATE__
}
})
Ofcourse the order is important here:
<body>
<script>
window.__STATE__ = <% config.json %>
</script>
<script src="app.js"></script>
</body>
Grrr, after several days after enduring this error, I discovered this:
<fieldset id="el">
...
<div id="el">
...
</div>
...
</fieldset>
So the issue was repeating #el within same page.
My mistake.
Just wish the error message emitted by Vue had been a bit more useful!
Bottom line: The pattern described in the origional question works just fine without NPM/CLI.
What am I doing?
I am using the intersection observer API to make lazy loading.
What have I tried?
I tried the code in a simple HTML page and it works perfect, but when I use the code in vue, the images won't load (local images). If I put a htttp source images (online images) it works perfect, too. I think this is a webpack error config. Am I right? How can I fix it?.
Whats the error?
When i use a local image the code doesnt work, if only change that src with something else like this image https://images.pexels.com/photos/69817/france-confectionery-raspberry-cake-fruit-69817.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940 the code WORKS, why i cant make it work with local images?
HTML AND SCRIPT
<template>
<div class="container" id="section3">
<span class="containerTitle">Galeria</span>
<div class="wrapper">
<img v-lazyload data-src="#assets/images/001.jpg" class="card">
</div>
</div>
</template>
<script>
import lazyload from '../directives/lazyload'
export default {
directives:{
lazyload
},
}
</script>
DIRECTIVE
export default{
inserted: el =>{
const options = {
// root:
rootMargin: '0px 0px 0px 0px',
threshold:1
}
var observer = new IntersectionObserver((entries,observer) =>{
entries.forEach(entry => {
if(entry.isIntersecting){
el.src = el.dataset.src
observer.unobserve(el)
console.log('intersecting');
}
})
},options)
observer.observe(el)
}
}
CODE IMAGE
FOLDER
The issue is with your image path.
You can fix it with either using public folder and give it in path.
You can also check for auto suggestion which come up while typing, this may help you to check whether your path is correct or not.
Like this
Your path is wrong. You gave ../assets/images/001.jpg as the path to the image (as stated in your question), but according to your directory tree it's ../assets/001.jpg (or write it like #/assets/001.jpg, # points to root of project). That should fix it.
As far as I remember you can't use # sign inside <template>.
So you can either:
require it
<img v-lazyload :data-src="require('#assets/images/001.jpg')" class="card">
import it
<template>
...
<img v-lazyload data-src="image" class="card">
...
</template>
<script>
import img from '#assets/images/001.jpg';
...
data() {
return {
image: img,
}
}
...
</script>
use relative path
<img v-lazyload data-src="../assets/images/001.jpg" class="card">
You can check how it works in Vue docs
I can't remember why this works, but you need to use the following syntax:
<img v-lazyload data-src="~assets/images/001.jpg" class="card">
with the ~ replacing the ../.
I will update the answer if I figure out exactly why.
doing extensive research i found this article about vuejs and static assets.
https://edicasoft.com/weblog/2018/04/27/static-vs-srcassets-webpack-template-vue-cli/
They said that this kind of problems occurs "because" of webpack,like i though, so the solution for this (i hope not the only solution), but this is the solution so far...
QUOTE
All asset URLs such as , background: url(...) and CSS #import are resolved by Webpack as module dependencies like require('./logo.png').
We then use loaders for Webpack, such as file-loader and url-loader, to process them. Webpack template has already configured these loaders.
File-loader helps to determine the final file location and how to name it using version hashes for better caching. Thus you can put your static assets near your .vue files and use relative paths. There is no need to put them strictly into the ‘assets’ folder.
Url-loader helps to conditionally inline assets such as base64 data URL, reducing the amount of HTTP requests.
So what the hell should I do with it?
The answer is: put your assets in the ‘src’ folder.
I tested this and it works perfect BUT you CANT make a subfolder and this for me, is disorganized.
This is the final folder structure to get this done using intersection observer api as vue directive!
I'm trying to implement VueJS in one of my pages blade template. I just want to use Vue in that single template.
I tried the following:
default.blade.php
//...
#yield('js-for-layout-before')
<script src="{{ asset('js/vue.min.js') }}"></script>
// ...
view.blade.php
#extends('layouts.default')
//...
#section('content')
<div id="app">
<ol>
<todo-item></todo-item>
</ol>
<p>#{{ message }}</p>
</div>
<script type="module" src="{{ asset('js/pages/vue_component.js') }}"></script>
#stop
vue_component.js
Vue.component('todo-item', {
template: '<li>This is a list item</li>'
})
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
With this, I am only getting a blank page. There are no errors in the console, all files are loaded.
The inspector shows what I mean:
I do not want to implement a build step or anything, just a minimum setup with vue. Any ideas what I am missing here?
--UPDATE:
I replaced vue.min.js with the development version and finally got a clue:
vue.js:633 [Vue warn]: It seems you are using the standalone build of
Vue.js in an environment with Content Security Policy that prohibits
unsafe-eval. The template compiler cannot work in this environment.
Consider relaxing the policy to allow unsafe-eval or pre-compiling
your templates into render functions.
For reference, the issue was that my CSP didn't allow for unsafe-eval, which is required in this scenario without a build step. I didn't notice this until I included vue.js instead of the minified vue.min.js, which doesn't show errors.
To fix this for now, I did the following, though you should probably not do this in production: Check where your CSP is defined and add 'unsafe-eval' to "script-src".
In production, you probably want to use nonce on the script instead of unsafe-eval and something like https://github.com/spatie/laravel-csp to generate the nonce.
I'm trying to create an Chrome extension with web accessible resources. Since my extension tries to create a modal with a list of available data, I decided to use VueJS to handle the dynamic nature of content.
However, When I create the sample files and initialize VueJS, it simply leads to all the DOM being commented out and my app not working.
Here's the code I'm using:
web_resources/vue.html
<html>
<head>
<script type="text/javascript" src="/web_resources/vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script type="text/javascript" src="/web_resources/app.js"></script>
</body>
</html>
web_resources/app.js
window.app = new Vue({
el: '#app',
data: {
message: 'Hello World'
}
})
When I run this, the entire div is replaced with: <!----> and nothing works.
On searching online for VueJS inside iframe, I came across this post which has this fiddle which surprisingly produces a blank page for me with no content. On inspecting the result, I find that the div has been replaced with <!----> here as well.
Why is VueJS not initializing properly within an iframe?
The problem was Content Security Policy (CSP). Since I was using a local copy of vue.min.js, I couldn't see any of the error messages. It looked like everything was initializing as expected except it wasn't. Once I replaced this with a un-minified version, I saw an error on the lines of:
I simply had to go update the CSP in manifest.json which I was able to do by adding:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",