background
There is a vue project that needs to realize international functions and can switch to Chinese and English displays, because the users of the project system include domestic and foreign users.
need
1. All Chinese labels on the page form should be internationalized, including form attribute labels, table column header labels, etc. title = "quantity";
2. The prompt content of the input box needs to be internationalized, such as placeholder="Select Date"
3. The prompt information in the js code needs to be internationalized, such as message ("Please check batch settings"), confirm ('Are you sure you want to set business losses?'), title: 'Delete error', etc.;
Solution
1. Development process. In the initial development process, we do not consider internationalization. After the code is basically completed, we will finally carry out internationalization;
2. Consider that other languages may be used in the future, so when we do an international word library, the international code uses 5 digits, corresponding to multiple language values, that is, one-to-many;
3. In the front end, we re-encapsulate a global method $lang(param1, param2) to support internationalization. param1 is an international encoding and param2 is the default value (if the corresponding language word is found in the international encoding, param2 is used by default, and the ‘~’ symbols on the left and right sides are removed);
(In fact, it was later analyzed that if the front-end developers wrote all Chinese words that need internationalization as $lang('Chinese words') at the beginning, and the $lang method logic is modified again. If there is no second parameter and there is no internationalization word corresponding to the first parameter, the first parameter string will be displayed directly. In this way, it will be very accurate when extracting the content that needs internationalization in the code later.)
4. Internationalization process:
- Extract all Chinese from the front-end code file, form an array and put it in a json file, and the array needs to be reused;
- Use a third-party translation interface to translate the exported Chinese and generate a json file in Chinese and English;
- Proofread the Chinese and English comparison tables because some translations may not be accurate;
- Based on the proofreaded Chinese and English comparison table, an international code library is generated and two international files are created;
- According to the proofreaded Chinese and English comparison table, and analyze the code rules, the Chinese in the program code is internationalized;
Internationalization process implementation
In the implementation of internationalized process, I use the JS script code to implement related processing and use the node environment to execute scripts;
1. Extract Chinese
Extract all Chinese from the front-end code file, form an array and put it in a json file, and the array needs to be reused;
The following code is used to extract Chinese in the file code. We can name the code file and use node to execute the script;
The path to internationalization in the code is set to the components and pages folders under src in the current directory.
const fs = require('fs'); const path = require('path'); const chineseRegex = /[\u4e00-\u9fa5]+/g; function extractChineseFromFile(filePath) { const content = (filePath, 'utf-8'); const chineseWords = (chineseRegex); return chineseWords || []; } function processDirectory(directoryPath) { const files = (directoryPath); const chineseSentences = []; ((fileName) => { const filePath = (directoryPath, fileName); const stats = (filePath); if (()) { (...processDirectory(filePath)); } else if (() && ['.js', '.vue'].indexOf((filePath)) > -1) { const chineseWords = extractChineseFromFile(filePath); (...chineseWords); } }); return chineseSentences; } function main() { const srcDirectory = (__dirname, 'src'); const componentsDirectory = (srcDirectory, 'components'); const pagesDirectory = (srcDirectory, 'pages'); const componentsChineseSentences = processDirectory(componentsDirectory); const pagesChineseSentences = processDirectory(pagesDirectory); const allChineseSentences = [...componentsChineseSentences, ...pagesChineseSentences]; //const allChineseSentences = componentsChineseSentences; const outputPath = (__dirname, ''); // Use Set object to reload let backString = (new Set(allChineseSentences)); // Sort the array after deduplication (); (outputPath, (backString, null, 2), 'utf-8'); ('The extracted Chinese word or statement has been saved to the file. '); } main();
2. Translate Chinese
Use a third-party translation interface to translate the exported Chinese and generate a json file in Chinese and English;
For translation interface, we are using Baidu Translation here. As for how to use Baidu Translation, I won’t talk about it here, go to Baidu for yourself;
This step requires the file generated in the first step, and the translation result is present in translated_zh_en.json.
const fs = require('fs'); const axios = require('axios'); const appId = '123456789'; // Replace it with your Baidu Translate APP IDconst secretKey = '999999999'; // Replace it with your Baidu Translation key const crypto = require('crypto'); ["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"; function md5Hash(input) { // Create a hash object const hash = ('md5'); // Update the content of the hash object (input); // Get the binary representation of the hash value const hashBuffer = (); // Convert binary to hexadecimal representation const hashHex = ('hex'); // Returns lowercase hash value return (); } // Use Baidu Translation API for translationasync function translateToEnglish(text) { const params = { q: text, appid: appId, salt: (), from: 'zh', to: 'en', sign: '' }; // Calculate the signature = md5Hash( + + + secretKey); // Request a translation const url = `/api/trans/vip/translate?q=${encodeURIComponent()}&from=zh&to=en&appid=${}&salt=${}&sign=${}`; const response = await (url); //(url); //() // Return to translation results return .trans_result[0].dst; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function mysleep() { ('Rest for 1 second............'); await sleep(1000); // Pause for 1 second ('Rest completed...'); } async function process() { // Read json file const data = (('', 'utf8')); // Objects that store translation results let translationData = {}; let execNumber = 1; // traverse the Chinese string array and translate for (let i = 0; i < ; i++) { const chineseString = data[i]; const englishString = await translateToEnglish(chineseString); // Store the original Chinese string and English string into key-value pairs into translationData object translationData[chineseString] = englishString; if (execNumber >= 120) { // If you don't want to execute all, how many fields will be executed? break; } else if (i == execNumber*20) { // Every 20 interface calls are executed, you will have a rest of 1 second execNumber++; await mysleep() } } // Write the translation result into the file ('translated_zh_en.json', (translationData, null, 2)); } process().catch(error => { (error); });
3. Proofreading and Translation
Proofreading Chinese and English comparison tables, because some translations may not be accurate; (Find someone with a high level of English in the industry, go and proofread it yourself)
4. Create an international library
Based on the proofreaded Chinese and English comparison table, an international code library is generated and two international files are created;
const fs = require('fs'); // Read the original JSON fileconst data = (('translated_zh_en.json', 'utf8')); // Chinese and English JSON filesconst chineseData = {}; const englishData = {}; let serialNumber = 00001; // Iterate through the original data and generate new key-value pairsfor (let chinese in data) { const english = data[chinese]; // Generate new key-value pairs with 5 digits const key = `N${String(serialNumber).padStart(5, '0')}`; chineseData[key] = chinese; englishData[key] = english; serialNumber++; } // Write JSON data in Chinese and English to a file('', (chineseData, null, 2)); ('', (englishData, null, 2));
5. Code internationalization processing
According to the Chinese internationalization file generated in step 4, analyze the code rules and internationalize the Chinese in the program code;
First of all, we need to analyze the code rules that require internationalization of the program, because this replacement is not simply a Chinese substitution. The code may all change. The current rules in our analysis project code are as follows:
Scene | **Code Example**** | **Find content**** | **Replace content**** |
---|---|---|---|
As component element content | <vxe-button @click="closeModel">Cancel</vxe-button> <span style="color: red;">If the color size is adjusted, please be sure to check the quantity and color matching data after saving!</span> <div class="title">Size information</div> |
>Cancel< | >{{$lang('10000', 'Cancel')}}< |
As component element attribute value | <vxe-table-column field="odgc_pcs" title="quantity" width="100" header-align="center" align="right"> <el-date-picker v-if=" == 'date'" type="date" placeholder="select date" v-model=""> |
title="Quantity"placeholder="Select date" | :title=" l a n g ( ′ 1000 1 ′ , ′ quantity ′ ) " : p l a c e h o l d e r = " lang('10001', '~quantity~')":placeholder=" lang('10001', ′ quantity ′)":placeholder="lang('Ph_select_data', 'Select date')" |
The results of ternary operations in component template code | <el-button size="mini" @click="alterConsumption(row)">{{onlyShow?'View':'Modify'}}</el-button> |
‘View’: ‘View’: ‘Modify’: ‘Modify’ | l a n g ( ′ 1000 2 ′ , ′ View ′ ) Same as above lang('10002', '~View~') Same as above lang('10002', ′ View ′) Same as above lang('10003', 'Modify') Same as above |
Method parameter value in js | this.$("Please check batch settings", "error"); this.$('Are you sure you want to set it?') this.$confirm("Are you sure you want to delete this record?", "Tip", { confirmButtonText: "OK", cancelButtonText: "Cancel", type: "warning", }) |
message("Please check batch settings"message('Please check to set batch settings'confirm("Are you sure you want to set?"confirm('Are you sure you want to set?'"Tip", confirmButtonText: "OK", cancelButtonText: "Cancel", | message(this. l a n g ( ′ 1000 4 ′ , ′ Please check batch settings ′ ) Same as above c o n f i r m ( t h i s . lang('10004', ′ Please check batch settings ~') Same as above confirm(this. lang('10004', ′ Please check batch settings ′) Same as above confirm(('10005', ′ Please check batch settings ′) Same as above confirm(('10005', ′ Please check batch settings ′) Same as above confirm(('10005', ′ Please check ′ ) , c o n f i r m B u t t o n T e x t : t h i s . lang('10006', ′ Please check ~'), confirmButtonText: this. lang('10006',' Tip ′),confirmButtonText:('10007', 'Confirm')cancelButtonText: this.$lang('10008', 'Cancel') |
Object attribute assignment in js | `this. X M o d a l . m e s a g e ( m e s s a g e : " save failed " , s t a t u s : " e r r o r " ) ; t h i s . ({ message: " save failed", status: "error" }); this. (message: " save failed", status: "error");({ message: 'Please select the material to be set!', type: 'warning' }); this. X M o d a l . a l e r t ( m e s s a g e : " please select attachment category " , s t a t u s : " w a r n i n g " , ) ; t h i s . ({ message: "Please select attachment category", status: "warning", }); this. (message:"Please select attachment category", status: "warning",);({ status: "error", title: "Delete error", message: | "An error occurred during server deletion", });` | |
|| Assignment in js | `this.$({ status: "error", title: "Delete error", message: | "An error occurred during server deletion", });` |
The replacement script code is as follows:
const fs = require('fs'); const path = require('path'); // Read the file and parse JSON datafunction loadTranslations() { const cnJsonPath = (__dirname, 'src', 'lang', ''); const content = (cnJsonPath, 'utf-8'); return (content); } // Determine whether the string begins with the specified prefixfunction startsWith(str, prefix) { return (prefix); } /** * Scene matching for each key-value pair * @param {String} fileContent file content * @param {String} key Internationalized variable name * @param {String} value Chinese string */ function replaceAllScene(fileContent, key, value) { // Scene:>Cancel< let searchValue = `>${value}<`; let replaceValue = `>{{$lang('${key}', '~${value}~')}}<`; fileContent = (searchValue).join(replaceValue); // Scene: title="quantity" searchValue = `title="${value}"`; replaceValue = `:title="$lang('${key}', '~${value}~')"`; fileContent = (searchValue).join(replaceValue); // Scene: placeholder="Select date" searchValue = `placeholder="${value}"`; replaceValue = `:placeholder="$lang('${key}', '~${value}~')"`; fileContent = (searchValue).join(replaceValue); // Scenario: message("Please check batch settings" searchValue = `message("${value}"`; replaceValue = `message(this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // Scenario: message('Please check batch settings' searchValue = `message('${value}'`; replaceValue = `message(this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // Scenario: confirm("Are you sure you want to set business losses?" searchValue = `confirm("${value}"`; replaceValue = `confirm(this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // Scenario: confirm('Are you sure you want to set business losses?' searchValue = `confirm('${value}'`; replaceValue = `confirm(this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // confirmButtonText: "OK", searchValue = `confirmButtonText: "${value}",`; replaceValue = `confirmButtonText: this.$lang('${key}', '~${value}~'),`; fileContent = (searchValue).join(replaceValue); // cancelButtonText: "Cancel", searchValue = `cancelButtonText: "${value}",`; replaceValue = `cancelButtonText: this.$lang('${key}', '~${value}~'),`; fileContent = (searchValue).join(replaceValue); // message: "Save failed" searchValue = `message: "${value}"`; replaceValue = `message: this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // message: 'Save failed'' searchValue = `message: '${value}'`; replaceValue = `message: this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // title: "Delete error" searchValue = `title: "${value}"`; replaceValue = `title: this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); // title: 'Delete error' searchValue = `title: '${value}'`; replaceValue = `title: this.$lang('${key}', '~${value}~')`; fileContent = (searchValue).join(replaceValue); return fileContent; } // Replace the specified string in the given filefunction replaceStringsInFile(filePath, replacements) { const content = (filePath, 'utf-8'); let newContent = content; for (const [key, value] of (replacements)) { // If the matching string is preceded by "message(", remove the double quotes on the left and right sides //const searchValue = startsWith(value, 'message("') ? (8, -1) : value; newContent = replaceAllScene(newContent, key, value); //newContent = (searchValue).join("$lang('" + key + "',')" + searchValue + "'"); } if (newContent !== content) { (filePath, newContent, 'utf-8'); (`Replaced strings in ${filePath}`); } } // Process all files in the specified directoryfunction processDirectory(directoryPath, replacements) { const files = (directoryPath); ((fileName) => { const filePath = (directoryPath, fileName); const stats = (filePath); if (()) { processDirectory(filePath, replacements); } else if (()) { replaceStringsInFile(filePath, replacements); } }); } function main() { const translations = loadTranslations(); const componentsDirectory = (__dirname, 'src', 'components'); const pagesDirPath = (__dirname, 'src', 'pages'); processDirectory(componentsDirectory, translations); processDirectory(pagesDirPath, translations); } main();
At this point, we have completed the internationalization of front-end code;
Why do we use the original Chinese as the second parameter of the internationalization method $lang?
Because, if you cannot see Chinese in the code file, it will be too difficult to find when modifying the code, and you can only see international digital encoding.
suggestion
It is recommended that when the front-end is first developed, all the places that need internationalization are written as $lang ('Chinese'), including template code and js code.
This way, the later replacement is more accurate, and developers don’t have to worry about internationalization at the beginning.
Moreover, when we extract the Chinese code, we can accurately extract it according to the format $lang('Chinese'), and after internationalization, it becomes $lang('International encoding','Chinese') so that when we extract the second time, we will not repeatedly extract the Chinese code that has been internationalized.
Summarize
This is the end of this article about the internationalization solution of front-end Vue projects. For more relevant internationalization solutions for front-end Vue projects, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!