The relation between App.vue and Other component at Vuejs webpack - vue.js

I installed vuejs with webpack.
vue init webpack frontend
And I use vue-router at main.js
routes: [
{
path: '/',
name: 'Home',
component: HomeView
},
App.vue is like here.
<template>
<div>
<div id='toparea'></div>
<router-view></router-view>
<div id='btmarea'></div>
</div>
</template>
file structure here
Is the relation of App.vue and HomeView.vue patent-child relation ?
How can I use App.vue's data at HomeVuer.vue?
More specific:
I printed a variable at App.vue like this.
<div id='toparea'>
<span v-html="variable_foo"></span>
</div>
And I want to change at HomeView.vue at HomeView.vue's mounted step.

I found App.vue apparently is parent of HomeView.vue from vuejs devtool.
It means router view component is children of main app view component.

There is no special relation between App.vue and HomeView.vue. App.vue is for root component. HomeView is one of your components for rendering page. This component will be rendered on <router-view></router-view>. If you register some components on router, you can see them through router-view.
To pass Props you can check this: https://router.vuejs.org/guide/essentials/passing-props.html
Or you can use Vuex(https://vuex.vuejs.org/) for state management. App.vue and HomeView.vue can share their states with it.

Related

vue instance with child vue instance possible or alternative approach?

I would like to develop a vuejs multitouch app for a 4K display. It’s about 3-4 cards that are on a background and actually show the same content. For each of the cards a different entry page is visible.
Is it possible to pack several other instances (with the same content) of vuejs in divs within a Vue instance?
Somehow I would like to integrate an instance with store and router multiple times, but I can’t figure it out.
It would be helpful if someone can help me here, maybe provide a link or an approach.
I am looking for an approach how I can display the same content 3 times at the same time, at best with routes and nested routes. Each User can navigate separately, everyone has their own history via GUI.
when I try to use 2 instance inside the main vue instance 3 different routers, it’s always renders the content of main route.
I found this example where to instances are side by side, works great: https://jsfiddle.net/m91e7s2v/
but not inside a parent instance? why?
inside app.vue
<div id="app">
<VueToolMultitouch class="schatten" :startX="100" :startY="100" :startColor='"#00FF00"' id="id1" :idName="'id1'" :startZ="2">
<div id="subapp1">
<router-link to="/">/home</router-link>
<router-link to="/foo">/foo</router-link>
<p>Route path: {{ $route.path }}</p>
<router-view></router-view>
</div>
<h2>Passing Text 1</h2>
</VueToolMultitouch>
<VueToolMultitouch class="schatten" :startX="200" :startY="600" :startColor='"#FF0000"' id="id2" :idName="'id2'" :startZ="3">
<div id="subapp2">
<router-link to="/">/home</router-link>
<router-link to="/foo">/foo</router-link>
<p>Route path: {{ $route.path }}</p>
<router-view></router-view>
</div>
<h2>Passing Text 2</h2>
</VueToolMultitouch>
</div>
inside main.js
import router1 from "./router/router";
import router1 from "./router/router-1";
import router2 from "./router/router-2";
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
new Vue({
router: router1,
}).$mount("#subapp1");
new Vue({
router: router2,
}).$mount("#subapp2");
An alternative would be if everything is implemented with a single vue instance, but each of the cards gets its own "router".
maybe someone has an idea what that might look like.
The problem is that every child gets bound to the parent vue app and its prototype, this overrides the router of the children. I think that you'll need either to use iframes for the children or make the parent app handle with state the children views.
Edit:
I just learned about v-pre, this directive prevents Vue from "compiling" an HTML node and it's children.
You can basically have as many Vue instances even if they're nested as long as you put v-pre on the tag you use to mount the child Vue app.
Here's a working fiddle https://jsfiddle.net/dja36s7x/18/
I found an alternative way in the VueJS forum.
<div id="app">
<div class="row">
<my-child1></my-child1>
<my-child2></my-child2>
</div>
<div class="row">
<my-child3></my-child3>
<my-child4></my-child4>
</div>
</div>
const routes = [
{
path: '/page1',
component: { template: '<p>Page 1</p>' }
}, {
path: '/page2',
component: { template: '<p>Page 2</p>' }
}, {
path: '/page3',
component: { template: '<p>Page 3</p>' }
}
]
const MyChild = {
template: `
<div>
<router-link to="/page1">Page 1</router-link>
<router-link to="/page2">Page 2</router-link>
<router-link to="/page3">Page 3</router-link>
<button #click="$router.back()">Back</button>
<div>{{ $route.path }}</div>
<router-view />
</div>
`
}
function getChild() {
return {
extends: MyChild,
router: new VueRouter({
mode: 'abstract',
routes
})
}
}
new Vue({
components: {
MyChild1: getChild(),
MyChild2: getChild(),
MyChild3: getChild(),
MyChild4: getChild()
}
}).$mount('#app')
JSFiddle Example
Here, the components are expanded with their own router.
I currently no longer need the route via nested instances. but i will test the v-pre on everyone.
It seems this might be achieved using a hierarchy of components. If you're sure you need different Vue app instances, then it's worth going with Vue 3 as it's abandoned the idea of a shared global config, allowing you to create many Vue instances with createApp. All with different configurations.
You could do something like this (JS Fiddle here):
Vue.createApp({
name: 'App',
template: `
<h1>Primary App</h1>
<div id="subAppOne"></div>
<div id="subAppTwo"></div>
<div id="subAppThree"></div>
`
}).mount('#app');
Vue.createApp({
name: 'AppOne',
template: `<h2>App One</h2>`,
}).mount('#subAppOne');
Vue.createApp({
name: 'AppTwo',
template: `<h2>App Two</h2>`,
}).mount('#subAppTwo');
Vue.createApp({
name: 'App Three',
template: `<h2>App Three</h2>`,
}).mount('#subAppThree');
You can specify different routers with .use() on each app instance, just before calling mount().
const routerOne = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes: [/* … */],
});
Vue.createApp({/* … */}).use(routerOne).mount('#appOne');

How can i navigate between different pages using vue router?

I have just started learning Vue. I actually became confused with the Vue router part. It's a very simple question. I tried looking for many docs and tuts but didn't find anything that I was looking for. It might be my fault on not implementing them correctly which I can understand as a beginner but still got stuck. Let me explain what I am trying to obtain and what I did so far.
This is my Home.vue file and I want user to see this page by default on / path.
<template>
<div>
<MainNavigation />
<LandingSection />
<Services />
<WhyKontext />
<SignupTrial />
<Footer />
</div>
</template>
This is my code for App.vue
<template>
<div>
<Home />
</div>
</template>
<script>
import Home from "./views/landing/Home";
export default {
name: "App",
components: {
Home,
},
};
</script>
This is my router.js
import Vue from "vue";
import VueRouter from "vue-router";
import LoginRegister from "./views/account/LoginRegister";
import App from "./App";
Vue.use(VueRouter);
export default new VueRouter({
mode: "history",
routes: [
{
path: "/",
component: App,
},
{
path: "/account",
component: LoginRegister,
},
],
});
On MainNavigation.vue there is this block of code
<router-link to="/account" class="bg-color text-white">TRY CONTEXT </router-link>
What I am trying is: If a user clicks on TRY KONTEXT button, I want them to go to Signup/Login page named as LoginRegister.vue.
I tried by putting <router-view></router-view> on MainNavigation but LoginRegister page comes attached with the rest of the Home components. When I am on http://localhost:8080/ then I get complete Home. When I click on TRY KONTEXT button It takes me to http://localhost:8080/account but I still can see All the Home Components along with LoginRegister. I am trying to make MainNavigation and Footer at all pages and Just change the content at middle according to the route. In this case, I actually wanted to see MainNavigation, LoginRegister and Footer. I know it's a silly question. Please help me.
Try putting your router-view in your App.vue, with the basic layout in it, such as header/footer/side_bar. Now, your App.vue should contain something like this:
<template>
<div class="container">
<AppHeader></AppHeader>
<router-view/>
<AppFooter></AppFooter>
</div>
</template>
Then move your Home.vue to a separate file, so that it doesn't contain header and footer which you already included in your layout:
<template>
<div class="container">
<carousel></carousel>
<image-grid></image-grid>
</div>
</template>
Now, in your router.js, specify the routes, almost like this:
import Home from './path/to/home.vue'
routes = [
{
path: '/',
name: 'home',
component: Home
}
]
Try editing your App.vue component template like this:
<template>
<div>
<router-view/>
</div>
</template>
The logic behind this is that the app is showing the current selection of your router.

Using v-if for every children route in vue.js

I would like to show a certain div for every child route of the route
So I thought simply adding something like this would work, but it does not:
<div v-if="$route.path == '/news/:child'">
</div>
So any route that is nested under /news/ still does not show that <div>
How can I display that div for every child route of the /news route?
So actually this will work if I set v-if="$route.path.includes('/news/')", thus div only shows in children routes (not in parent).
Use Vue Nested Routes:
const routes = [
{
path: '/news',
component: NewsComponent,
children: [
{
path: ':child',
component: ChildComponent,
},
]
}
]
// NewsComponent
<template>
<div>
My News Component
<router-view />
</div>
</template>
// ChildComponent
<template>
<div>
My Child Component
</div
</template>
Will render:
<div>
My News Component
<div>
My Child Component
</div>
</div>

Can i import single file component using Vue and Vue Router CDN?

I'm currently using Vue and Vue Router CDN. I want to import a single file component (user.html) to my index.html with Vue router. But when I click on "Go to user" the data didn't display. I read a few guides about Vue router but they used NPM or CIL instead of Vue CDN.
Index.html
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- use router-link component for navigation. -->
<!-- specify the link by passing the `to` prop. -->
<!-- `<router-link>` will be rendered as an `<a>` tag by default -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
<router-link to='/User.html'>Go to User</router-link>
</p>
<!-- route outlet -->
<!-- component matched by the route will render here -->
<router-view></router-view>
</div>
<script>
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const User = { template: '#test'}
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar },
{
path:'/User.html', component: User
}
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
</script>
User.html
<template id = "test">
fsjdfjdfldskjflkd
</template>
I think there's been a misunderstanding. As far as I can tell you're trying to load User.html in the way you would load a .vue file, but that doesn't work unless you're using Webpack to build your project since the .vue filetype is something that the vue-loader project is responsible for parsing.
Vue Router CDN means you're not building with Webpack, so loading a component like you're doing is impossible. You can configure Vue Router to serve a User.html file, but that file can't be a template component since in CDN mode Vue Router has no idea what files are on your server, nor can it simply retreive them.
So you need to do one of the following three options:
Option 1: Start using Webpack for your project
This is what I recommend you doing. You'll find that your project will perform better and will be easier to develop using it.
Option 2: Use the proper template syntax for CDN
This is for example:
var mytemplate = `<div>
<h1>This is my template</h1>
</div>`
Vue.component('mycomp1', {
template: mytemplate
});
Vue.component('mycomp2', {
template: `
<div>
Hello, {{ name }}!
</div>
`,
props: ['name'],
});
You can't load other files as templates when you're not building using Webpack. Webpack puts them into your single page application for you, Vue Router has no idea what's inside User.html nor can Vue use it as a template. Vue Router can be told to redirect to a fully functional User.html website page, but not to just use it as a template.
Option 3: Use Ajax requests to fetch the template file
This is something I STRONGLY URGE YOU NOT TO DO, but for the sake of completeness, you can use the CDN version if you fetch the contents of User.html file using an Ajax request and create a component from that.
I really, really recommend that you stop using the CDN version and instead go for a Webpack based solution, give in to the dark side! Or make it even simpler and use Nuxt.js instead since it's easier for beginners to use.

I have a question about the app.vue file in vue

In vue, if you declare in a file named app.vue as below, the contents of text.vue will be applied to all pages. By the way, I do not want that text.vue to be applied on certain pages. Is there a way?
app.vue
<template>
<div>
<test></test>
</div>
</template>
You can make use of v-if to conditionally show certain components depending on the page.
You haven't given any details about how your pages are organized, but assuming you are using vue-router and your routes are set up something like this:
router.map({
'/page_one': { name: 'pageOne', component: PageOneView },
'/page_two': { name: 'pageTwo', component: PageTwoView },
});
Then you can add v-if on your component to check the current route's name:
<template>
<div>
<test v-if="['pageOne'].indexOf($route.name) > -1"></test>
</div>
</template>
The array provided to the code above represents the routes on which you would like to hide the component (you can change the comparison logic to only show the component on routes you specify, if you would like the component to be hidden on the majority of routes).