I am transitioning a Vue 3 website from Javascript to TypeScript. Mathjax is loaded from a CDN, and this field from a custom component which worked previously:
watch: {
note_content: function () {
this.$nextTick(MathJax.typesetPromise);
}
}
now generates a static error which should translate as:
Can not find name 'MathJax'.ts(2304)
How can I solve this ?
You'll need to install #types/mathjax
Related
I am new to Nuxt and Vue, so go easy on me. I am trying to create a video player component in my Nuxt 3 app using vue3-video-player, which doesn't seem to support SSR based on the following error I get when I import it in my video component:
ReferenceError: navigator is not defined
This error persists even if the component is wrapped with <ClientOnly>. So, based on what I saw in the Nuxt 3 Documentation I thought I would create a client-only plugin located at plugins/vue3-video-player.client.js with the following contents:
import Vue3VideoPlayer from '#cloudgeek/vue3-video-player'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(Vue3VideoPlayer)
})
But when I try to use it in my component as <vue3-video-player>, I get the following error:
[Vue warn]: Failed to resolve component: vue3-video-player
So I guess my question is how do I create a client-only Vue component using Nuxt 3 plugins? Or is there an entirely different approach that would work better?
Solution for nuxt 3:
Nuxt will automatically read the files in your plugins directory and load them. You can use .server or .client suffix in the file name to load a plugin only on the server or client side.
For example:
plugins/apexcharts.client.ts
Everything is so simple! And that is why we love nuxt ❤️
Solution for nuxt 2 (to show the difference):
nuxt.config.ts
plugins: [
{src: '~/plugins/apexcharts', mode: 'client'}
],
This is only for nuxt 2 because All plugins in your nuxt 3 plugins/ directory are auto-registered, so you should not add them to your nuxt.config separately.
you could try to provide a helper function. As mentioned in the docs.
import Vue3VideoPlayer from '#cloudgeek/vue3-video-player'
export default defineNuxtPlugin((nuxtApp) => {
return {
provide: {
Vue3VideoPlayer
}
}
})
To tag along with the given correct answer here,
If you're trying to install and use a third party NPM package, and running into "window is not defined" type errors, you can load the package as a plugin as follows (eg WAD)
npm install web-audio-daw
// plugins/wad.client.ts
import Wad from "web-audio-daw"
export default defineNuxtPlugin(nuxtApp => {
return {
provide: {
Wad,
}
}
})
// pages/whatever.vue
<script lang="ts" setup>
const { $Wad } = useNuxtApp();
// Can use $Wad normally from here on out
</script>
QUESTION: How can I resolve error 'validations' does not exist in type 'ComponentOptions<Vue [etc.] while using Vetur with Typescript also installed, all in VSCode?
BACKGROUND: I attempted to introduce Vuelidate into a single-file Vue component (by adding a validations property as per the docs). The project containing that component has TypeScript installed so that Vetur's intellisense is improved (but the <script> sections are using JavaScript). After introducing the validations prop, Vetur was displaying an error with the message highlighted in the above question, and intellisense was breaking for methods (such as mount()) that were calling other methods.
CODE: My code basically looks like the sample below, but one would need to install TypeScript to reproduce the Vetur error:
export default {
data() {
return {
name: '',
}
},
validations: {
name: {
required,
minLength: minLength(4)
},
}
}
WHAT HAVE I TRIED: I tried adding #ts-ignore to the validations property, but intellisense is still broken for methods calling other methods.
The solution is:
run npm install --save-dev #types/vuelidate
restart VSCode
I've been reading Nuxt.js's documentation on Plugins and the config nuxt file for adding scripts. I tried both, but no luck.
I'm trying to add the following code (located in /static/js/scripts.js):
$(window).scroll(function(){
if ($(window).scrollTop() >= 200) {
$('nav').addClass('fixed-header');
}
else {
$('nav').removeClass('fixed-header');
}
});
Can someone help me please?
In regular HTML usage, I just do the script tags before the closing body tag (for the sake of user experience). I was able to get the scripts.js to load in a Vue.js 2.0 framework, but once I moved everything to Nuxt.js, and tried to adapt it to Nuxt.js, everything else worked, except the scripts.js file.
[SOLVED]!
I figured it out! I had to refer back to the Vue.js documentation since the Nuxt.js documentation didn't help me at all.
So I basically went into the vue file that contained the navigation bar I wanted the class to toggle appear in based on scroll. I also had to modify the javascript so it's ESLINT friendly... So for the code underneath is the equivalent of what I wrote in my question.
<script>
export default {
name: 'MainNav',
data: function () {
return {
fixedOnScroll: false
}
},
methods: {
handleScroll () {
if (window.scrollY >= 200) {
this.fixedOnScroll = true
} else {
this.fixedOnScroll = false
}
}
},
created () {
if (process.browser) {
window.addEventListener('scroll', this.handleScroll)
}
},
beforeUpdate () {
if (process.browser) {
window.addEventListener('scroll', this.handleScroll)
}
}
}
</script>
Once that was settled, I had to use the vue bind class in the template tag on the same file.
<nav class = "navbar-expand-lg text-center" v-bind:class="{ 'fixed-header': fixedOnScroll }">
Everything worked perfectly after that!
The official guide in Nuxt v1.4.0 document is here: https://nuxtjs.org/faq/window-document-undefined#window-or-document-undefined-
If you need to specify that
you want to import a resource only on the client-side, you need to use
the process.browser variable.
For example, in your .vue file:
if (process.browser) {
require('external_library')
}
If you are using this library within multiple files, we recommend that
you add it into your vendor bundle via nuxt.config.js:
build: {
vendor: ['external_library']
}
I'm using Jhipster 4 with Angular 2 and need to use a 3rd party lib in my project, however the library is no on npm and doesn't have an .d.ts file. I need to include directly the js.
Import inside vendor.ts works for libraries installed via npm but won't work with my js, how can I use this file in my project?
I am also trying to figure this out right now.. I actually couldn't get libraries installed via yarn to work by importing them in the vendor.ts file either though..
My current workaround (...until I can figure out the correct way to do this) was to copy the .js files I needed into src/main/webapp/content/js/ and reference it from webpack.common.js in the CopyWebpackPlugin plugin:
Under plugins in webpack.common.js, I added an entry to CopyWebpackPlugin:
new CopyWebpackPlugin([
{ from: './node_modules/core-js/client/shim.min.js', to: 'core-js-shim.min.js' },
{ from: './node_modules/swagger-ui/dist', to: 'swagger-ui/dist' },
{ from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' },
{ from: './src/main/webapp/favicon.ico', to: 'favicon.ico' },
{ from: './src/main/webapp/robots.txt', to: 'robots.txt' },
{ from: './src/main/webapp/i18n', to: 'i18n' },
{ from: './src/main/webapp/content/js/FooLib.js', to: 'FooLib.js'}
]),
And then added an import to the webapp/index.html
<script src='FooLib.js'></script>
And then declared it in the component that I was using it with:
declare var Foo: any;
While it's less than ideal, you can just use the plain-old-js. Link it as you would normally in the index.html, and then in any TypeScript code that you need to use it put a declare of the library at the top of the file. So, for example:
import { Component } from '#angular/core';
declare myAwesomeJsLibrary: any;
#Component(/* brevity*/)
export class AppComponent {
constructor() {
myAwesomeJsLibrary.doSomethingAwesome();
}
}
It doesn't give you any kind of autocompletion, of course, but you can always create your own interfaces and d.ts files for it if you really want. This way you can at least get it working.
I'm building an Angular 2 (rc.4) app with TypeScript and I would like to use D3.
I've installed D3 through npm install, but this is a js module without .d.ts file. However, I've found a .d.ts file here.
What I do now (a component):
import d3 from 'node_modules/d3/build/d3.min.js';
//<reference path="../declaration/d3.d.ts" />
//[...]
export class Test {
constructor() {
this.object = this.d3.select(...);
}
}
If I set a break-point on that line in the TS file, I can execute everything just fine. However, the mapped .js version of this file was converted to:
var d3_min_js_1 = require('node_modules/d3/build/d3.min.js');
[...]
this.object = d3_min_js_1.default.select(...);
The d3_min_js_1 object exists, but there is no 'default', so it throws a undefined exception...
How can I get this mapping right (I'm pretty sure d3.d.ts does nothing) or how can a use the plain javascript in the TS-file (without it getting f*cked up by the compiler)?
I hope this plunker will help you: https://embed.plnkr.co/qM3qrk3swvalQFBh1Db1/