Vue.js
vue-form validator
▌Introduction
vue-i18n is a internationalization plugin for Vue.js
I will
show three ways for setting localization dictionary in this sample:
1. Constant variable
2. JSON file
3. ASP.NET Resource file (.resx)
▌Environment
▋vue.js 2.5.13
▋vue-i18n 7.4.2
▌Implement
▋From constant variable
▋JS for creating vue-i18n instance
Vue.use(VueI18n);
const messages = {
enUS: {
"column": {
"key": "Book
title",
"description": "Price",
"createBy": "Create
by",
"createOn": "Create
On",
"updateBy": "Update
by",
"updateOn": "Update
On"
},
"text": {
"search": "Search"
}
},
zhTW: {
"column": {
"key": "書名",
"description": "價格",
"createBy": "建立者",
"createOn": "建立日期",
"updateBy": "更新者",
"updateOn": "更新日期"
},
"text": {
"search": "搜尋"
}
}
}
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: '', // set
locale
fallbackLocale: 'enUS',
messages, // set
locale dictionary
});
Notice that you have to
name the constant variable as “messages” or the data won’t be loaded to
vue-i18n.
▋JS (Inject the vue-i18n instance)
var app = new Vue({
el: '#app',
i18n, //In IE, you have to write like this... i18n: i18n
data: {
locale: '',
},
created: function () {
var vm = this;
//vm.$i18n.setLocaleMessage('zh',
messages.ja); //You can also set messages here
vm.$i18n.locale = 'zhTW';
}
}
▋HTML
<div id="app" class="container-fluid">
<div class="container">
<div class="row">
<div class="col-2">
<input type="text" v-model="keyword" class="form-control" />
</div>
<div class="col-2">
<input type="button" class="btn
btn-warning" :value="$t('text.search')" />
</div>
</div>
</div>
<div style="width:100%">
<div class="col-centered"> </div>
<table class="table">
<thead class="thead-dark">
<tr>
<th>#</th>
<th>{{ $t("column.key") }}</th>
<th class="col-xs-2">{{ $t("column.description") }}</th>
<th>{{ $t("column.createBy") }}</th>
<th>{{ $t("column.createOn") }}</th>
<th>{{ $t("column.updateBy") }}</th>
<th>{{ $t("column.updateOn") }}</th>
</tr>
</thead>
</table>
</div>
PS. I skip the code of
footer component which can changes the vm.$i18n.locale‘s value
dynamically.
▋From json files
If we would like to put the localization
dictionary to a JSON file but not in javascript, we can ajax the dictionary and
lazy load it. (See more on vue-i18n: Lazy loading)
▋en-us.json
{
"column": {
"key": "Book
title",
"description": "Price",
"createBy": "Create
by",
"createOn": "Create
On",
"updateBy": "Update
by",
"updateOn": "Update
On"
},
"text": {
"search": "Search"
}
}
▋JS for creating vue-i18n instance
Vue.use(VueI18n);
// Create
VueI18n instance with options
const i18n = new VueI18n({
locale: '', // set locale
fallbackLocale: 'enUS',
});
function i18nGetEnUS() {
// return axios.get('/wwwroot/js/assets/en-us.json');
return axios.get('/api/Resource/get/en-US');
}
function i18nGetZhTW() {
// return axios.get('/wwwroot/js/assets/zh-tw.json')
return axios.get('/api/Resource/get/zh-TW');
}
var i18nPromise = axios.all([i18nGetEnUS(), i18nGetZhTW()])
.then(axios.spread(function (response1, response2) {
i18n.setLocaleMessage('enUS', response1.data);
i18n.setLocaleMessage('zhTW', response2.data);
console.log(Vue.prototype.$locale);
i18n.locale = Vue.prototype.$locale;
}));
▋From ASP.NET resource file (.resx)
If you already manage the
localization dictionary in ASP.NET resource file, here is a way you can restore
them to vue-i18n instance by web api.
▋Resource factory
However, the most difficult part is dump the
resource file as JSON string.
So first we create ResourceFactory to store the
data in resource as Dictionary<TKey, TValue>.
public enum
ResourceFileNameEnum
{
Column = 1,
Text
}
public static class ResourceFactory
{
public static Dictionary<string, string> GetResource(ResourceFileNameEnum
rsFileName, CultureInfo targetCulture)
{
Dictionary<string, string>
resources = new Dictionary<string, string>();
//FieldInfo[]
fields = null;
ResourceSet
resourceSet = null;
switch (rsFileName)
{
case ResourceFileNameEnum.Column:
resourceSet = Resx.Resources.Column.ResourceManager.GetResourceSet(targetCulture, true, true);
break;
case ResourceFileNameEnum.Text:
resourceSet = Resx.Resources.Text.ResourceManager.GetResourceSet(targetCulture, true, true);
break;
}
IDictionaryEnumerator
enumerator = resourceSet.GetEnumerator();
while (enumerator.MoveNext())
{
resources.Add(enumerator.Key.ToString(), enumerator.Value.ToString());
}
return resources;
}
}
2019-06-09
Updated: Get the
resource-file’s content by using System.Resources.ResourceManager as following.
|
public static
class ResourceFactory
{
public static string
GetResource(CultureInfo targetCulture, string rsFileName)
{
string rsBaseName
= $"MyProject.{rsFileName}";
Dictionary<string, string>
resources = new Dictionary<string, string>();
ResourceSet resourceSet
= null;
var resourceManager
= new ResourceManager(rsBaseName,
Assembly.GetExecutingAssembly());
resourceSet = resourceManager.GetResourceSet(targetCulture, true, true);
IDictionaryEnumerator enumerator
= resourceSet.GetEnumerator();
while
(enumerator.MoveNext())
{
resources.Add(enumerator.Key.ToString(), enumerator.Value.ToString());
}
var
camelCaseFormatter = new JsonSerializerSettings();
camelCaseFormatter.ContractResolver
= new CamelCasePropertyNamesContractResolver();
string json =
JsonConvert.SerializeObject(resources, camelCaseFormatter);
return json;
}
}
▋Web API
public class ResourceController : ApiController
{
internal class LocaleResource
{
public Dictionary<string, string>
Column { get; set; }
public Dictionary<string, string>
Text { get; set; }
}
[HttpGet]
public async Task<HttpResponseMessage> Get(string id)
{
CultureInfo ci = new CultureInfo(id);
var
columnResources = ResourceFactory.GetResource(ResourceFileNameEnum.Column, ci);
var
textResources = ResourceFactory.GetResource(ResourceFileNameEnum.Text, ci);
var
resources = new LocaleResource() {
Column= columnResources,
Text = textResources
};
var
camelCaseFormatter = new JsonSerializerSettings();
camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
string json = JsonConvert.SerializeObject(resources, camelCaseFormatter);
var
response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
}
}
Remember to convert the JSON
string as lower case camel!
Now you can update the url when
doing lazy loading of vue-i18n and have fun.
function i18nGetEnUS() {
ss
return axios.get('/api/Resource/get/en-US');
}
▌Reference
沒有留言:
張貼留言