I have a problem when I change routes. Between pages it renders me fine. But when I need a dynamic route it does not render me.
In routes I have the folder uw and inside [table].js
When I put the manual routes uw/first and I want to go to uw/second, the first one does render well and then the second one sticks to the style of the first one and it does not bring me the correct data for that view
const menuItems = [
{
href: '/dashboard',
title: 'Inicio',
icon: 'fluent:home-16-filled',
},
{
href: '/uw/primera' ,
title: 'Cartera',
icon: 'bxs:user',
},
{
href: '/uw/segunda',
title: 'Cartera',
icon: 'bxs:user',
},
];
and then return the routes
<div>
<aside className="main-aside">
<div className="main-aside-image">
<Image
src="/logo-castor.png"
alt=""
width={198}
height={32}/>
</div>
<nav>
<ul className="main-aside-items">
<div className="main-aside-categories">
{menuItems.map(({ href, title, icon }) => (
<li className="main-aside-item-categories" key={title}>
<Link href={href}>
<a
className={`flex p-2 bg-fuchsia-200 rounded hover:bg-fuchsia-400 cursor-pointer ${
router.asPath === href && 'bg-fuchsia-600 text-white'
}`}
>
{title}
</a>
</Link>
</li>
))}
</div>
</ul>
</nav>
</aside>
</div>
You're using the title as the key inside the map, since the title is the same between uw/primera and uw/segunda it won't update the component.
Changing the key to the href could solve that.
<li className="main-aside-item-categories" key={title}>
to
<li className="main-aside-item-categories" key={href}>
Related
I'm trying to create a function that selects an HTML element and changes the value in it to the value in another element using the ref, state, and effect hooks but I can't get the right effect I want
const Service = () => {
const [selected, setSelected] =
useState(false);
let change = useRef(null);
const[title, setTitle] = useState("");
useEffect(() => {
setTitle(change.current.children(0))
})
const Changer = (e)=>{
e.preventDefault()
const style = e.target;
if(selected === false){
console.log(`you clicked ${style}`);
}
setSelected( current => !current);
// let style={background: selected ?
'#6EEFB1' : ''};
// if (selected === true){
// setSelected(false)
// // let style= {styleObject.li}
// }else{
// setSelected(true)
// }
}
return(
<section className={selected ?
"serviceClicked" : "services"}>
<h1>Our Services</h1>
<div className='service-content'>
<div className='service-text' ref=.
{change}>
<h2></h2>
<p>
Syse infrans att dedade. Redar
fäsat. Älogi hypol. Antere
nydavarat och hemil.
Dist kyning. Kroska
bröllopskoordinator. Teletotal.
Mor tin.
</p>
<p>
Spejörar befaladat. Lavis
kvasideledes.
Dande dak. Anteck ur dick.
Skurkstat larad henifiera. Belogi
koliga selig.
</p>
</div>
<div className='service-list'>
<ul id='top-list'>
<li onClick={Changer}>
<img src={oby} />
{/* <div></div> */}
<p>ob/gyn</p>
</li>
<li onClick={Changer}>
<img src={neuro} />
{/* <div></div> */}
<p>neurology</p>
</li>
<li onClick={Changer}>
<img src={peds} />
{/* <div></div> */}
<p>pediatrics</p>
</li>
</ul>
<ul id='bottom-list'>
<li onClick={Changer}>
<img src={dental}/>
{/* <div></div> */}
<p>dental care</p>
</li>
<li onClick={Changer}>
<img src={cardio} />
{/* <div></div> */}
<p>cardiology</p>
</li>
<li onClick={Changer}>
<img src={ent} alt='E.N.T' />
{/* <div></div> */}
<p>ent</p>
</li>
</ul>
</div>
</div>
</section>
)
};
The h2 tag is meant to take on the value of the p tags under the li element when clicked, I've figured out how to make the content in the service text shown when the li element is clicked.
what's troubling is how to change the value of the h2 tag to whatever value the p tag of which li element is clicked.
CodeSandBox Example
Instead of using useEffect, useRef, you could simply use your useState to do all that.
I created a constant to make my/your life easier and just map though the elements (you don't need this, but I would recommend it)
const IMAGES = [
{ src: "oby", name: "ob/gyn" },
{ src: "neuro", name: "neurology" },
{ src: "peds", name: "pediatrics" },
{ src: "dental", name: "dental care" },
{ src: "cardio", name: "cardiology" },
{ src: "ent", name: "ent" }
];
<section className={title ? "serviceClicked" : "services"}>
<h2>{title}</h2>
...
<ul id="top-list">
{IMAGES.map(({ src, name }) => {
return (
<li
key={name}
onClick={() => {
setTitle(name);
}}
>
<img src={src} />
<h3>{name}</h3>
</li>
);
})}
</ul>
...
</section>
You would really want to use useRef if there's need to interact directly with the element, otherwise when dealing with only data useState/useEffect is more than enough.
well i'm new to vue js and developing an application with a search function.
This is my component where the search results will be rendered.
<script>
import RecipeItem from "../recipe/RecipeItem";
import { baseApiUrl } from "#/global";
import axios from "axios";
import PageTitle from "../template/PageTitle";
export default {
name: "Search",
components: { PageTitle, RecipeItem },
data() {
return {
recipes: [],
recipe: {},
search: '',
}
},
methods: {
getRecipes() {
const url = `${baseApiUrl}/search?search=${this.search}`;
axios(url).then((res) => {
this.recipes = res.data;
});
}
},
watch: {
search() {
const route = {
name: 'searchRecipes'
}
if(this.search !== '') {
route.query = {
search: this.search
}
}
},
'$route.query.search': {
immediate: true,
handler(value) {
this.search = value
}
}
},
};
</script>
<template>
<div class="recipes-by-category">
<form class="search">
<router-link :to="{ path: '/search', query: { search: search }}">
<input v-model="search" #keyup.enter="getRecipes()" placeholder="Search recipe" />
<button type="submit">
<font-icon class="icon" :icon="['fas', 'search']"></font-icon>
</button>
</router-link>
</form>
<div class="result-search">
<ul>
<li v-for="(recipe, i) in recipes" :key="i">
<RecipeItem :recipe="recipe" />
</li>
</ul>
</div>
</div>
</template>
ok so far it does what it should do, searches and prints the result on the screen.
But as you can see I created the search field inside it and I want to take it out of the search result component and insert it in my header component which makes more sense for it to be there.
but I'm not able to render the result in my search result component with my search field in the header component.
but I'm not able to render the result in my search result component with my search field in the header component.
Header component
<template>
<header class="header">
<form class="search">
<input v-model="search" #keyup.enter="getRecipes()" placeholder="Search recipe" />
<router-link :to="{ path: '/search', query: { search: this.search }}">
<button type="submit">
<font-icon class="icon" :icon="['fas', 'search']"></font-icon>
</button>
</router-link>
</form>
<div class="menu">
<ul class="menu-links">
<div class="item-home">
<li><router-link to="/">Home</router-link></li>
</div>
<div class="item-recipe">
<li>
<router-link to="/"
>Recipes
<font-icon class="icon" :icon="['fa', 'chevron-down']"></font-icon>
</router-link>
<Dropdown class="mega-menu" title="Recipes" />
</li>
</div>
<div class="item-login">
<li>
<router-link to="/auth" v-if="hideUserDropdown">Login</router-link>
<Userdropdown class="user" v-if="!hideUserDropdown" />
</li>
</div>
</ul>
</div>
</header>
</template>
Result component
<template>
<div class="recipes-by-category">
<div class="result-search">
<ul>
<li v-for="(recipe, i) in recipes" :key="i">
<RecipeItem :recipe="recipe" />
</li>
</ul>
</div>
</div>
</template>
Keep the state variables in whatever parent component is common to both the header component and the results component. For example, if you have a Layout component something like this:
<!-- this is the layout component -->
<template>
<HeaderWithSearch v-on:newResults="someFuncToUpdateState" />
<ResultsComponent v-bind:results="resultsState" />
</template>
<!-- state and function to update state are in a script here... -->
When the search bar returns results you need to pass that data "up" to the parent component with an $emit call, then the parent component can then pass that state back down to the results component using normal props.
Check out this documentation: https://v2.vuejs.org/v2/guide/components-custom-events.html
Be sure to pay special attention to the .sync part of the documentation and determine if that's something you need to implement as well.
Unless you want to use a more complicated state management library like vuex (which shouldn't be necessary in this case) you can just keep state in a common parent and use $emit to pass up and props to pass down.
I know about the scrollBehavior function that Vue has, but I am unsure of how to use it with my code.
I have an Index page, where sections are made of imported vue components.
For example
<template>
<div class="Container">
<About />
<Services />
<Contact />
</div>
</template>
My Navbar has links to all these components.
<template>
<nav>
<img class="nav__logo" :src="navLogo" height="40px" width="auto">
<ul class="nav__row" ref="nav">
<div class="nav__row__dropdown-toggle-btn" #click="toggleNav">
<img :src="navMenuIcon" height="40px" width="auto">
</div>
<li class="nav__list-item" v-for="(link, index) in navLinks" :key="index"
#mouseover="hover = true"
#mouseleave="hover = false"
:class=" { active: hover } ">
<router-link :to="link.path">
{{ link.text }}
</router-link>
</li>
</ul>
</nav>
</template>
which it gets from my App.vue script
<script>
import Navbar from '#/components/Navbar'
import Footer from '#/components/Footer'
export default {
components: {
Navbar,
Footer
},
data: () => ({
navLinks: [
{
text: 'Home',
path: '/'
},
{
text: 'About',
path: '/about'
},
{
text: 'Contact',
path: '/contact'
},
{
text: 'Services',
path: '/services'
}
]
})
}
</script>
but if I click on "About" it will just take me to a seperate page for the "About" component.
When I click on "About" I want the page to scroll down to the imported About component that is nested on my Index page.
How can I accomplish this? Is it something I need to change in the path?
The idea of router that you trying to implement is actually treating About components as a page, and when clicking at it, it will go to that page (and change URL)
So, in order to implement what you want, I actually suggest using pure javascript
First, give the About component and id ( or ref if you prefer Vue ref)
<template>
<div class="Container">
<About id="about"/>
<Services />
<Contact />
</div>
</template>
Then bind a method to click event of nav
<li class="nav__list-item" v-for="(link, index) in navLinks" :key="index"
#mouseover="hover = true"
#mouseleave="hover = false"
:class=" { active: hover } ">
#click=nav(link)
</li>
data: () => ({
navLinks: [
{
text: 'About',
id: 'about'
}
]
}),
methods:{
nav(link) {
const position = document.getElementById(link.id).offsetTop;
// smooth scroll
window.scrollTo({ top: position, behavior: "smooth" });
}
}
If you prefer Vue ref, can change all id to ref. And use this.$refs[link.id].$el.offsetTop instead;
i found this video so useful,
my goal was able to scroll between component at the same page.
but still you can apply anywhere, i think
https://laracasts.com/series/practical-vue-components/episodes/1
My entire component is attached here:
https://gist.github.com/j42/392e63b275e1209ac269
The relevant render method from the component is below, for convenience:
render() {
let className = this.state.active ? 'active hidden-xs' : 'hidden-xs';
return (
<div id="git-flow" className={className}>
<div className="beanstalk-container">
<div className="beanstalk"></div>
<ul className="events">
<TransitionSpring
defaultValue={this.getDefaults()}
endValue={this.getEndValues()}>
{key => {
this.state.people.map(function(person, i) {
let deployFailed = (Math.round(Math.random()*1) <= 0.4),
headline = (deployFailed) ? 'PUSH BLOCKED' : 'PUSHED TO PRODUCTION',
className = (deployFailed) ? 'status negative' : 'status positive',
icon = (deployFailed) ? 'ion-android-close' : 'ion-android-checkmark-circle';
return (<li key={i}
className="person"
style={{
top: `-100px`,
opacity: `1`
}}>
<div className={className}>
<i className={icon}></i>
<div className="label-text">
<h4>{headline}</h4>
<h5><strong>Dec 15th, 2015</strong> — 5:00PM</h5>
</div>
<ul className="notifications">
<li className="notification">
<i className="ion-email-unread"></i>
<span>Group Leader Notified</span>
</li>
</ul>
</div>
<div className="image">
<img src={person.picture.medium} className="img-responsive" />
</div>
</li>);
});
}}
</TransitionSpring>
</ul>
</div>
</div>
);
}
The Problem:
This code runs without any errors, but only renders so far as ul.events. Within that is <noscript data-reactid=".2.0.1.0"></noscript> which leads me to believe React is encountering an error with the JS, and thus silently ignoring the bracketed content.
Everything looks normal to me though... I'm still a bit new to react, so is there something basic I'm overlooking? I just want to have a list of avatars that essentially fadeInDown within a TransitionSpring (so components can be added and removed)...
Thanks for the help!
use React Native Animated.
It's designed to work with React Native.
I'm creating a web-app using React. I'm facing a problem with my navbar and the main content:
In AppWrapper I have this:
var contents = [
<Offers />,
<Create />,
<List />
];
and where each item will be the content displaying.
In getInitialState I initialize it like this:
getInitialState: function() {
return {
currentTab: 0
};
},
Later, in render function I have this:
return (
<div>
<Navbar />
<div className='mainPanel'>
{contents[this.state.currentTab]}
</div>
</div>
);
You can see that I call the navbar component before the content.
In Navbar component I have a menu where, from there, I want to change the currentTab of AppWrapper.
How can I do that? Thank you for advance!
After trying to handle it, I found how to do that.
This is the answer:
<Navbar selectTab={this.selectTab} />
selectTab: function(tab) {
this.setState({ currentTab: tab });
}
I pass to Navbar component the function "selectTab of the parent (AppWrapper).
Then in Navbar component:
<li>
<a onClick={this.selectTab.bind(this, 0)}><i className="fa fa-dashboard fa-fw" /> Dashboard</a>
</li>
<li>
<a onClick={this.selectTab.bind(this, 1)}><i className="fa fa-edit fa-fw" /> Create</a>
</li>
Then in selectTab of Navbar I change the props to current tab.
selectTab: function(tab) {
this.props.selectTab(tab);
},
Hope someone helps this answer!