I am currently implementing an application migration from Vue2 to Vue3.
In the Vue2 application (vue-class-component+vue-property-decorato), it is implemented with class-style.
For large scale applications, we are trying to implement it with class-style in Vue3 as a first step.
The two things we want to achieve are as follows
- Communicate SmSwitch v-switch changes to DecoratorView
- Dynamically change isSwitch in DecoratorView
Console log when switching v-switches enter image description here
I need help resolving this.Please advise.
/** DecoratorView.vue(ParentComponent) **/
<template>
<div class="home">
<h1>new view</h1>
<decorator-organism text="component" flg :obj="obj" />
<!-- <decorator-organism flg :obj="obj" /> -->
<v-btn @click="changeObj" text="changeObj" />
<p>obj.age = {{ obj.age }}</p>
<sm-switch v-model="isSwitch" @update:modelValue="updateIsSwitch" />
<!-- <sm-switch :onSwitch="isSwitch" @change="onChangeSwitch" /> -->
<p>{{ mixinText }}</p>
</div>
</template>
<script lang="ts">
import { defineAsyncComponent } from "vue";
import { Component, Watch, Mixins } from "vue-property-decorator";
import { Options, Vue } from "vue-class-component";
import SmMixin from "@/components/SmMixin";
Vue.registerHooks(["beforeRouteLeave"]);
@Options({
components: {
DecoratorOrganism: defineAsyncComponent(
() => import("@/components/decoratorComponent/DecoratorOrganism.vue")
),
SmSwitch: defineAsyncComponent(
() => import("@/components/decoratorComponent/SmSwitch.vue")
),
},
})
export default class DecoratorView extends Mixins(SmMixin) {
obj = objectMock;
isSwitch = false;
switch2 = false;
private updateIsSwitch(newValue: boolean): void {
this.isSwitch = newValue;
}
private changeObj(): void {
this.obj.age = this.obj.age + 1;
}
private onChangeSwitch(newValue: boolean): void {
console.log("onChangeSwitch excuted");
console.log(newValue);
this.isSwitch = newValue;
console.log(this.isSwitch);
}
get mixinText(): string {
return this.$isFlg ? "true" : "false";
}
beforeRouteLeave(): void {
console.log("leave");
}
@Watch("obj.age")
printOut() {
console.log("watch func start");
}
@Watch("isSwitch")
printSwitch() {
console.log("printSwitch");
console.log(this.isSwitch);
}
}
const objectMock = {
name: "hoge",
age: 28,
sex: "male",
};
</script>
/** SmSwitch.vue(ChildComponent) **/
<template>
<div>
<v-switch
:value="state"
color="secondary"
@update:modelValue="onChangeSwitch"
/>
<!-- <v-switch :value="onSwitch" color="secondary" @change="onChangeSwitch" /> -->
</div>
</template>
<script lang="ts">
import { Vue, Options } from "vue-class-component";
import { Prop, Model } from "vue-property-decorator";
@Options({})
export default class SmSwitch extends Vue {
@Prop({ type: Boolean, default: false })
@Model("update:modelValue", { type: Boolean })
private readonly onSwitch!: boolean;
private get state(): boolean {
return this.onSwitch;
}
private set state(newValue: boolean) {
console.log("child-component setter execute");
console.log(newValue);
console.log(this.onSwitch);
this.$emit("update:modelValue", this.state);
}
private onChangeSwitch(newValue: boolean) {
console.log("onChangeSwitch start");
console.log(newValue);
this.state = newValue;
this.$emit("update:modelValue", this.state);
}
}
</script>
pacakge.json is here.
{
"name": "vee-validate-tutorial",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vee-validate/i18n": "^4.11.8",
"@vee-validate/rules": "^4.11.8",
"core-js": "^3.8.3",
"vue": "^3.3.7",
"vue-class-component": "^8.0.0-rc.1",
"vue-facing-decorator": "^3.0.4",
"vue-property-decorator": "^9.1.2",
"vue-router": "^4.0.3",
"vuex": "^4.0.0",
"yup": "^1.3.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/compat": "^3.3.4",
"@vue/eslint-config-typescript": "^9.1.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.0.3",
"prettier": "^2.4.1",
"typescript": "~4.5.5",
"vee-validate": "^4.11.8",
"vuetify": "^3.3.20"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"plugin:prettier/recommended"
],
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}
I've tried vue-facing-decorator, but gave up.
Because mixins did not work well.
I've tried vue-facing-decorator, but gave up. Because mixins did not work well.