I'have this template in my vue.js 2.0 app:
<template>
<div>
<button class="xs:w-full md:w-auto button-main" #click="show = true">
Open filters
</button>
<portal to="port-details">
<div class="modal" v-if="show">
<p>jow</p>
</div>
</portal>
</div>
</template>
I need to remove the surrounding div because otherwise my markup looks weird. But if I remove that I obviously will get this error:
Component template should contain exactly one root element
How could I accomplish this?
Related
Im making my first vue modal and I want to make a simple pop up window when you click on a button. I followed a tutorial but it wouldnt work. Then I tried others and... same result. I have no idea what I'm doin wrong!
My modal component code in the template:
<div class="save-btn">
<button #click="showModal = true">Save</button>
</div>
<transition name="modal-fade">
<div class="modal-overlay" #click="$emit('close-modal')">
<div class="modal" #click.stop>
<h6>Saved!</h6>
<p>Your Details have been saved Successfully</p>
<button>Go Home</button>
</div>
<div class="close" #click="$emit('close-modal')">
<img class="close-img" src="" alt="" />
</div>
</div>
</transition>
My modal compant code in the script:
data () {
return {
showModal: false
}
}
When I click the button :
<div class="save-btn"><button u/click="showModal = true">Save</button></div>
absolutely nothing happens and I have no idea why!
You are missing v-if for your Transition
<div v-if="showModal" class="modal-overlay" #click="$emit('close-modal')">
Also you should stick to the regular syntax so use Transition instead of transition since it is a component.
Here is the working demo of your code
Version: Vue 3.0.5
index.html.twig
<div id="app">
<div class="text-center">
<h3>My text rendered in Twig</h3>
<div class="jumbotron text-center">
<example></example>
</div>
</div>
</div>
</div>
entry-file.js
import { createApp } from 'vue';
import Example from './components/Example.vue'
createApp(Example).mount('#app');
components/Example.vue
<template>
<div>
<p>This is text from VueJs component</p>
</div>
</template>
<script>
export default {
name: 'example'
}
</script>
Currently, when I access the page Vue completely removes Twig content inside #app div and replaces it with text from the component.
My question are,
How can I keep initial #app content rendered by Twig and additionally compile <example></example> component by Vue?
Is it OK practice to mix it this way? The problem is that I already have blocks/widgets and custom logic based on backed variables in Twig and it will be far too long to rewrite everything in Vue
I have a 3 tabs Account Information, Address Book, and Payment Options like this,
function AccountDetails() {
return (
<div className="account__details">
<AccountDetailsTabs>
<div label="Account Information">
<AccountInformation></AccountInformation>
</div>
<div label="Address Book">
<AddressBook></AddressBook>
</div>
<div label="Payment Options">
<PaymentOptions></PaymentOptions>
</div>
</AccountDetailsTabs>
</div>
);
}
Now, when clicked in the Account Information Tab, it renders the AccountInformation component
import React from "react";
import "./AccountInformation.css";
function AccountInformation() {
return (
<div className="account__information">
<div className="account__information__instruction">
Please update your personal account details, update your address book or
change your email setting here.
</div>
<div className="account__information__container">
<div className="userDetails">
<span>
{" "}
<strong>First Name:</strong>{" "}
</span>
<span>Aman</span>
</div>
</div>
<div className="account__information__buttons row justify-content-between">
<div className="edit__button__container col-6">
<button className="edit__button">EDIT</button>
</div>
<div className="changepassword__button__container col-6">
<button className="changepassword__button">CHANGE PASSWORD</button>
</div>
</div>
</div>
);
}
export default AccountInformation;
The image below illustrates it,
As I am inside the Account Information tab, inside this tab there are EDIT & CHANGE PASSWORD buttons.
Now, when I click on the EDIT or CHANGE PASSWORD buttons the tab should render the EdIT component keeping all things in the page same. How can I do that?
I am known to the react-router but I don't think this is the good practice using react-router here because there are many other components in the page.
When clicked on one of the button, it should give the following result.
It would be even great, if you could give link from reactjs official doc to know more about it. Thanks.
Just make the two sections different components. If you have a component that isn't changing or is the background/backdrop, you could make it the parent. Or you could make them siblings with another component wrapping around both
I'm trying to create a re-usable base modal component and make use of slots to provide the modal content... It creates the application and modal. On button click the modal displays, but without the content. How can I get my content to display within the content specified slot? Am I using slot's incorrectly?
Here's a fiddle to help illustrate my problem : https://jsfiddle.net/70yyx8z2/19/
// register base modal component
Vue.component('modal', {
template: '#modal-template'
})
// register content component for modal
Vue.component('modal-content', {
template: '#modal-content'
})
// start app
new Vue({
el: '#app',
data: {
showModal: false
}
})
<modal v-if="showModal" #close="showModal = false">
<h3 slot="header">Header here</h3>
<!--
How can I use slot to render the modal content component?
-->
<modal-content></modal-content>
</modal>
JsFiddle Working Example
You can't specify a slot name inside the component as it won't be mounted before the slot replacement takes place. Instead you can assign the component to the slot
<!-- modal content component -->
<script type="text/x-template" id="modal-content">
<form>
<h2>This should show...</h2>
<input type="text" placeholder="user name" />
</form>
</script>
<!-- app -->
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<!-- use the modal component, pass in the prop -->
<modal v-if="showModal" #close="showModal = false">
<h3 slot="header">Header here</h3>
<!--
How can I use slot to render the modal content component?
-->
<modal-content slot="body"></modal-content>
</modal>
</div>
EDIT: Fixed a small bit of nomenclature related issue as noticed by #thanksd
Technically all you need to do is this.
<modal-content slot="body"></modal-content>
You probably want to remove the modal-container from the modal-content component.
Here is your fiddle updated.
I'm pretty new to angular, and I'm trying to create a modal as a component (trying not to use ui-bootstrap or libraries) and I'm having trouble wrapping my head around it. My code:
App.component('modal', {
templateUrl: '../modal.html',
controller: ChocoListCtrl
});
I have a modal.html which I want to reference my controller which displays items inside a cart:
<h2>Your Cart</h2>
<div ng-if="!cart.length">
There are no items in your cart
</div>
<div class="col-lg" ng-repeat="item in cart | unique : 'type'">
<div class="col-md">
<span>Type: </span>
<strong>{{item.type}}</strong>
</div>
<div class="col-md">
<strong>${{item.price}}</strong>
</div>
<div class="col-md">
<span>Quantity: </span>
<strong>{{item.quantity}}</strong>
</div>
<div class="col-md">
<button ng-click="removeItem()">Remove</button>
</div>
</div>
However that's really the extent of my knowledge. I'm not sure how to make the modal popup work or even start it. Any guidance would be greatly appreciated!
It looks like you've defined your component well, all you have left to do is rig up the trigger:
<modal ng-if="showModal"></modal>
<button ng-click="showModal = !showModal">Show Modal</modal>
This may change based on the configuration of the parent element, but it's the same idea.
Then style the modal in such a way that it pops up in the desired location. position:fixed, etc.
You may want to consider dropping a backdrop behind the modal that has an ng-click attached to it to close the modal.