preface
Read the series in order before reading, for better results! Vue routes to a common component, and then dynamically loads the component based on whether files exist in the path
It is said that the series of articles is difficult to be popular, because the knowledge point baggage is not enough, so we are not willing to collect in the future, but it doesn’t matter, the benefit of the series of articles is to look comfortable, fragmental time is soon finished, isn’t it?
1. Review
The first part basically belongs to the exploration stage, after exploration, Vue’s function is still very powerful! As an important front-end output weapon, it can be said that Xiao Li flying knife, no case of virtual hair, knife deadly.
Now that it’s validated, it shows that the common component does the job and can be easily extended. Even if the automatically generated common components don’t meet the requirements, why not let the flat-lying front-end engineer get up and continue coding on demand?
The second part tries to overview the requirements from the big idea combined with the advantages of the front and back ends. Overall coordination to complete a nearly impossible demand (let the front end of the little brothers lie flat, do not know whether to save the front end, or destroy the front end).
Front end brothers, when you figure this out, you should have advanced, don’t care about this little pressure, right?
In fact, it is still a big project to really complete this demand, and there are still many problems during this period. This is not me again.
2. Back-end interface development
The book is connected back, saying that by the rear end of the operator, the design of the interface table has been shaped, this is not, the product manager A found the door.
Product Manager A: “Wok, Wang, is it there?”
Is the code of the back end of the shaking pot king, suddenly heard the ear spread familiar and with the magic voice, not only a fibrillation in the heart, with reluctance, but still pretending to be a hundred times the spirit of the answer, “Ah ah, in this.”
Product manager A: “Come alive! The design that you said last time is very good, can make a few interfaces today, let front end child shoe play?”
The back end rejects the pot king: “see outside, this is not minute matter? However front end child shoe is not ask for leave (lie flat)?”
Product manager A: “This is not asking for leave to wait in line to get the vaccine. When I arrived, I found that I went to work too early. I ranked first, so I came to work again.”
The back end of the pan king psychological dark scold, this unlucky child, my time to touch fish! And they said, “Ok, let’s give him a job!”
The product manager A patted the back end to shake the pot king, “Big god, I look forward to you!”
Visual Studio 2019 Global Enterprise Planning flagship edition, right-click openEF Core Power Tools”I saw him operate as follows, but in a moment, three five divided by two to fix the entity definition.
All that magic is left is the write service layer and the API control layer.
If not, return the control as a number, text, and date by default.
private string GetDefaultType(Type type)
{
if (numberType.Contains(type))
{
return "Number";
}
else if (dateType.Contains(type)){
return "DateTime";
}
else
{
return "Text"; }}Copy the code
The definitions that automatically get the column information according to the EF definition and generate lists and forms are inserted into the database.
// To insert a list, look at the following code
var type = _unitOfWork.DbContext.Model.GetEntityTypes().FirstOrDefault(x=>x.ClrType.Name == model.ModelName);
if(type == null)
{
throw new BusinessException(PublicError.NotFoundModelName, model.ModelName);
}
List<UdfListTemplate> templates = new List<UdfListTemplate>();
var sortId = 10;
foreach(var p in type.GetProperties())
{
//var f = p.FieldInfo;
templates.Add(new UdfListTemplate
{
ModelGuid = model.ModelGuid,
ModelName = model.ModelName,
SysId = model.SysId,
FieldName = p.Name,
ControlType = GetDefaultType(p.ClrType),
SortId = sortId,
Width = 140,
IsEncrypte = 0,
IsFixed = 0,
IsHidden = 0,
IsSearch = 1,
IsSort = 1,
IsSum = 0}); sortId +=10;
}
// Insert a batch, fast (can query the previous batch insert article)
await _unitOfWork.DbContext.BulkInsertAsync<UdfListTemplate>(templates);
Copy the code
Define the front – end children’s shoes access interface
[HttpGet("{modelGuid}")]
[AllowAnonymous]
public Task<GetModelDefineResult> GetModelDefine(string modelGuid)
{
return _modelService.GetModelDefine(modelGuid);
}
Copy the code
We’re done, we’re testing, and we’re done!
Touch the fish. You can deliver the front end shoes.
3. Design of front children’s shoes
I’m the front end. Say that day, originally want to give product economy a sudden attack, did not think of the pot king’s pot or hit my head, ah, this unlucky child ~~~
To show how much I care about this feature, I’ll start with an ES6 class, just to kick things off.
3.1 class design
Generally for the interface of this kind of change of class, usually our front-end principle is to take as you go, design wool class!
For example, the back-end A\B interface returns the following format:
//A
{
"data": {
"a":123."b":"aaaaaabbbb"}}//B
{
"list": ["a"."b"]."saa":"aaa"
}
Copy the code
So I basically get the data from the API, and I use it, assuming that data is the return value from the API
const a = data.data.a
const b = data.data.b
const c = data.list[0]
const d = data.saa
Copy the code
Good ~~~, if something goes wrong, BB back end, why don’t you return XXX? You can’t be null!
This design class, a little idle! Copy some of them
// Module information definition
class UdfModelInfo {
constructor(modelGuid, modelName, sysId, name, businessPk, functionOperate, formColNum, listShowSelect, listShowPage, listShowNo, listShowTree, udf1, udf2, udf3) {
this.modelGuid = modelGuid
this.modelName = modelName
this.sysId = sysId
this.name = name
this.businessPk = businessPk
this.functionOperate = functionOperate
this.formColNum = formColNum
this.listShowSelect = listShowSelect
this.listShowPage = listShowPage
this.listShowNo = listShowNo
this.listShowTree = listShowTree
this.udf1 = udf1
this.udf2 = udf2
this.udf3 = udf3
}
}
// Module/list/form definition
export default class UdfModel {
constructor(model, listTemplate, formTemplate) {
this.model = newUdfModelInfo(... model)this.listTemplate = newUdfListTemplate(... listTemplate)this.formTemplate = newUdfFormTemplate(... formTemplate)this.createDate = new Date()}}export {
UdfListTemplate,
UdfFormTemplate,
UdfModelInfo,
}
Copy the code
3.2 Designing A Store
Vuex is used here to store configuration information on each request. We plan to save data to VUEX every 10 minutes, if more than 10 minutes, we will re-request the backend API.
Map is used to store data by modelGuid because it is unique.
const state = {
udf: new Map(),}Copy the code
I’m going to add 2 mutations to operate the UDF
const mutations = {
SET_UDF_MODEL: (state, key, data) = > {
const udfModel = new UdfModel(data.model, data.listTemplate, data.formTemplate)
state.udf.set(key, udfModel)
},
CLEAR_CACHE: (state) = > {
state.udf.clear()
},
}
Copy the code
According to the VUEX specification, we need to add asynchronous Actions instead. In this case, we use the stored time to determine if the value exceeds 10 minutes. If it does, we get the configuration information from HTTP and update it.
const actions = {
setUdfModel({ commit }, guid) {
if (state.udf.has(guid)) {
const val = state.udf.get(guid)
if (val && Math.abs(((new Date()).getTime() - val.createDate.getTime())) > 1000 * 60 * 10) {
return}}const http = new Http()
http.fetch({
url: `/Tools/GetModelDefine/${guid}`.method: 'get',
}).then(data= > {
if (data && 'model' in data) {
commit('SET_UDF_MODEL', guid, data)
}
})
},
clearCache({ commit }) {
commit('CLEAR_CACHE')}},Copy the code
All right, so I’m going to export these variables.
export default {
namespaced: true,
state,
mutations,
actions,
}
Copy the code
3.3 Clearing the Cache
Because VUex does not have persistent storage, the user presses F5 to clear all the cache. In order to make frequent login user experience more pleasant, we actively clear the cache when logging in.
Add a reference to mapActions in the component of the logged in user.
import { mapActions } from 'vuex'
Copy the code
Introduce the cleanup cache method in the component method:
methods: { ... mapActions({clearUdfCache: 'udf/clearCache',}})Copy the code
Then, when the component is created, it is called.
created() {
this.clearUdfCache()
}
Copy the code
3.4 Loading Data
As mentioned earlier, our common operation methods are already extracted into the Mixus class, so we load the data when we define the component’s creation methods.
Since the same public component is used to complete the operation of adding, deleting, changing and checking all modules, according to the optimization strategy of Vue, after switching routes, the public component is not destroyed, but reused, so its Created hook method is only called once.
To enable the new configuration to be invoked after switching routes, we use the method of monitoring routes to load data.
watch: {
$route: function(to, from) {
// todo
// console.log('watch', to)
let guid = ' '
if (to.meta && 'guid' in to.meta) {
guid = to.meta.guid
} else {
let arr = to.path.split('/').slice(0.3)
arr = arr.map(item= > item ? item[0].toUpperCase() + item.substring(1) : ' ')
guid = arr.join(' ')}console.log('guid=', guid)
this.$store.dispatch('udf/setUdfModel', guid)
},
},
Copy the code
After a series of operations, the configuration data can be loaded very well!
4 summary
Laying down every engineer is not what I want to see, we want to help the novice more quickly to save time and focus on more complex requirements logic.
So don’t worry, the above dialogue is just a joke, software engineer is the system development indispensable talent, of course, we should also start more brains, let the tedious repetition away from the human! This is also one of the sacred responsibilities of software engineers