Loading mermaid in a vue component (webpack) - vue.js

I am migrating a vue project that uses mermaid from CDN to webpack. I'm total new with it. I did npm install save mermaid on project folder.
If i load mermaid cdn as static js (in /public/index.html), it crashes for some graphs (shows bomb icon, says syntax error)
If in webpack, it shows nothing as mermaid graphs, but seems to load empty (inspecting generated html with browser tools). No console errors
<svg id="mermaidChart0" width="100%" xmlns="http://www.w3.org/2000/svg"><g><g class="output"><g class="clusters"></g><g class="edgePaths"></g><g class="edgeLabels"></g><g class="nodes"></g></g></g></svg>
Tried:
//package.json
...
"dependencies": {
"axios": "^0.21.0",
"core-js": "^3.6.5",
"mermaid": "^8.8.2",
and in the component.vue
<template>
...
<div class="mermaid m-5">
graph LR
B(dsfgdsfgsd <br>) --> Bo(gdfshfghfdh <br>)
...
<script>
import mermaid from 'mermaid'
export default {
data: function() {
return {}
},
mounted() {
this.init();
},
methods: {
init: function() {
mermaid.initialize({
theme: 'forest',
htmlLabels: true,
//startOnLoad: true
});
console.log(mermaid);
mermaid.init(undefined, document.querySelectorAll('.mermaid'));
}
}
}

If you want a ready-to-use solution, you can use my component vue-mermaid-string. It does the internal work for you.
Install it via NPM, then add it to your project via CDN script or by adding the component, then use it like so:
<template>
<vue-mermaid-string :value="diagram" />
</template>
<script>
export default {
computed: {
diagram: () => 'graph TD\n A --> B',
},
}
</script>

Related

Does Vue 3 support HTML-based single file components without compilation?

I've been using HTML-based components with Vue 2 - and loading them dynamically, without a compile step. That is, files that look like this:
<style scoped>
</style>
<template>
<div>empty component</div>
</template>
<script>
module.exports = {
data: function () {
return {
};
},
async mounted(){
},
destroyed: function(){
},
methods: {
},
components: {
},
}
</script>
and are served statically.
Does this approach still work with Vue 3?
https://medium.com/#marcel.leusch/use-vue-3-single-file-components-without-compilation-ac2ccb5f15c2
You need to use the vue3 single file component loader
Yes.
Vue 3 Setup without Build Tools is the official guide on how to use Vue 3 without build tools. Hope it helps.

Vue Component including Inertiajs-Link Not working in Project

I'm going to build small UI library package with Vue components and use it in my Inertia-Laravel Project.
//Logo.vue
<template>
<Link href="/" class="text-xl font-bold flex items-center lg:ml-2.5">
My Logo
</Link>
</template>
<script>
import { Link } from '#inertiajs/inertia-vue3'
export default {
name: "Logo",
components: {
Link,
},
}
</script>
I was able to build this as package Vite or Vue-SFC-RollUp and publish it on npm.
But when I was going to install it on my inertia/laravel projects and use it, I got some warning and error.
MyProjectComponent.vue
<template>
...
<Logo />
...
</template>
<script>
import {Logo} from 'mypackage-ui'
export default {
components: {Logo}
}
</script>
Error message:
export 'default' (imported as 'require$$1') was not found in 'vue'
(possible exports: BaseTransition, Comment, EffectScope, ... , withScopeId)
If I remove <Link> in Logo.vue and use <a> tag and update package, then it's working well.
Any suggestion would be highly appreciated.
I'm using Vue 3.
The solution to this is to add the inertia link as a component in the app.js file:
import { createInertiaApp, Head, Link } from '#inertiajs/inertia-vue3';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.component('InertiaHead', Head)
.component('InertiaLink', Link)
.use(ZiggyVue, Ziggy)
.mount(el);
},
});

JSX rendered by nuxt dev server works, while the prod version doesn't work

I have a nuxt app with a component that uses JSX. It works locally using npm run dev, but the dist build I get after running npm run build fails to properly render.
Here' the component's code:
<script>
import draggable from 'vuedraggable'
export default {
data () {
return {
columns: [
{ width: 2 },
{ width: 3 },
{ width: 4 }
]
}
},
components: {
draggable
},
render (h) {
const buildColumn = (column, index) => {
const result = (
<v-col md={ column.width } cols="auto">
<v-card>
<v-row>
<v-col>
<v-icon class="handle">mdi-drag</v-icon>
</v-col>
<v-col>
{ index }
</v-col>
</v-row>
</v-card>
</v-col>
)
return result
}
return (
<v-container>
<draggable handle=".handle" onEnd={ () => this.$emit('update-order', this.columns) } list={this.columns} tag="v-row" options={{ animation: 500 }}>
{ this.columns.map((column, index) => buildColumn(column, index)) }
</draggable>
</v-container>
)
}
}
</script>
When running npm run dev, it renders the following:
After building:
Can anyone help me figure out what could be causing this? I'm including a base repo that demonstrates the problem
https://gitlab.com/qualisign/test_jsx
One more possible clue:
the first image is the non-working html one sees on the production server when inspecting the icons that fail to load:
this second image is how the working html looks when one inspects the same elements on the dev server:
I don't know if this helps, but I thought it might be relevant.
Update: after looking the code shared by OP, this seems to be a BUG #382 and is mentioned on the project repository as well.
There seems to be an issue with vuetify-loaded and to get around this issue, disabling treeShake option in the configuration like:
nuxt.config.js
{
...
vuetify: {
...,
treeShake: false
}
...
}
Original answer:
Looks like material icon library is not configured property due to which icons are not rendered. Check if following are configured properly as mentioned in the guide:
Check if material-design-icons-iconfont is installed
npm install material-design-icons-iconfont -D
Check if css file is imported are on entry point of your app (index.js/app.js)
import 'material-design-icons-iconfont/dist/material-design-icons.css' // Ensure you are using css-loader
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
export default new Vuetify({
icons: {
iconfont: 'md',
},
})
If you are using CDN link for the library check if it is correct.
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet">.
If this still doesn't work, check for all console and network errors, it's possible you have misconfigured style/font url somewhere in your app.

How to get an object item from package.json in Vue / Quasar

I am trying to get the 'version' from package.json in my Vue/Quasar project.
There was an information in the internet to use this code:
import { version } from '../package.json'
Now I am a beginner and I cannot get this running.
My current code looks somewhat like this:
<template>
// ... REMOVED CODE FOR BETTER READABILITY
<q-layout view="lHh Lpr lFf">
<q-page-container>
<div>VERSION: {{ version }}</div>
<router-view />
</q-page-container>
</q-layout>
</template>
<script>
import { version } from '../package.json'
export default {
name: 'Layout',
data () {
return {
leftDrawerOpen: false
}
},
components: {
version
}
}
</script>
ESLint throws the following error:
87:5 error The "version" component has been registered but not used
vue/no-unused-components
How do I use the component variable I imported correctly?
Follow these steps it will works fine
import {version} from '../../package.json'
data: () => ({
appVersion:version
}),
{{appVersion}}
(or)
Vue.prototype.application_version = require('../package.json').version;
Remove this piece of code:
components: {
version
}
You are trying to register it as a component which it is not.
Then add the version to vue:
data () {
...
version: version
}

How to use mathjax with vue.js 2?

My package.json:
"dependencies": {
"bootstrap": "^3.3.7",
"mathjax": "^2.7.2",
"vue": "^2.5.2",
"vue-moment": "^3.1.0",
"vue-router": "^3.0.1"
},
I have a component:
<template>
<div class="post--body" v-html="previewText" id="post--body"></div>
</template>
<script>
import MathJax from 'mathjax'
export default {
name: 'blog-post',
data () {
return {
post: {body: ""}
}
},
mounted() {
fetch("/api/post/" + this.$route.params.id)
.then(response => response.json())
.then(data => {
this.post = data;
})
this.$nextTick(function () {
console.log("tick")
MathJax.Hub.Typeset()
})
},
computed: {
previewText () {
return this.post.body
}
}
}
</script>
But I got "Uncaught SyntaxError: Unexpected token <" on MathMenu.js?V=2.7.2:1
How to properly use mathjax?
I don't think you can import mathjax, because if I console log imported mathjax , it shows empty object. I have gone through the folder directory also that doesn't seem importable. So you need to manually put the script src pointing to Mathjax.js
The way I currently use Mathjax in vue is by making a custom global component.
<template>
<span ref="mathJaxEl" v-html="data" class="e-mathjax"></span>
</template>
<script type="text/javascript">
export default{
props:['data'],
watch:{
'window.MathJax'(val){
this.renderMathJax()
},
'data'(val){
this.renderMathJax()
}
},
mounted(){
this.renderMathJax()
},
methods:{
renderMathJax(){
if(window.MathJax){
window.MathJax.Hub.Queue(["Typeset", window.MathJax.Hub,this.$refs.mathJaxEl]);
}
}
}
}
</script>
It can be made a bit better by using a variable to save boolean whether, mathjax has been rendered or not, as rendering gets called for two watch values, which both may get triggered in case of browser refresh.
So for MathJax v3, just add the following to your vue component
mounted(){
MathJax.typeset();
},
Now when navigating to pages via Vue router the math will render on component mount.