I have to get the components in Vue 2:
i the main page i have this:
import { component1, component2, component3, } from '#/components'
export default {
components: {
component1,
component2,
component3
}
}
How I can do something like that:
methods: {
getComponents () {
return this.$components
}
}
Related
I am having trouble with something seemingly simple: how do I use a prop, passed to my component, as the basis for some computation? As in --
export default {
props: {
officeConsumption: {
type: Number,
},
commuteOutput: {
type: Number,
},
savings: {
type: Number,
}
},
data() {
return {
drives: this.savings,
flights: this.savings
}
},
And so on, except I want do something with savings (like Math.round) and use it in my template like {{ drives }}. I get as far as {{ savings }} i.e. using the original prop but am having trouble achieving the desired end result {{ Math.round(savings * / + some computation) }}. This is due 3 and Vite.
You have two ways of using computed in Vue3. Under the hood, they're the same thing:
1. Composition API computed:
import { defineComponent, computed } from 'vue';
export default defineComponent({
props: {
officeConsumption: {
type: Number,
},
},
setup(props) {
const myComputed = computed(() => Math.round(props.officeConsumption));
return {
myComputed
}
}
})
Another flavor of the above is inside a reactive() object:
import { defineComponent, computed, reactive, toRefs } from 'vue';
export default defineComponent({
props: {
officeConsumption: {
type: Number,
},
},
setup(props) {
const state = reactive({
myComputed: computed(
() => Math.round(props.officeConsumption)
)
})
return {
...toRefs(state)
}
}
})
2. Options API computed (just like in Vue 2, it's still available):
import { defineComponent } from 'vue'
export default defineComponent({
props: {
officeConsumption: {
type: Number,
},
},
computed: {
myComputed() {
return Math.round(this.officeConsumption);
}
}
})
All of the above produce the same result. You can use myComputed in the <template>.
I've mapped chartData to a state property using vuex. What I'd like to do is update the chart when a dataset is updated. I have heard that it can be done with mixins or watchers but I don't know how to implement it. I understand that mixins creates a watcher but I don't know how it is used within vuex.
Chartline.vue:
<script>
import { Line } from 'vue-chartjs'
import { mapState } from 'vuex'
export default {
name: 'ChartLine',
extends: Line,
computed:{
...mapState(['charData','options'])
},
methods:{
regraph: function(){
this.renderChart(this.charData,this.options);
}
},
mounted () {
this.regraph();
},
watch: {
}
}
</script>
Pension.vue:
<template>
<div id='pension' class="navbarPar">
<ChartLine/>
</div>
</template>
<script>
import ChartLine from '../components/ChartLine.vue';
import { mapState } from 'vuex'
//import { Line } from 'vue-chartjs'
export default {
name: 'Pension',
components: {
ChartLine,
},
data(){
return{
form: {
...
},
var:{
...
},
}
},
methods: {
calculate: function(indice){
...
//modify data of mapState
//after here, I want to rerender chart
}
},
computed:{
...mapState(['charData','options']),
},
}
</script>
Using a watcher like this should be enough:
<script>
import { Line } from "vue-chartjs";
import { mapState } from "vuex";
export default {
name: "ChartLine",
extends: Line,
computed: {
...mapState(["chartData", "options"])
},
methods: {
regraph() {
this.renderChart(this.chartData, this.options);
}
},
mounted() {
this.regraph();
},
watch: {
chartData: {
handler: this.regraph,
deep: true
}
}
};
</script>
Also having the explicit vuex state map inside the ChartLine component seems a bit wasteful - passing the vuex data through props would render the component more generic:
<template>
<div id='pension' class="navbarPar">
<ChartLine :options="options" :chart-data="chartData"/>
</div>
</template>
<script>...
Chartline.vue:
<script>
import { Line } from "vue-chartjs";
export default {
name: "ChartLine",
extends: Line,
props: {
options: {
type: Object,
default: () => ({})
},
chartData: {
type: Object /*is it?*/,
default: () => ({})
}
},
methods: {
regraph() {
this.renderChart(this.chartData, this.options);
}
},
mounted() {
this.regraph();
},
watch: {
chartData: {
handler: this.regraph,
deep: true
}
}
};
</script>
If you are using vue-chartjs, the library has its own way to handle reactive data in charts:
// ChartLine.js
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['options'], // passed from the parent
mounted () {
// this.chartData is created in the mixin (pass it as any prop with :chart-data="data").
this.renderChart(this.chartData, this.options)
}
}
Now the Pension.vue file
// Pension.vue
<template>
<div id='pension' class="navbarPar">
<ChartLine :chart-data="charData" :options="options" />
</div>
</template>
<script>
import ChartLine from '../components/ChartLine';
import { mapState } from 'vuex'
export default {
name: 'Pension',
components: {
ChartLine,
},
data(){
return{
form: {
...
},
var:{
...
},
}
},
methods: {
calculate: function(indice){
...
//modify data of mapState
//after here, I want to rerender chart
}
},
computed:{
...mapState(['charData','options']),
},
}
</script>
You can read more about it here: https://vue-chartjs.org/guide/#updating-charts,
there are some caveats
In my project, I have 3 components. one component is already showing on the page and now I want to add those 2 components with that component. The code is in below,
<template>
<component v-bind:is="currentComponent" ></component>
</template>
<script>
import { ROAST_CONFIG } from '../../../config/config.js';
import ZoneIndex from './components/zone/Index';
import { listen } from '../../../util/history.js';;
import axios from 'axios'
let baseUrl = ROAST_CONFIG.API_URL;
export default {
name: 'LocationsView',
layout: 'admin/layouts/default/defaultLayout',
middleware: 'auth',
components: {
'zone-index' : ZoneIndex,
},
data() {
return { currentComponent:'','stateId':''}
},
methods: {
updateCurrentComponent(){
console.log(this.$route.name);
let vm = this;
let route = vm.$route;
if(this.$route.name == "Locations"){
this.currentComponent = "zone-index";
}
}
},
mounted() {
let vm = this;
let route = this.$route;
window.addEventListener('popstate',this.updateCurrentComponent);
},
created() {
this.updateCurrentComponent();
}
}
The ZoneIndex component is showing in the code. The other 2 components are CountryIndex and StateIndex.
The correct way to carry out your procedure would be.
<template>
<div>
<zone-index></zone-index>
<state-index></state-index>
<country-index></country-index>
</div>
</template>
<script>
import ZoneIndex from './components/zone/Index';
import CountryIndex from '...way';
import StateIndex ryIndex from '...way';
import { ROAST_CONFIG } from '../../../config/config.js';
import { listen } from '../../../util/history.js';;
import axios from 'axios'
let baseUrl = ROAST_CONFIG.API_URL;
export default {
name: 'LocationsView',
layout: 'admin/layouts/default/defaultLayout',
middleware: 'auth',
components: { ZoneIndex, CountryIndex, StateIndex },
data() {
return { currentComponent:'','stateId':''}
},
methods: {
updateCurrentComponent(){
console.log(this.$route.name);
let vm = this;
let route = vm.$route;
if(this.$route.name == "Locations"){
this.currentComponent = "zone-index";
}
}
},
mounted() {
let vm = this;
let route = this.$route;
window.addEventListener('popstate',this.updateCurrentComponent);
},
created() {
this.updateCurrentComponent();
}
}
How to call a method of another component ?
Like I have a component named Modal.vue . I have a method like below
<script>
export default {
name: 'modal'
methods: {
getUsers() {
//some code here
}
},
created: function () {
this.getUsers();
}
}
</script>
I would like to call that method in another component named Dashboard.vue.
<script>
export default {
name: 'dashboard'
methods: {
add_adddress () {
this.getUsers(); // I would like to access here like this
//some code here
}
},
}
</script>
I read this question, but how can I use $emit,$on,$broadcast in my current setup ?
In order to use emit one of the components need to call the other (parent and child). Then you emit from the child component to the parent component. For example if Dashboard component uses the Modal component you can emit from the Modal to the Dashboad.
If your components are separate from one another you can make use of Mixins. You can create a mixin UsersMixin.js like the following:
export default {
methods: {
getUsers: function () {
// Put your code here for a common method
}
}
}
Then import the mixin in both your components, and you will be able to use its methods:
Modal.vue
<script>
import UsersMixin from './UsersMixin';
export default {
name: 'modal'
mixins: [
UsersMixin
],
created: function () {
this.getUsers();
}
}
</script>
Dashboard.vue
<script>
import UsersMixin from './UsersMixin';
export default {
name: 'dashboard',
mixins: [
UsersMixin
],
methods: {
add_adddress () {
this.getUsers(); // I would like to access here like this
//some code here
}
},
}
</script>
I can create a constant through a store in my vuejs application, but i don't think it is a good practice.what is other way to do the same?
You can always define a variable outside of the Vue app scope and use it throughout the application.
However, if you are using any bundler like Webpack/Browserify/etc. you can do the same but you'd have to import it into every component using it. An example for that can be found below.
//const.js
export default {
c1: 'Constant 1',
c2: 'Constant 2'
}
// component.vue
import const from './const';
export default {
methods: {
method() {
return const.c1;
}
}
}
You can use the method
const State= Object.freeze({ Active: 1, Inactive: 2 });
export default {
data() {
return {
State,
state: State.Active
};
},
methods: {
method() {
return state==State.Active;
}
}
}
or
const State= Object.freeze({ Active: 1, Inactive: 2 });
export default {
data() {
return {
State_: State,
state: State.Active
};
},
methods: {
method() {
return state==State_.Active;
}
}
}
try this instead
//conts.js
const test = "texte";
export default test
//component.vue
import test from "./conts";
<template>
<div>
{{example}}
</div>
</template>
export default {
data: function(){
return {
example: test
}
}
}
The most small big solution
//helper.js
export const Test = {
KEY1: 1,
KEY2: 2,
KEY3: 3,
KEY4: 4
}
testing the code..
//page.vue
import {Test} from "./helper";
<template>
<div>
{{testing.KEY2}}
</div>
</template>
export default {
data: function(){
return {
testing: Test
}
}
}