How change language in Element UI and Vue dynamically? - vuejs2

I have el-table which was rendered. User change language i have event where i want set new language. But table did not change this language dynamically, because was rendered early.
For translation we use vue-gettext
import elementLangDe from 'element-ui/lib/locale/lang/de';
import elementLocale from 'element-ui/lib/locale';
elementLocale.use(elementLangDe);

You need to combine vue-i18n.
Vue.use(Element, {
i18n: (key, value) => i18n.t(key, value)
})
Then you only need to change the value of i18n.locale.
Detail see:
main.js
index.vue

The parameter's name which passed to Vue.use(ElementUI, {locale}) function always is "locale".
I checked window.local that is set before to set locale variable is language that I want to set dynamic.
This is my code:
window.Vue = require('vue').default;
import locale_vi from 'element-ui/lib/locale/lang/vi';
import locale_ja from 'element-ui/lib/locale/lang/ja';
import locale_ja from 'element-ui/lib/locale/lang/ja';
import locale_en from 'element-ui/lib/locale/lang/en';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
let locale;
switch(window.local) {
case "vi":
locale = locale_vi;
break;
case "en":
locale = locale_en;
break;
default:
locale = locale_ja;
}
Vue.use(ElementUI, {locale});

Related

How to update TipTap content dynamically with Vue 3?

I was able to set the initial value of the content from the editor with the value of a ref, but it doesn't update the content when the value of the ref changes.
Would anyone have an idea how to do it?
<editor-content
:editor="editor"
v-model:content="
/>
<script setup>
import { ref } from 'vue'
import { useEditor, EditorContent } from '#tiptap/vue-3'
import StarterKit from '#tiptap/starter-kit'
const generatedText = ref('<p>Hello!</p>')
/* editor */
const editor = useEditor({
content: generatedText.value,
extensions: [
StarterKit,
],
onUpdate: ({editor}) => {
generatedText.value = editor.getHTML()
}
})
</script>
Sorry if the question is too silly, I couldn't find an answer in the documentation.
Thank you for your help!
How will the generatedText be generated? Through tiptap?
The v-model of tiptap is the editor.content value. You could give it an initial state but if you want to change the editor.content after some interaction with the wysiwyg (like onFocus) you could use: setContent
Or maybe this helps:
Listening for changes

How to watch deep state change in component using pinia

I'm having problems with watching deep changes inside component. My store looks like this (simplified):
import {defineStore} from 'pinia'
import {PiniaAuth} from "#/store/piniaauth";
import {get, getDatabase, ref, set, update} from "firebase/database";
import {toRaw} from 'vue'
import {PiniaMainStore} from "#/store/pinia";
// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
export const PiniaInfo = defineStore('info', {
// arrow function recommended for full type inference
state: () => {
return {
info: {
name: 'John',
bill: 10000,
}
}
},
}
I need to watch bill changes and recount other data in component run methods. I've seen the function storeToRefs but didn't find how to watch if the data is in another object (in my case inside the info object).
Are there any ways to do this?

vue test util: trigger change in el-select (element ui) not working

I have a problem, I can't trigger change the el-select. It works fine on a normal select. The el-checkbox also works well. I have tried to see other subjects like here:
https://stackoverflow.com/questions/53749460/simulate-select-with-element-ui-and-vue-test-utils[enter link description here]1
or
https://github.com/vuejs/vue-test-utils/issues/260
but nothing can stop it from not working.
Do you have an idea?
Here's my original code(sorry it's pug):
el-form-item#recommendationAlgorithmProcess(prop="process")
el-select#recommendationAlgorithmSelectProcess(v-model="recommendationAlgorithm.processId", #change="addProcessParamsToAlgorithm()", name="process", :disabled="this.editMode", filterable, value-key="process", :placeholder="$t('choose algorithm process')")
el-option(v-for="process, index in recommendationAlgorithmProcesses", :key="index", :label="$t(process._embedded.algorithmProcessDefinition.description)", :value="process.internalId")
And my test:
import { shallowMount, createLocalVue } from '#vue/test-utils'
import Vuex from 'vuex'
import router from '../router'
import i18n from '#/i18n'
import RecommendationAlgorithmEdit from '#/components/RecommendationAlgorithmEdit'
import _ from 'lodash'
import { Select, Option, Input, Row, Col, FormItem, Form, Card } from 'element-ui'
it.only('Should add selected process parameters to algorithm', async () => {
const wrapper = shallowMount(RecommendationAlgorithmEdit,
{
store,
computed,
localVue,
router,
i18n,
stubs: {
'el-form': Form,
'el-card': Card,
'el-row': Row,
'el-col': Col,
'el-input': Input,
'el-form-item': FormItem,
'el-select': Select,
'el-option': Option
}
})
wrapper.vm.$router.push({
name: 'add a new recommendation algorithm'
})
wrapper.findAll('.el-select-dropdown__item').at(1).trigger('change')
console.log('####: ', wrapper.vm.recommendationAlgorithm.processParameterValues)})
I have also tried with other methods:
wrapper.findAll('.el-select-dropdown__item').at(1).element.selected = true
wrapper.find('#recommendationAlgorithmSelectProcess').trigger('change')
But nothing works, I added a console.log to the change function (addProcessParamsToAlgorithm) but it doesn't appear in the console.
Note that I tried with the other elements of the element where everything works except the el-select.
Thanks in advance
I have solved my problem :
import { Select, Option, Input, Row, Col, FormItem, Form, Card } from 'element-ui'
const wrapper = shallowMount(YourComponent,
{
store,
computed,
localVue,
router,
i18n,
stubs: {
'el-form': Form,
'el-card': Card,
'el-row': Row,
'el-col': Col,
'el-input': Input,
'el-form-item': FormItem,
'el-select': Select,
'el-option': Option
}
})
const reco = wrapper.find(Select)
reco.vm.$emit('change')

Vue 3 use dynamic component with dynamic imports

I use Vue 3 and I have a dynamic component. It takes a prop called componentName so I can send any component to it. It works, kind of.
Part of the template
<component :is="componentName" />
The problem is that I still need to import all the possible components. If I send About as a componentName I need to import About.vue.
Part of the script
I import all the possible components that can be added into componentName. With 30 possible components, it will be a long list.
import About "#/components/About.vue";
import Projects from "#/components/Projects.vue";
Question
It there a way to dynamically import the component used?
I already faced the same situation in my template when I tried to make a demo of my icons which are more than 1k icon components so I used something like this :
import {defineAsyncComponent,defineComponent} from "vue";
const requireContext = require.context(
"#/components", //path to components folder which are resolved automatically
true,
/\.vue$/i,
"sync"
);
let componentNames= requireContext
.keys()
.map((file) => file.replace(/(^.\/)|(\.vue$)/g, ""));
let components= {};
componentNames.forEach((component) => { //component represents the component name
components[component] = defineAsyncComponent(() => //import each component dynamically
import("#/components/components/" + component + ".vue")
);
});
export default defineComponent({
name: "App",
data() {
return {
componentNames,// you need this if you want to loop through the component names in template
};
},
components,//ES6 shorthand of components:components or components:{...components }
});
learn more about require.context

Vuetify override default prop value

Is there any way to change default value of a prop in a vuetify component?
For example lets say we have a component like v-btn.
This component has many props, One of them like outlined with default value of false.
Lets say i want is to change this default value to true forever in my application. Is there any way?
I was able to do that at the top of my app's entry point (before any Vue component creation).
/**
* [required imports]
* (you must somehow import VBtn component separately)
*/
Vue.use(Vuetify);
VBtn.options.props.outlined.default = true;
But this practice is called monkey patching and not encouraged to use, consider to use inheritance instead.
In my case I was trying to get component from Vue.options.components['VBtn'] but it didn't work.
So I monkey patched vue library too:
import Vue from "vue";
import Vuetify from 'vuetify'
export const vueComponentsImported: any = {};
export const vueComponentFnDefault = Vue.component.bind(Vue);
/** #see node_modules/vue/src/core/global-api/assets.js */
export const vueComponentFnModded = (id, component) => {
vueComponentsImported[id] = component;
return vueComponentFnDefault(id, component);
};
Vue.component = vueComponentFnModded;
Vue.use(Vuetify);
let VBtn = vueComponentsImported['VBtn'];
if (VBtn) {
VBtn.options.props.outlined.default = true;
}
(please feel free to edit this code if it doesn't work, I have much more lines in my app)
It doesn't make sense to do this,you could just replace '<v-btn' with '<v-btn outlined'.