I used Epubjs. But when I run the application. It turns out "Cannot read property 'requestContent' of undefined". Maybe it is about Asynchronous loading.`
// # is an alias to /src
import Epub from 'epubjs'
global.ePub = Epub
export default {
name: 'home',
mounted () {
this.book = new Epub('/public/东京暗鸦_qinkan.net.epub')
this.book.renderTo('read', {
width: window.innerWidth,
height: window.innerHeight
})
}
}
</script>`
I saw this issue in Chrome and loaded the new code into FF instead and it was showing me a Cross Origins blocked error (which makes sense because I hadn't added that to my API yet).
So this appears to be a chrome issue but might want to look into Cross-origin being blocked in your API.
Related
I have question related to using context or prototype in Nuxt
I create a constant for 'modal' name like this:
export default Object.freeze({
MODAL_SHOWPRO: "MODAL_SHOWPRO",
})
I also created constant.js in plugin folder and already added to nuxt config.
import modals from '#/constants/modal';
export default ({ app }, inject) => {
inject('modalName', modals)
}
In component I can't call value from v-bind, it said : undefined MODAL_SHOWPRO
<Popup :id="$modalName.MODAL_SHOWPRO" />
but I can call it from $emit function something like this:
#click="$nuxt.$emit('showModal', {id: $modalName.MODAL_SHOWPRO})"
Can you let me know why and how to fix it?
Notice: It will work if:
I make data
{
modal: ''
}
and add to created:
async created() {
this.modalName = await this.$modalName
}
Nuxt is a meta-framework aimed at providing an universal app (server then client side). So, you need to think about both server and client.
In your code, you specified ssr: false, this is outdated and should rather be mode: 'client'. But setting so is still false because it means that the ENUM will not be available on the server (hence the error).
Setting it like this is more appropriate (regarding the nature of the plugin) and also fixes the issue
plugins: ['~/plugins/constant.js'],
More on Nuxt plugins: https://nuxtjs.org/docs/directory-structure/plugins#plugins-directory
I'm tying to follow the official nuxt.js documentation to dynamically load dozens of .mp3 files as the user progresses through a quiz.I've set up my config file as follows:
nuxt.config.js (Nuxt v2.15.8):
build: {
extend ( config, ctx ) {
// Might be used for loading media files
config.module.rules.push({
test: /\.(ogg|mp3|wav|mpe?g)$/i,
loader: 'file-loader',
options: {
name: '[path][name].[ext]'
}
});
}
}
This works:
import audioFile from '~/assets/audio/sfx_Q1_1.mp3';
// Outputs /_nuxt/assets/audio/sfx_Q1_1.mp3, and the file plays as expected
console.log(audioFile);
Using an import statement works, and it gives me the correct asset path. The problem is that I need dozens of mp3s with sfx_Q#_#.mp3 format, so I need a more dynamic approach.
This doesn't work:
mounted() {
let audioURL = `~/assets/audio/sfx_Q${this.qID}_${this.aID}.mp3`;
let audio = require(audioURL);
console.log(audio);
}
With this approach, my app crashes and I get Cannot find module '~/assets/audio/sfx_Q1_1.mp3', even though it's exactly the same path as the version that worked with the import statement.
This also works
<audio v-bind:src="require(`~/assets/audio/sfx_Q${qID}_${aID}.mp3`).default"></audio>
...but this doesn't work
<audio v-bind:src="require(getAudioURL()).default"></audio>
// ... //
getAudioURL() {
return `~/assets/audio/sfx_Q${this.qID}_${this.aID}.mp3`;
}
... I get the same Cannot find module error. Why does the import break when the file path is generated dynamically inside a method? I've tried with # symbol as well, to no avail. This question had the same issue, but I've tried exactly the solutions suggested, and it doesn't help.
I use this package : https://www.npmjs.com/package/vue-recaptcha-v3
I add on my main.js :
import { VueReCaptcha } from 'vue-recaptcha-v3'
Vue.use(VueReCaptcha, { siteKey: 'xxxxxxx' })
I add this code :
await this.$recaptcha('login').then((token) => {
recaptcha = token
})
to my component to get token from google recapchta
My problem is the captcha icon in the lower right corner appears on all pages
I want it to only appear in certain components
Maybe I must to change this : Vue.use(VueReCaptcha, { siteKey: 'xxxxxxxxxxxxxxxxx' }). Seems it still mounting to Vue.use. I want to mount to a certain component instead of vue root instance
How can I solve this problem?
Update
I try like this :
Vue.use(VueReCaptcha, {
siteKey: 'xxxxxxx',
loaderOptions: {
useRecaptchaNet: true,
autoHideBadge: true
}
})
It hides the badge. I want the badge to still appear. But only on 1 page, the registration page. How can I do it?
I've had the same issue while using the npm package, it's pretty annoying.
At the end of the day, I've decided not to use the package & follow Google's documentation.
This line here :
grecaptcha.execute('_reCAPTCHA_site_key_', {action: 'login'}).then(function(token) {
recaptcha = token
})
Is equivalent to this line here from the npm package :
this.$recaptcha('login').then((token) => {
recaptcha = token
})
You just need to add this line into your < head > for recaptcha to work :
<script src="https://www.google.com/recaptcha/api.js?render=_reCAPTCHA_site_key"></script>
But as soon the script tag is in your < head >, you will be facing the same issue of it showing on every page.
The hack is that you only insert it into the < head > on components that you need.
There are ways to do this but I ended up referencing this.
You can put it in the methods of your component & call the method when the component is loaded.
That way it will only show up on the pages that you need it to.
in main.js set autoHideBadge true:
import { VueReCaptcha } from 'vue-recaptcha-v3'
Vue.use(VueReCaptcha, { siteKey: 'your site key',
loaderOptions:{autoHideBadge: true }})
in every page you want to show the badge you can show the badge in mounted,
for some reasons until a few seconds after mounted event this.$recaptchaInstance is null and you cant use it, so I use a timeout to showing the badge 5 second after page load in mounted.
mounted(){
setTimeout(()=>{
const recaptcha = this.$recaptchaInstance
recaptcha.showBadge()
},5000)
},
when you show it you have to hide it again in the same page.
beforeDestroy() {
const recaptcha = this.$recaptchaInstance
recaptcha.hideBadge()
},
If you are using composition API setup this is what you need:
const reCaptchaIn = useReCaptcha().instance
onMounted(() => {
setTimeout(() => {
reCaptchaIn.value.showBadge()
}, 3000)
})
Just use this code:
const recaptcha = this.$recaptchaInstance
// Hide reCAPTCHA badge:
recaptcha.value.hideBadge()
// Show reCAPTCHA badge:
recaptcha.value.showBadge()
vue-recaptcha-v3 npm
I stumbled upon this incredibly simple answer. It is excellent especially if you wish to hide the badge from all your pages. You can perhaps use scoped css to hide on some pages as well.
.grecaptcha-badge { visibility: hidden; }
You can read the post here
I have the following code in one of my layouts.
bodyAttrs: {
class: this.$store.state.user.theme + '-scheme'
}
unfortunately, i am using an old bootstrap theme css. I DO NOT want to redo it as such i have to figure out some work arounds.
The theme color for the bootstrap theme attaches itself to the body tag. Unfortunately the body tag is a no no in nuxt.
What i have noticed is, that upon refresh the page is rendered with the base state value.
example :
//store/index.js <- not modular
var state = () => ({
user: {
id: 0,
avatar: 'default.jpg',
status: 'offline',
nickname: 'Guest',
admin: false,
theme: 'brownish' //-> this is the value
}
})
The entire page renders with the users details but the theme variable is not placed into the render. If i go to another page(ajax routing), the page is updated with the correct color.
Essentially the page loads brown and then on subsequent pages it will load blue. If the page is refreshed then the color reverts to brown and then on subsequent pages it will turn blue again.
How can i get the SSR to display the correct bodyAttr?
I am using vuex-persistedstate and cookies both are client side
The nuxt server does not have any sessions as this is handled on a separate domain(api)
I couldn't find a pure vuejs way to do this so i made a fix.
This is technically a bad idea as it is directly modifying the DOM which is a no-no in vue. However, vue doesnt use reactivity on the body tag. Therefore i think it is fairly safe to use. Also, using vuex-presistedstate will ensure that vue set the proper state variable on subsequent loads..
//This is layouts/default.vue
head() {
return {
bodyAttrs: {
class: this.$store.state.user.theme + '-scheme'
}
}
},
mounted() {
window.onNuxtReady(() => {
document.body.className = this.$store.state.user.theme + '-scheme'
})
}
Are you using the cookies based version of vuex-persistedstate? Customize Storage
Remember to enable the ssr mode for the plugin in nuxt.config.js
I wonder if someone using the jest addon can share it's Vue Storybook configuration, since I can't seem to make it work. I've tried the global mode:
In Storybook's config.js:
import { withTests } from '#storybook/addon-jest';
import results from '../.jest-test-results.json';
addDecorator(
withTests({
results,
})
);
And inside my Story:
storiesOf('Elements/Tag', module)
.addParameters({ jest: ['ThuleTag'] })
.addDecorator(VueInfoAddon)
.addDecorator(withTests({ results })('ThuleTag'))
.add('Squared',
withNotes(_notes)(() => ({
components: {ThuleTag},
template: _template,
propsDescription: {
size: 'medium / small / mini',
type: 'success / info/warning / danger'
}
})),
)
I get this error:
TypeError: Object(...)(...).addParameters is not a function
I've also tried the local way:
In my Story:
import { storiesOf } from '#storybook/vue'
import { withNotes } from '#storybook/addon-notes'
import results from '../../../jest-test-results.json'
import { withTests } from '#storybook/addon-jest'
import ThuleTag from '../../components/ui/elements/ThuleTag.vue'
let _notes = `A simple wrapper for the Elements el-tag, that accepts the same <i>type</i> and <i>size</i> props`
let _template = `<thule-tag
size="small"
key="name">Tag Namez
</thule-tag>`
storiesOf('Elements/Tag', module)
.addDecorator(withTests({ results }))
.add('Squared',
withNotes(_notes)(() => ({
components: {ThuleTag},
template: _template,
propsDescription: {
size: 'medium / small / mini',
type: 'success / info/warning / danger'
}
})),
{
jest: ['ThuleTag.test.js'],
}
)
Here I get this error:
Error in render: "TypeError: Cannot read property '__esModule' of undefined"
And the Tests tab is shown with this message:
This story has tests configured, but no file was found
Can someone point me what's messing things up please?
It looks like storybook jest addon is not supported for Vue.js for now
https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md
Ok, about first error
Error in render: "TypeError: Cannot read property '__esModule' of undefined"
I think that you should check your babel-config, It seems like you forget some presets for your framework.
About second question
This story has tests configured, but no file was found
That problem happens from Jest and storybook/addon-jest want to get with equals api, but they can't. In last versions of Jest, output file structure has options.testResults , but storybook/addon-jest wants options.results & options.results.testResults.
There are two possible solutions:
use appropriate version of Jest and storybook/addon-jest
apply huck in index.js of storybook-jest library, smth like that
if (testFiles && !testFiles.disable) {
//todo: HERE should be your storybook hack
options.results = options.tests.testResults;
options.results.testResults = options.results;
emitAddTests({
kind: kind,
story: story,
testFiles: testFiles,
options: options
});
}