Vue template render without all the extra - vue.js

I have a very, very simple set of Vue components that all work. These are a simple addition on top of an existing C# app.
At the moment, these are .html files (brought into the app inside <script> tags) and .js files loaded by reference.
These all work, are very light weight, and I love it.
Now I want to compile the HTML for each component into a Vue render function, and the .js into one minified .js file.
The .js to .min.js is pretty standard, but I cannot figure out how to get the HTML to compile into the Vue render function. Everything I've found involves a LOT of overhead and running a web server which seems a massive overkill for an html->script transform, and I don't need a full web application spun up. I only need my existing, simple templates transformed to something more friendly for production than my long-form html templates getting dumped to the page.
I'm not entirely opposed to turning the .html+.js into .vue files, but just doing that doesn't seem to overcome my issue.

I cannot figure out how to get the HTML to compile into the Vue render function
To generate a render function from a Vue template string (e.g., read from an HTML file), you could use vue-template-compiler like this:
const compiler = require('vue-template-compiler')
const output = compiler.compile('<div>{{msg}}</div>')
console.log(output) // => { render: "with(this){return _c('div',[_v(_s(msg))])}" }
Everything I've found involves a LOT of overhead and running a web server which seems a massive overkill for an html->script transform
The "web server" you mention is provided by Webpack CLI, and is intended to faciliate development. You don't need to use the dev server. The article indeed describes several steps in manually setting up a project to build Vue single-file-components, but a simpler method is to use Vue CLI to automatically scaffold such a project.

Related

How to convert a Vue page to a vector-based PDF on the client-side

I want to convert an HTML page written with Vue.js to a vector-based PDF client-side. I understand there are solutions in the backend, however, in my case I specifically want client-side. I have very complex Vue components and styling which I would like to print to pdf. I tried multiple approaches and I could not find a solution.
Here is what I tried: -
The easiest way I found is window.print().
The issue with this approach, is that there is no other way to invoke the download functionality directly without going through the pop-dialog. Another issue I found window.onafterprint and window.onbeforeprint event listeners don't work on firefox but work in chrome. In firefox, both events fire at the same time. regardless, I do not like the default dialog, I would rather build my own.
I retrieved the HTML and CSS from the DOM using this.$el.innerHTML, and window.getComputedStyle(element) and saved them to a variable, then converted to blob and downloaded it with javascript.
this solution worked, however only in DEV build, since I bundle my app with Vite, the computed styles don't render on the DOM as I expected when in Production build; which I believe is due to the way Vite bundles CSS for optimization. Therefore the result will only be HTML with no styling.
I used the popular vue-html2pdf library and it is straightforward.
the issue with this approach is the fact it simply renders HTML and CSS to an image the saves as a pdf, therefore the output will be an image-based-pdf. which is not my preferred kind of pdf.
I cannot find any library that takes in HTML and CSS and covert to a Vector-based pdf on the client-side.

Page specific tailwind classes with SSG

Currently I'm developing a website using the following stack:
vue.js
#vue/server-renderer
vite
tailwind CSS
SSG was chosen as the rendering mode.
Tailwind, as described in the documentation, allows you to specify directories and file extensions (content property) , in which he will try to find the classes, in order to leave only those that are actually used in the project.
As a result, the 'main.css' file is formed, in which only those classes that are used remain.
Next, I just take this file and include it in every page that was rendered during the build phase of the project.
This results in:
index.html - main.css
about.html - main.css
blog.html - main.css
It turns out that main.css file may contain classes that are needed only for one of the pages and are not needed for others.
I would like to implement the following:
Take main.css which turned out
Render a page, for examle about.html
take only those styles that are needed for about.html page from the main.css file
create a new about.css file
link the resulting about.css styles to about.html
I’ve already tried to implement this using an awesome PurgeCSS tool as following:
render page content usind #vue/server-renderer's renderToString() method;
Pass an resulting css and html sources to PurgeCSS
here is an example
But there are too many corner cases around this solution, such as:
Dynamic classes which can be added to the html on the client side
Some components may be missing in rendered html and their content will be added later (for example, v-if directive was used on the component)
A few takeaways:
PurgeCSS is not needed anymore since Tailwind v2 (the latest being v3.x)
as far as I know, you cannot have code-splitting with Tailwind, not that it matters anyway since it will still perform okay with further optmizations
the classes that will be generated, will be only once for the whole app (hence no need to have a bg-red-500 for index or about page, both are referencing the same unique declaration)
if you want to have SSR/SSG, I recommend the usage of Nuxt (in it's v3 if you're using Vue3 or plan to have anything long-term)
dynamic classes are not possible with Tailwind, you can create things like bg-[#ccc] but it goes on the opposite side of what Tailwind is achieving and should be used exceptionally
for Tailwind's content, still the defaults on this page, section Configure your template paths, no need to do anything crazy or complicated
if you want to have some scoped/local style, style to using style scoped, you can still use Tailwind inside of those tags tho
if you want to write vanilla CSS into dedicated CSS files like index, about, blog etc, then Tailwind is probably not the best approach because this is not how it is supposed to work
stay simple, the performance will still be amazing. Only focus on not having too many screens, colors etc that you're not using
you could run some bundle size tests to see if the CSS is taking a huge chunk in terms of size. Will probably not, but if it still is: you can then start making complex configurations
JS will be far harder to reduce and be more impactful regarding the performance (because of how a browser works with it: parsing, executing is indeed blocking the main thread)

How do I load a Vue template from a hosted html file (no webpack, etc)

I am trying a new way of writing my ui and I am using straight ESM loading with Vue. As such I am trying to load my HTML files like I would with say Webpack. I have a simple example of what I am talking about. I basically want to take...
export default {
template: "<div>Here is the component. I want this template to be an html file without webpack</div>"
// I want this to be from a url say mysite.net/viewport.html
}
I tried the simple things like
import Template from "/viewport.html"
But of course that didn't work
I think there might be something I can do with dynamic components. Has anyone tried this an come up with a good solution?

Using Vue Components in Moqui Screens

Is it possible to use VusJS Components into Moqui Screens?
I know for sure that you can render Basic HTML but I wasn't able to find a hook for the VueJS app.
The need comes from the following scenario:
While form-single widget can be made collapsible, form-list cannot. So I wanted to use vue-collapsible (https://github.com/vue-comps/vue-collapsible) but I don't know where I am supposed to register the component.
If there's no way to use vue, maybe you can help me with my concrete issue.
In the 'vuet' render mode which is used in the /vapps path (as opposed to /apps) it isn't actually HTML sent to the client it is a Vue Template. If you look at the text returned by the server you'll see a number of Vue Components already being used (see the WebrootVue.js file for their source). You can see this in Chrome using the Sources or Network tab in the tools window or similar tools in other browsers. If you inspect an element you'll be looking at the rendered HTML, ie after Vue runs the components to change the Vue Template to HTML.
This means that if you include the necessary JavaScript file(s), and CSS file(s) if needed, then you can use any Vue component in the Vue Template returned. You can do this inline in XML Screen files using the render-mode.text element with the #type=vuet.
None of this runs under NPM in the way VueJS is used in Moqui Framework through XML Screens. In other words it isn't a pre-packaged Vue app with 100% client/browser rendering but rather is a hybrid client and server rendered approach.
You can include scripts in this Moqui hybrid approach using the script element with a #src attribute for the script file which the WebrootVue.js file loads on the fly. There are various examples of this for additional JS scripts like Chart.JS

Vuejs - How to insert JS Tracking Codes like Google Analytics or Adsense

So I am developing a site as a SPA with Vue JS and I have just came across a issue.
I went to insert Adsense's code snippet like i would normally, but Vue complains with the following
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as , as they will not be parsed.
So I am now a bit stuck, I have seen a library that will put Adsense in as a component but its a very new/small library and i could not get the thing to work.
I also have a lot of other tracking pixels that will need to go on the site in a similar fashion so I will need to find a way around doing this.
Can anyone lend some advise, thanks.
Try modifying the index.html file instead of the *.vue files. The Vue SPA app automatically listens for updates to *.vue files. So pasting the snippet in html file will bypass the compiler checks for undefined variables, etc.