"Failed to resolve directive: transition" when trying to use a transition with vue-router - css-transitions

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">

Related

Unit Testing Login Vue Jest ValidationProvider

I am new to Jest and I am trying to mock the store, an action and to assert that the method was indeed called. Basically I want to check the login function.
I cannot query the button because I am retrieving only a part of the component and I don't know what I'm missing.
Where my Vue component looks like:
<ValidationObserver id="observer" v-slot="{ invalid }" :class="['w-full h-full']">
<form class="flex flex-col justify-around h-full" #submit.prevent="onSubmit">
<ValidationProvider v-slot="{ errors }" name="accessCode" :class="['w-full py-6']">
<sd-field :class="['sd-field_secondary', { ['sd-invalid ']: errors && errors.length > 0 }]">
<label for="email">{{ $t("form.access-code") }}</label>
<sd-input v-model="accessCode" type="accessCode" />
<span class="sd-error">{{ errors[0] }}</span>
</sd-field>
</ValidationProvider>
<div class="btn-group-y">
<button class="btn btn-fixed btn-blueDark" type="submit">
<span>{{ $t("account.login") }}</span>
</button>
<!-- <button class="btn btn-link" type=""> //TODO: temporary hide
<span>{{ $t("account.forgot_id") }}</span>
</button> -->
</div>
</form>
</ValidationObserver>
***MY TEST FILE***
import login from "../../pages/index/login";
import Vuex from "vuex";
import { mount, createLocalVue } from "#vue/test-utils";
const localVue = createLocalVue();
localVue.use(Vuex);
describe("Login form", () => {
it("calls the login action correctly", () => {
const loginMock = jest.fn(() => Promise.resolve());
const store = new Vuex.Store({
actions: {
onSubmit: loginMock,
},
});
const wrapper = mount(login, { localVue, store, stubs: { ValidationObserver: true } });
console.log(wrapper.html());
// wrapper.find("button").trigger("click");
// expect(loginMock).toHaveBeenCalled();
});
});
console.log(wrapper.html()) returns only a part of component
<div class="h-full w-full"><validationobserver id="observer"
class="w-full h-full"> </validationobserver>
</div>
With a warning also:
> console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
> [Vue warn]: Unknown custom element: <ValidationObserver> - did you register the
> component correctly? For recursive components, make sure to provide the "name" option.
> found in
> ---> <Anonymous>
> <Root>
I would like to understand how this works, I have tried to stub and other ways found but with no success.
I can get rid of the warning by adding the stubs: { ValidationObserver: true } to mount but I actually need to access the elements inside.
Thank you!

How to access Vue-test-util console error

I am using Jest to test this Vue component:
import { mount } from '#vue/test-utils'
import ExampleComponent from '../Components/Example.vue'
describe("Test", () => {
it('shows no errors', () => {
jest.spyOn(global.console, 'error');
jest.spyOn(global.console, 'warn');
mount(ExampleComponent)
expect(console.warn).not.toHaveBeenCalled()
expect(console.error).not.toHaveBeenCalled()
})
})
I am expecting this test to Fail since I have this component:
Example.vue
<template>
<div>
{{ number }}
</div>
</template>
<script>
export default {}
</script>
as you can see number is not defined, and if opened this component using the browser it will show me:
[Vue warn]: Property or method "number" is not defined on the instance but referenced during render.
but if I test it, the test will pass. How can If the Vue component has warnings or errors?

Vue warn: property or method 'processLogout' is not defined on the instance but defined during render

I'm having an issue with Vue. At this point I've read things like this detailing this error occurring when you try to define a method on the root instance, then reference it in local scope.
My issue is slightly different because it is defined in local scope, so I'm not sure what to make of this error. I've also looked at this, and this.
Here is my App.vue:
<template>
<div id="app">
<router-link to="/Home">home</router-link>
<router-link to="/Login">login</router-link>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
console.log('app.vue loading')
</script>
My main.js:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import store from './store'
import router from './router'
import Home from './components/Home'
import Login from './components/Login'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App, Home, Login },
template: '<App/>'
})
console.log('main js loading');
The component the issue is coming from:
<template>
<div class="login">
<head>
<title>{{title}}</title>
</head>
<form for="login" id="loginMain">
<label for="username">Username:</label>
<input type="text" id="username"></input>
<label for="password">Password:</label>
<input type="password"></input><br/><br/>
<button for="login" #click="processLogin">LOGIN</button>
<button for="logout" #click="processLogout">LOGOUT</button>
</form>
<p> Your login status: {{ loginStatus }} </login></p>
</div>
</template>
<script>
import Vue from 'vue'
import { mapGetters, mapActions, Vuex } from 'vuex'
import store from '#/store'
const Login = {
delimiters: [ '[{','}]'],
data () {
title: 'Foo',
msg: 'Bar'
}
name: 'Login',
props: {
// worry about this later
},
methods: {
...mapActions({
processLogin : 'LOGIN_ACTION',
processLogout : 'LOGOUT_ACTION'
})
},
computed: {
...mapGetters({
title: 'GET_TITLE',
loginStatus: 'GET_LOGIN_STATUS'
}),
}
}
console.log('Login loading');
export default Login
And although I'm unsure if it is related, but my store:
import Vue from 'vue'
import Vuex from 'vuex'
import Home from './components/Home'
import Login from './components/Login'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
title: 'My Custom Title',
loggedIn: false
},
mutations: {
MUT_LOGIN: (state) => {
state.loggedIn = true
},
MUT_LOGOUT: (state) => {
state.loggedIn = false
}
},
actions: {
LOGIN_ACTION ({ commit }){
store.commit('MUT_LOGIN')
},
LOGOUT_ACTION ({ commit, state }) {
store.commit('MUT_LOGOUT')
}
},
getters: {
GET_LOGIN_STATUS: state => {
return state.loggedIn
},
GET_TITLE: state => {
return state.title
}
}
})
console.log('store loading');
export default store
I know that I had some of these errors at one point and got rid of them by revisiting each import statement and making some corrections to how I had things hooked up. The only other difference between now and then is that I am running all of these files through Webpack and serving them with Django in a template. (The reason for all the consoles, making sure all the files got in there via Webpack.)
The image below is a couple of the specific things it is barking about.
Because of the link from the devtools error, I have looked at this and also experimented with adding local data () properties to the component itself.
Changing
data () {
title: 'Foo',
msg: 'Bar',
},
to
data () {
return {
title: 'Foo',
msg: 'Bar',
}
},
will fix the "title" error.
As for the issue with the actions nothing is jumping out at me. Can you try mapGetters and see if you have access to the getters?

rendering a rails partial in a .vue file

After struggling for a while, I was able to get Vue working with webpacker in my Rails 4.2.5 app. This is my first Vue project and I am still unsure of a lot of things when using it.
I am using Buefy, which are Vue.js components based on Bulma CSS (https://buefy.github.io/#/documentation/tabs). I have some tabs setup inside of a modal and I want each tab to render a form for a different partial, however, I don't know how to set this up as Vue can't run the ruby code. The result of this code is that the tabs work properly, but my Ruby render code is shown as a string and not run.
I could just copy the contents of the partials into the vue.js file, but there is still more ruby I am calling in there. I am sure there is a proper way to do all of this, but I just can't figure it out.
Here is my html/haml file calling the modal
#buefy
= javascript_pack_tag 'buefy_modal'
Here is my buefy_modal.js
import Vue from 'vue'
import App from './B_modal.vue'
import Buefy from 'buefy'
Vue.use(Buefy)
new Vue({
el: '#buefy',
render: h => h(App)
})
and here is the B_modal.vue
<template>
<section>
<button class="button is-primary is-medium"
#click="isCardModalActive = true">
Social Save
</button>
<b-modal :active.sync="isCardModalActive" :width="640" has-modal-card>
<div class="card">
<div class="card-content">
<section>
<b-tabs v-model="activeTab">
<b-tab-item label="Lists">
<%=render partial: 'shared/list_item/list_form', locals: {media: #media} %>
</b-tab-item>
<b-tab-item label="Clubs">
<%=render partial: 'shared/club_item/club_form', locals: {media: #media} %>
</b-tab-item>
<b-tab-item label="Challenges">
<%=render partial: 'shared/challenge_item/challenge_form', locals: {media: #media} %>
</b-tab-item>
</b-tabs>
</section>
</div>
</div>
</b-modal>
</section>
</template>
<script>
export default {
data() {
return {
isCardModalActive: false,
activeTab: 0,
}
}
}
</script>
Maybe try to rename file to something.vue.erb

Using Jest to mock a component which has other components as properties

I'm trying to mock react-bootstrap <Modal> component with jest. <Modal> contains some "sub-components" as properties, for example <Modal.Header>. I'm trying to find out the correct way to mock this kind of components using Jest.
Here's a simple component using <Modal>:
// mymodal.js
import React from 'react'
import {Modal, Button} from 'react-bootstrap'
const MyModal = ({ visible, hide, title, onOk }) =>
<Modal show={visible} onHide={hide}>
<div className='simple-modal'>
<Modal.Header closeButton>{title}</Modal.Header>
<Modal.Body>
<div>I'm body</div>
</Modal.Body>
<Modal.Footer>
<Button className='invert-primary' onClick={hide}>
Cancel
</Button>
<Button bsStyle='primary' onClick={onOk}>
Ok
</Button>
</Modal.Footer>
</div>
</Modal>
export default MyModal
And here's basic snapshot test for it:
// mymodal.test.js
import renderer from 'react-test-renderer'
import * as React from 'react'
import MyModal from './mymodal'
jest.mock('react-bootstrap', () => {
function Modal(props) {
return <div>{props.children}</div>
}
Modal.Header = 'Modal.Header'
Modal.Body = 'Modal.Body'
Modal.Footer = 'Modal.Footer'
return({
Modal: Modal,
Button: 'Button',
})
})
describe('MyModal component', () => {
test('should render a modal', () => {
const modal = renderer.create(<MyModal
visible={true}
hide={() => ''}
onOk={() => ''}
title='Title' />)
expect(modal.toJSON()).toMatchSnapshot()
})
})
And here's snapshot:
// Jest Snapshot v1
exports[`MyModal component should render a modal 1`] = `
<div>
<div
className="simple-modal"
>
<Modal.Header
closeButton={true}
>
Title
</Modal.Header>
<Modal.Body>
<div>
I'm body
</div>
</Modal.Body>
<Modal.Footer>
<Button
className="invert-primary"
onClick={[Function]}
>
Cancel
</Button>
<Button
bsStyle="primary"
onClick={[Function]}
>
Ok
</Button>
</Modal.Footer>
</div>
</div>
`;
I'm quite happy with the snapshot result, but I'd like to get better output for the <Modal> component itself so that the snapshot would contain also component's name (currenlty <div>) and props (currently no props shown).
How should the mocking be done to achieve this?
I couldn't find way to achieve this with jest mocking. Finally I went with enzyme shallow rendering, which handles the basic mocking out of box. To do spanshot matching, I serialized the enzyme wrappers using enzyme-to-json npm package.