I use Vuejs2 with a server side rendering, and I have create a plugin. When I declare a directive and use this on a DOM element, I have many warnings, but my directive working:
Here is my code for directive on plugins:
Vue.directive("htl-mouse-tracker", {
bind(el, binding, vnode, oldVnode) {
console.log(el)
}
})
and I use my directive like this:
button(v-on:click="toggleMobileNavigation", v-htl-mouse-tracker).AppHeader__headerButton
Related
How can I make my custom modifiers in vuejs and how can I use them?
any idea?
You can create modifiers only for your own custom directives.
Vuejs doesn't allow to add additional modifiers to core directives like v-model, v-on etc.
Example with a custom directive:
<div v-my-directive.uppercase="myVar" />
const myDirective = {
created(el, binding, vnode, prevVnode) {
if(binding.modifiers.uppercase) {
// Do whatever
}
},
}
Sources:
Vuejs documentation: Custom directives
Vuejs issue #3666: Add custom v-model modifier
Vue complain when I use "emit" I'm looking for a same-functioning alternative
It will be a todo list
Code:
<button #click="$emit('delete-todo-event', todo.id)">Button</button>
Warnig in the Browser-Console:
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Extraneous non-emits event listeners deleteTodoEvent) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option. at <ToDos todoEntries= (9) [Proxy, Proxy, Proxy, Proxy, Proxy, Proxy, Proxy, Proxy, Proxy] onDeleteTodoEvent=fn<bound deleteToDoItem> > at <App>
You seem to be using Vue 3. The warning tells you that you did not declare your event before using it in your component. Here is an example:
export default {
name: "YourComponent",
emits: ["deleteTodoEvent"], // <--- this is what the warning in hinting to
setup(_,{ emit }) {
...
},
};
I have VUE3 app with vue-router using third party web components imported as custom elements, I set the isCustomElement option to ignore custom element, but it seems not to be taken into account.
I set the "vue": { "runtimeCompiler": true } in package.json.
I set app.config.isCustomElement = (tag) => tag.startsWith('bdl-') to ignore customElements in main.js
I use web components - custom elements starting with bdl- in About.vue:
<template>
<div class="about">
<h1>This is an about page</h1>
<bdl-fmi></bdl-fmi>
<bdl-range></bdl-range>
<bdl-chartjs-time></bdl-chartjs-time>
</div>
</template>
However, it seems that it's not taken into account and the browser console log contains warning [Vue warn]: Failed to resolve component: bdl-fmi and custom elements fails to render in router view.
Tried VUE2 and the configuration Vue.config.ignoredElements = ['bdl-chartjs'] is working and similar application with vue-router do not try to interpret third party custom elements and renders as expected.
Any thoughts on isCustomElement will be appreciated.
Sample with this issue can be seen at CODESANDBOX: https://codesandbox.io/s/vue-3-router-with-bodylightjs-components-h8v50
The app.config.isCustomElement flag is intended for projects that use the runtime compiler, which could be enabled in a Vue CLI project via the runtimeCompiler flag in vue.config.js:
// vue.config.js
module.exports = {
runtimeCompiler: true,
}
But you could also resolve this without the runtime compiler by removing app.config.isCustomElement, and configuring vue-loader directly:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.compilerOptions = {
...options.compilerOptions,
isCustomElement: tag => tag.startsWith('bdl-')
}
return options
})
}
}
I meet the problem because element-plus icon component not called correctly. I have to import ElementPlusIconsVue in my main.js and global register it like the following:
import * as ElementPlusIconsVue from '#element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
// then I can call the icon in my vue file directly
<Refresh
style="width:30px;cursor: pointer;float: right;"
#click="get_bili"
/>
For performance issues I want to dynamically load a Vue directive.
But when I try to use the same method as for the dynamic components it doesn't work
directives: {
mydirective: () => {
return import('#/src/directives/mydirective.js');
}
}
// In a .vue file
If someone has already done that with success it could be nice to share.
Thanks 😊
is there a way how to write a custom directive in nuxt js, which will work for ssr and also for frontend (or even for ssr only)?
I tried it like in following documentation:
https://nuxtjs.org/api/configuration-render#bundleRenderer
so I added this code:
module.exports = {
render: {
bundleRenderer: {
directives: {
custom1: function (el, dir) {
// something ...
}
}
}
}
}
to nuxt.config.js
then I use it in template as:
<component v-custom1></component>
but it doesn't work, it just throw the frontend error
[Vue warn]: Failed to resolve directive: custom1
And it doesn't seem to be working even on server side.
Thanks for any advice.
If you want use custom directives in Nuxt you can do the following:
Create a file inside plugins folder, for example, directives.js
In nuxt.config.js add something like plugins: ['~/plugins/directives.js']
In your new file add your custom directive like this:
import Vue from 'vue'
Vue.directive('focus', {
inserted: (el) => {
el.focus()
}
})
How To Create A Directive
You can make directives run on the client by adding the .client.js extension to your directives file. This works for SSR and static rendering.
// plugins/directive.client.js
import Vue from 'vue'
Vue.directive('log-inner-text', {
inserted: el => {
console.log(el.innerText)
}
})
How To Insert Directives
In your nuxt.config.js file add it as a plugin like this.
plugins: [
'~/plugins/directive.client.js'
]
Don't forget to save your directive in the plugins folder.
How To Use A Directive
<div v-log-inner-text>Hello</div>
Console logs
> "Hello"
I have written a medium article that goes a lot more in-depth on how this works. It shows you how to make a directive that makes an element animate into view on scroll: Nuxt - Creating Custom Directives For Static & SSR Sites
Tested in nuxt-edge ( its nuxt 2.0 that will be out in this or next month, but its pretty stable as it is).
nuxt.config.js
render: {
bundleRenderer: {
directives: {
cww: function (vnode, dir) {
const style = vnode.data.style || (vnode.data.style = {})
style.backgroundColor = '#ff0016'
}
}
}
}
page.vue
<div v-cww>X</div>
Resulting html from server:
<div style="background-color:#ff0016;">X</div>
For anyone else coming here, the accepted answer allows you to run an SSR-only directive. This is helpful but a little unintuitive if you want to have a directive run everywhere.
If you only use nuxt.config.js to implement a directive via render, it will not be supported on the client-side without also adding a directive plugin and adding it to the config (see the How to Create a Directive Answer).
To test this out, try this experiment:
Follow the instructions to create directive using plugins (make one called loading)
Vue.directive('loading', function (el, binding) {
console.log('running loading directive client side')
})
Add this to your nuxt.config:
render: {
bundleRenderer: {
directives: {
loading (element, binding) {
console.log('running loading directive server side')
}
}
}
}
Use the directive on a Vue page file like:
<div v-loading="true">Test</div>
On page load, you will see both the client-side and SSR directives run. And if you remove the client-side directive, you will see errors thrown like the OP had: [Vue warn]: Failed to resolve directive: loading.
Tested on nuxt 2.12.2.