I want to write a directive in nuxts.js and want to add it via the plugins array in the nuxt.config file, but then my directive doesn't get resolved...
//plugins/myGlobalDirective.js
import Vue from 'vue'
Vue.directive('my-global-directive', {
inserted: function(el) {
console.log('my-global-directive')
}
})
//nuxt.config.js
plugins: [
'~plugins/myGlobalDirective.js'
],
//component
<template>
<p v-my-global-directive>lala</p>
</template>
that doesn't work.
But if I import it directly in the component it works ( I can also remove it from the plugins array)
//component
<template>
<p v-my-global-directive>lala</p>
</template>
<script>
import '~/plugins/myGlobalDirective.js'
</script>
What I'm doing wrong?
Problem solved
I have to restart the server if I change something in the nuxt.config file...
And it works with or without the the '/'
Related
I have this structure for a Vue app:
App.vue
-> Router View(with two child components)
App.vue
<template>
<div id="app" #click="mutateStore(null)">
<router-view #storeUpdate="mutateStore"/>
</div>
</template>
<script>
export default {
name: 'app',
methods:{
mutateStore(){
this.$store.commit('increment')
}
},
mounted(){
this.$store.commit('increment')
}
}
</script>
<style>
...styles
</style>
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
type: 1
},
mutations: {
increment (state) {
state.type++
}
}
})
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Main from '#/components/Childcomponent1'
import Display from '#/components/Childcomponent2'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Childcomponent1',
component: Main
},
{
path: '/display',
name: 'Childcomponent2',
component: Display
}
]
})
In Child Component 1, I have a button where if clicked would do:
this.$emit("storeUpdate")
which triggers the event handler mutateStore() in App.vue
In Vue Dev Tools, it also shows the state.type with the incremented value
In Child Component 2, I display directly the state.type value as computed:
<template>
<div class="main">
{{type}}
</div>
</template>
<script>
export default {
name: 'Childcomponent2',
computed: {
type () {
return this.$store.state.type
}
}
}
</script>
<style scoped>
..Styles
</style>
But the value never got updated in Child Component 2, not even when viewed in Vue Dev Tools.
And one curious observation, when the same commit in App.vue is called in mounted(), it increments the state.type all across the two child components, but when via method mutateStore(), it does update in Child Component 1, but the change is not detected in Child Component 2.
Note that before I did the emit/event handler part in the App.vue, I already tried mutating the store directly from within the Child Component but to no effect that's why I tried the emit event handler instead.
Did I do anything incorrectly?
Please help!
Found it. Turns out I had wrongly assumed that Vuex standard has built in support for shared states across multiple browser windows using localStorage. Apparently it only does share state across multiple components in the SAME browser tab/window. To allow for multiple browser support, a plugin must be added: vuex-shared-mutations
npm install vuex-shared-mutations
I am using Vue.js 2.0, and I have this exact same code in 2 differents files, the only thing that changes is the ID_SPECIFIC_TO_THIS_BLOCK so I am a beginner about Vue and I was wondering if there was an way to implement a kind of template that I would be able to reuse for my 2 files
You can find bellow the entire code for one file:
<template>
<div>
<div class="container">
<hp-row>
<hp-column>
<component v-for="component in content.column" :data="component" :key="component.id" :is="getComponentIdentifier(component.is)"></component>
</hp-column>
</hp-row>
</div>
</div>
</template>
<script>
import ModularView from '#/views/ModularView'
export default {
name: 'AboutUsView',
mixins: [ModularView],
created () {
this.fetch('blocks/ID_SPECIFIC_TO_THIS_BLOCK')
},
}
</script>
Use props:
export default {
name: 'AboutUsView',
mixins: [ModularView],
props: ['ID_SPECIFIC_TO_THIS_BLOCK']
created () {
this.fetch(`blocks/${this.ID_SPECIFIC_TO_THIS_BLOCK}`)
},
}
<about-us-view ID_SPECIFIC_TO_THIS_BLOCK="123"></about-us-view>
<about-us-view ID_SPECIFIC_TO_THIS_BLOCK="789"></about-us-view>
I try to get working the electron-vue boilerplate. After setting up the project everything works, but as I create a new .vue file (TopMenu.vue) I get:
vue.common.js?4eb4:2569 [Vue warn]: Unknown custom element: <topmenu> -
did you register the component correctly? For recursive components, make
sure to provide the "name" option. (found in component <landing-page>)
I use the exact syntax as the original .vue files which came with the boilerplate:
LandingPageVue.vue:
<style scoped>
img {
margin-top: -25px;
width: 450px;
}
</style>
<template>
<div>
<!-- <img src="./LandingPageView/assets/logo.png" alt="electron-vue"> -->
<h1>Welcome.</h1>
<topmenu></topmenu>
<current-page></current-page>
<versions></versions>
<links></links>
<div class="container">
</div>
</template>
<script>
import TopMenu from './LandingPageView/TopMenu'
import CurrentPage from './LandingPageView/CurrentPage'
import Links from './LandingPageView/Links'
import Versions from './LandingPageView/Versions'
export default {
components: {
TopMenu,
CurrentPage,
Links,
Versions
},
name: 'landing-page'
}
</script>
TopMenu.vue (my file):
<template>
<p>
TOPMENU
</p>
</template>
By the way, how the hack does <current-page></current-page> work (notice the "-" dash) if bellow it is declared without?
It's not working because you're not exporting anything in your vue file.
Try this in your TopMenu.vue file:
<template>
<p>
TOPMENU
</p>
</template>
<script>
export default {
}
</script>
Also change the html <topmenu></topmenu> to <top-menu></top-menu>
For your second question, HTML is case insensitive so your title case components wouldn't match with html tags. So Vue translates your title case components to a 'dash-case'.
From the documentation itself there's the explanation why:
Note that Vue does not enforce the W3C rules for custom tag names (all-lowercase, must contain a hyphen) though following this convention is considered good practice.
You can read more from the the docs
I've got a vue app in which I'm using the vue-router.
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
let router = new VueRouter()
// Components
import App from './App.vue'
import Mapper from './components/Mapper/mapper.vue'
import ToDos from './components/Todos/ToDoApp.vue'
import Punchlist from './components/Punchlist/punchlist.vue'
// Transitions
Vue.transition('slide',{
enterClass: 'slideInRight',
leaveClass: 'slideOutRight'
})
// Redirects
router.redirect({
'*': 'punchlist'
})
// Mappings
router.map({
'/mapper': {
component: Mapper
},
'/todos': {
component: ToDos
},
'/punchlist': {
component: Punchlist
}
})
router.start(App, '#app')
I have a specific transition registered called slide that I would like to use when navigating between routes. In my App component I added the v-transition and transition-mode directives to the route-view:
<template>
<div class="container">
<h1>Component Gallery</h1>
<p>
<a class='btn btn-primary' v-link="{ path: '/punchlist' }">Punchlist</a>
<a class='btn btn-primary' v-link="{ path: '/todos' }">Todos</a>
<a class='btn btn-primary' v-link="{ path: '/mapper' }">Mapper</a>
</p>
<router-view v-transition="slide" transition-mode="out-in" :google-maps-api-key="googleMapsApiKey"></router-view>
</div>
</template>
When I try to run it, I get the console error:
[Vue warn]: Failed to resolve directive: transition (found in component: )
I've been reading through the docs and looking at examples but I can't figure out why it's erroring out when trying to resolve the binding.
Any ideas?
Transition is an attribute, not a directive. No v-:
<router-view transition="slide">
I have this as my router.js. Note that it has no application route:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('todos', { path: '/'});
});
export default Router;
When I hit the home path, I see my application.hbs template and the todos.hbs template is loaded in the outlet. This is my application.hbs:
<section id="todoapp">
<header id="header">
<h1>todos header in application.hbs</h1>
</header>
{{outlet}}
</section>
<footer id="info">
<p>
Footer in application.hbs. Double-click to edit a todo
</p>
</footer>
Why does my application.hbs get loaded?
I assume Ember knows to also load the todos.js in my routes folder which is this:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
let todos = [
{
title: 'Learn Ember',
complete: false,
},
{
title: 'Solve World Hunger',
complete: false,
}
];
return todos;
}
});
And this is my todos.hbs template:
<h2>Todos Template</h2>
<ul>
{{#each model as |todo|}}
<li>
{{todo.title}}
</li>
{{/each}}
</ul>
Main questions
1. Why does my application.hbs get loaded when I hit the home route?
2. What is export default mean?
3. What is the line import Ember from 'ember' doing? Where is 'ember' coming from?
The application route is loaded in every Ember.js application. See http://guides.emberjs.com/v2.1.0/routing/defining-your-routes/#toc_the-application-route
export default is part of the ES6 module specification. See http://exploringjs.com/es6/ch_modules.html It takes the object or variable to be returned as the default thing to be imported when that module is imported inside another module.
The 'ember' namespace is built into Ember CLI. Its default export is itself, the Ember variable, which was once a global variable in prior versions of Ember.