A mature form

Form form , You have grown up , You have to learn to :

  • Dynamic rendering
  • Single column support 、 Double column 、 Multiple columns
  • Support to adjust the layout
  • Support form validation
  • Support to adjust the arrangement ( Show ) The order
  • Display required components according to component values
  • Support item Extension components
  • Can automatically create model

This form control is based on element-plus Of el-form Make a second encapsulation , So first of all, thank you element-plus Provides such a powerful UI library , Previously used jQuery I've done something like that , But it's very troublesome , It doesn't look good , Maintainability 、 Poor scalability , A lot of ideas don't come true ( Limited technology ).

Ok now , Standing on the shoulders of giants , I realized my idea .

Achieve dynamic rendering

Put the required attributes of the form , Put it all in json Inside , And then use require( convenient ) perhaps aioxs( Can be hot updated ) Loading in , In this way, dynamic rendering can be realized .

For example, to add company information 、 modify , So just load what the company information needs json that will do .

Want to add employee information 、 modify , Then you only need to load what the employee information needs json.

All in all , Load what you need json that will do , No more hand code .

So this amazing json What does it look like ? The file is a little long , Look directly at the screenshot , More clearly .

There are several additional features :

  • Supports merging under single line .

    In the case of a single line , Some short controls will take up more space , We can merge multiple small ones into one line .

  • Support extension under multiple lines .

    In the case of multiple lines , Some long controls need to take up more space , We can set it to take up a few more squares .

  • Automatically creating forms requires model.

    There is no need to write model 了 .

Realize the form of multi row and multi column

Thank you again for el-form, It's really powerful , Not only beautiful , Verification function is also provided , There are many other functions .

It's just like it's just horizontal , Or in vertical rows . So can we have more rows and more columns ? There seems to be no direct provision of .

We know el-row、el-col It can realize the function of multi row and multi column , So can we combine them ? The official website doesn't say it directly , I'm looking for , Fortunately, I found .( ok , In fact, it's been a while table)

Just combine the two , Here's a tip ,el-row Just one is enough ,el-col There can be multiple , When this line is full , It will automatically go to the next line .

 <el-form
ref="form"
:inline="false"
class="demo-form-inline"
:model="formModel"
label-suffix=":"
label-width="130px"
size="mini"
>
<el-row>
<!-- No circulation row, Direct circulation col, If you can't put it down, it will wrap down automatically .-->
<el-col
v-for="(ctrId, index) in formColSort"
:key="'form_'+index"
:span="formColSpan[ctrId]"
>
<el-form-item :label="getCtrMeta(ctrId).label">
<!-- Forms item Components , Using dynamic components -->
<component
:is="ctlList[getCtrMeta(ctrId).controlType]"
v-model="formModel[getCtrMeta(ctrId).colName]"
:meta="getCtrMeta(ctrId)"
@myChange="mySubmit">
</component>
</el-form-item>
</el-col>
</el-row>
</el-form>
  • formColSort

    Storing components ID Array of , It determines which components are displayed and in which order they are displayed .

  • v-for

    Traverse formColSort Get the components ID, And get ID Corresponding span( Determine the occupancy ) And what components need meta.

  • formColSpan

    An array that holds the component footprint . basis el-col Of span Of 24 Grid settings .

  • getCtrMeta(ctrId)

    According to the components ID Get the meta.

    Why write a function ? because model Parentheses are not allowed for properties of , So I have to write a function .

    Why not compute properties ? Calculated properties don't seem to pass parameters .

  • component :is="xxx"

    Vue Dynamic components provided , You can easily load different types of subcomponents with this .

  • ctlList

    Component Dictionary , Change the component type into the corresponding component label .

Such a v-for A lot of things have been done , For example, single column 、 Multiple columns , The sorting of components , The space occupying problem of components , There is also the problem of displaying different components according to the user's choice , In fact, it's just a revision formColSort The components in ID The composition and order of the .

Automatically create model

I compare lazy , Hand rolling model Isn't it a bit troublesome ? If only we could get it automatically , So I wrote this function .

 // According to the form elements meta, establish v-model
const createModel = () => {
// basis meta, establish module
for (const key in formItemMeta) {
const m = formItemMeta[key]
// Set property values based on control type
switch (m.controlType) {
case 100: // The text class
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
case 130:
case 131:
formModel[m.colName] = ''
break
case 110: // date
case 111: // Date time
case 112: // years
case 114: // year
case 113: // Year week
formModel[m.colName] = null
break
case 115: // Any time
formModel[m.colName] = '00:00:00'
break
case 116: // Selection time
formModel[m.colName] = '00:00'
break
case 120: // Numbers
case 121:
formModel[m.colName] = 0
break
case 150: // Check
case 151: // switch
formModel[m.colName] = false
break
case 153: // Radio group
case 160: // Drop down the radio
case 162: // Pull down linkage
formModel[m.colName] = null
break
case 152: // Multiple choice group
case 161: // Pull down multiple choices
formModel[m.colName] = []
break
}
// See if there's a default set
if (typeof m.defaultValue !== 'undefined') {
switch (m.defaultValue) {
case '':
break
case '{}':
formModel[m.colName] = {}
break
case '[]':
formModel[m.colName] = []
break
case 'date':
formModel[m.colName] = new Date()
break
default:
formModel[m.colName] = m.defaultValue
break
}
}
}
// Synchronization of parent components v-model
context.emit('update:modelValue', formModel)
return formModel
}

Depending on the type and default value , Set up model Properties of , It's much more convenient .

Create a user selected model

The user selects an option , The components of the form respond to the changed model.

I need such a simple one in my plan model, So I wrote another function

 // Depending on user options , Create the corresponding model
const createPartModel = (array) => {
// Delete attributes first
for (const key in formPartModel) {
delete formPartModel[key]
}
// Create new attributes
for (let i = 0; i < array.length; i++) {
const colName = formItemMeta[array[i]].colName
formPartModel[colName] = formModel[colName]
}
}

So you can get a simple model 了 .

Multi column forms

This is the most complicated , There are two cases : Single row squeeze 、 Multi column position grabbing .

Single column

A single column form has one feature , The line is relatively loose , So sometimes you need to display two components in one line , The others are just one component per line , So how to adjust ?

Here's a setup :

  • One component, one line , Remember to do 1
  • Two components in a row , Remember to do -2
  • Three components in a row , Remember to do -3

    And so on , In theory, the most support is -24, Of course, it doesn't seem to have such a wide display .

After recording like this , We can judge ,≥1 What do you remember span=24, negative , use 24 Remove , What you get is span The number of . Of course, take the whole number .

Why mark it with a negative number ? It is to distinguish the adjustment of multiple columns .

Multiple columns

I found a problem after adjusting too much , It looks the same as after single column adjustment .

A multi column form has one feature , One grid is smaller , Some components are too long to fit , At this time, this component will be used in the back grid .

So let's make a setting :

  • One component occupies one space , Still remember to do 1
  • One component takes up two spaces , Remember to do 2
  • One component occupies three spaces , Remember to do 3

    And so on .

After recording like this , We can judge ,≤1 Of , Remember to do 24 / Number of columns , Greater than 1 What do you remember 24/ Number of columns * n.

That's it , Compatible with single column settings , You don't have to adjust the settings for changing from single column to multi column .

Just a little trouble , If it takes up too much space , It will be squeezed to the next line , And there will be “ vacancy ”.

Let's adjust this manually for the time being .

After all, which field comes first , It needs to be set manually .

An analysis is as fierce as a tiger , There are few lines of code .

 // According to the configuration colCount, Set up formColSpan
const setFormColSpan = () => {
const formColCount = formMeta.formColCount // Number of columns
const moreColSpan = 24 / formColCount // How many copies of a grid if (formColCount === 1) {
// A column of information
for (const key in formItemMeta) {
const m = formItemMeta[key]
if (typeof m.colCount === 'undefined') {
formColSpan[m.controlId] = moreColSpan
} else {
if (m.colCount >= 1) {
// Single column , Only 24 grid
formColSpan[m.controlId] = moreColSpan
} else if (m.colCount < 0) {
// A squeeze situation , 24 Divide Share of
formColSpan[m.controlId] = moreColSpan / (0 - m.colCount)
}
}
}
} else {
// In the case of multiple columns
for (const key in formItemMeta) {
const m = formItemMeta[key]
if (typeof m.colCount === 'undefined') {
formColSpan[m.controlId] = moreColSpan
} else {
if (m.colCount < 0 || m.colCount === 1) {
// Multiple columns , Squeeze a share of
formColSpan[m.controlId] = moreColSpan
} else if (m.colCount > 1) {
// Multiple columns , The number of squares occupied * Additional copies
formColSpan[m.controlId] = moreColSpan * m.colCount
}
}
}
}
}

Finally, let's see the effect , The number of columns can be set dynamically :

【 Video 1 】

https://www.zhihu.com/zvideo/1347091197660405760

According to the user's choice , Display the corresponding component

This is also an urgent function , Otherwise , The adaptability of dynamic rendering form controls will be limited .

Actually, it's not hard to think about it , Just change it formColSort Components inside ID Just fine .

We set up a watch To monitor changes in component values , And then put the components you need ID Set to formColSort That's all right. .

 // Listen for changes in component values , Adjust the display of components and display order 
if (typeof formMeta.formColShow !== 'undefined') {
for (const key in formMeta.formColShow) {
const ctl = formMeta.formColShow[key]
const colName = formItemMeta[key].colName
watch(() => formModel[colName], (v1, v2) => {
if (typeof ctl[v1] === 'undefined') {
// No settings , Show default components
setFormColSort()
} else {
// Display the components according to the settings
setFormColSort(ctl[v1])
// Set up part of model
createPartModel(ctl[v1])
}
})
}
}

Because there may be more than one component to listen to , So I did a loop , So you can listen to all the components you need .

Look at the effect

【 Video 2 】

https://www.zhihu.com/zvideo/1347099700483457024

Complete code

The code above is messy , Here's a general introduction .

  • el-form-manage.js

    Management class of form component , Take it out alone , So you can support other UI The library , such as antdv
import { reactive, watch } from 'vue'
/**
* Form management class
* * establish v-model
* * Adjust the number of columns
* * Merge
*/
const formManage = (props, context) => {
// Definition complete v-model
const formModel = reactive({})
// Define local model
const formPartModel = reactive({}) // Determine how many cells a component occupies
const formColSpan = reactive({})
// Define sort by
const formColSort = reactive([])
// Get the form meta
const formMeta = props.meta
console.log('formMeta', formMeta)
// Form Elements meta
const formItemMeta = formMeta.itemMeta
// Form validation meta, spare
// const formRuleMeta = formMeta.ruleMeta // According to the form elements meta, establish v-model
const createModel = () => {
// basis meta, establish module
for (const key in formItemMeta) {
const m = formItemMeta[key]
// Set property values based on control type
switch (m.controlType) {
case 100: // The text class
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
case 130:
case 131:
formModel[m.colName] = ''
break
case 110: // date
case 111: // Date time
case 112: // years
case 114: // year
case 113: // Year week
formModel[m.colName] = null
break
case 115: // Any time
formModel[m.colName] = '00:00:00'
break
case 116: // Selection time
formModel[m.colName] = '00:00'
break
case 120: // Numbers
case 121:
formModel[m.colName] = 0
break
case 150: // Check
case 151: // switch
formModel[m.colName] = false
break
case 153: // Radio group
case 160: // Drop down the radio
case 162: // Pull down linkage
formModel[m.colName] = null
break
case 152: // Multiple choice group
case 161: // Pull down multiple choices
formModel[m.colName] = []
break
}
// See if there's a default set
if (typeof m.defaultValue !== 'undefined') {
switch (m.defaultValue) {
case '':
break
case '{}':
formModel[m.colName] = {}
break
case '[]':
formModel[m.colName] = []
break
case 'date':
formModel[m.colName] = new Date()
break
default:
formModel[m.colName] = m.defaultValue
break
}
}
}
// Synchronization of parent components v-model
context.emit('update:modelValue', formModel)
return formModel
}
// Run it first
createModel() // Submit... To the parent component model
const mySubmit = (val, controlId, colName) => {
context.emit('update:modelValue', formModel)
// Sync to part model
if (typeof formPartModel[colName] !== 'undefined') {
formPartModel[colName] = formModel[colName]
}
context.emit('update:partModel', formPartModel)
} // Depending on user options , Create the corresponding model
const createPartModel = (array) => {
// Delete attributes first
for (const key in formPartModel) {
delete formPartModel[key]
}
// Create new attributes
for (let i = 0; i < array.length; i++) {
const colName = formItemMeta[array[i]].colName
formPartModel[colName] = formModel[colName]
}
} // According to the configuration colCount, Set up formColSpan
const setFormColSpan = () => {
const formColCount = formMeta.formColCount // Number of columns
const moreColSpan = 24 / formColCount // How many copies of a grid if (formColCount === 1) {
// A column of information
for (const key in formItemMeta) {
const m = formItemMeta[key]
if (typeof m.colCount === 'undefined') {
formColSpan[m.controlId] = moreColSpan
} else {
if (m.colCount >= 1) {
// Single column , Only 24 grid
formColSpan[m.controlId] = moreColSpan
} else if (m.colCount < 0) {
// A squeeze situation , 24 Divide Share of
formColSpan[m.controlId] = moreColSpan / (0 - m.colCount)
}
}
}
} else {
// In the case of multiple columns
for (const key in formItemMeta) {
const m = formItemMeta[key]
if (typeof m.colCount === 'undefined') {
formColSpan[m.controlId] = moreColSpan
} else {
if (m.colCount < 0 || m.colCount === 1) {
// Multiple columns , Squeeze a share of
formColSpan[m.controlId] = moreColSpan
} else if (m.colCount > 1) {
// Multiple columns , The number of squares occupied * Additional copies
formColSpan[m.controlId] = moreColSpan * m.colCount
}
}
}
}
}
// Run it first
setFormColSpan() // Set the display order of components
const setFormColSort = (array = formMeta.colOrder) => {
formColSort.length = 0
formColSort.push(...array)
}
// Run it first
setFormColSort() // Listen for changes in component values , Adjust the display of components and display order
if (typeof formMeta.formColShow !== 'undefined') {
for (const key in formMeta.formColShow) {
const ctl = formMeta.formColShow[key]
const colName = formItemMeta[key].colName
watch(() => formModel[colName], (v1, v2) => {
if (typeof ctl[v1] === 'undefined') {
// No settings , Show default components
setFormColSort()
} else {
// Display the components according to the settings
setFormColSort(ctl[v1])
// Set up part of model
createPartModel(ctl[v1])
}
})
}
} return {
// object
formModel, // v-model createModel()
formPartModel, // Of the components selected by the user model
formColSpan, // Determine the component footprint
formColSort, // Determine component ordering
// function
createModel, // establish v-model
setFormColSpan, // Set the component footprint
setFormColSort, // Set the component sort
mySubmit // Submit
}
} export default formManage
  • el-form-map.js

    Dynamic components need dictionaries
import { defineAsyncComponent } from 'vue'
/**
* Component inside the registration control with
* * Text
* ** eltext Single line text 、 Telephone 、 mail 、 Search for
* ** elarea Multiline text
* ** elurl
* * Numbers
* ** elnumber Numbers
* ** elrange slider
* * date
* ** eldate date 、 years 、 Year week 、 year
* ** eltime Time
* * choice
* ** elcheckbox Check
* ** elswitch switch
* ** elcheckboxs Multiple choice group
* ** elradios Radio group
* ** elselect Drop down to select
*/
const formItemList = {
// The text class defineComponent
eltext: defineAsyncComponent(() => import('./t-text.vue')),
elarea: defineAsyncComponent(() => import('./t-area.vue')),
elurl: defineAsyncComponent(() => import('./t-url.vue')),
// Numbers
elnumber: defineAsyncComponent(() => import('./n-number.vue')),
elrange: defineAsyncComponent(() => import('./n-range.vue')),
// date 、 Time
eldate: defineAsyncComponent(() => import('./d-date.vue')),
eltime: defineAsyncComponent(() => import('./d-time.vue')),
// choice 、 switch
elcheckbox: defineAsyncComponent(() => import('./s-checkbox.vue')),
elswitch: defineAsyncComponent(() => import('./s-switch.vue')),
elcheckboxs: defineAsyncComponent(() => import('./s-checkboxs.vue')),
elradios: defineAsyncComponent(() => import('./s-radios.vue')),
elselect: defineAsyncComponent(() => import('./s-select.vue')),
elselwrite: defineAsyncComponent(() => import('./s-selwrite.vue'))
} /**
* Dictionary of dynamic components , Easy v-for Set the control in the loop
*/
const formItemListKey = {
// The text class
100: formItemList.elarea, // Multiline text
101: formItemList.eltext, // Single line text
102: formItemList.eltext, // password
103: formItemList.eltext, // Telephone
104: formItemList.eltext, // mail
105: formItemList.elurl, // url
106: formItemList.eltext, // Search for
// Numbers
120: formItemList.elnumber, // Array
121: formItemList.elrange, // slider
// date 、 Time
110: formItemList.eldate, // date
111: formItemList.eldate, // date + Time
112: formItemList.eldate, // years
113: formItemList.eldate, // Year week
114: formItemList.eldate, // year
115: formItemList.eltime, // Any time
116: formItemList.eltime, // Choose a fixed time
// choice 、 switch
150: formItemList.elcheckbox, // Check
151: formItemList.elswitch, // switch
152: formItemList.elcheckboxs, // Multiple choice group
153: formItemList.elradios, // Radio group
160: formItemList.elselect, // The drop-down
161: formItemList.elselwrite, // Pull down multiple choices
162: formItemList.elselect // Pull down linkage } export default {
formItemList,
formItemListKey
}
  • el-form-div.vue

    Form control code

    Templates
 <div >
<el-form
ref="form"
:inline="false"
class="demo-form-inline"
:model="formModel"
label-suffix=":"
label-width="130px"
size="mini"
>
<el-row>
<!-- No circulation row, Direct circulation col, If you can't put it down, it will wrap down automatically .-->
<el-col
v-for="(ctrId, index) in formColSort"
:key="'form_'+index"
:span="formColSpan[ctrId]"
>
<el-form-item :label="getCtrMeta(ctrId).label">
<!-- Forms item Components , Using dynamic components -->
<component
:is="ctlList[getCtrMeta(ctrId).controlType]"
v-model="formModel[getCtrMeta(ctrId).colName]"
:meta="getCtrMeta(ctrId)"
@myChange="mySubmit">
</component>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>

js

import { watch } from 'vue'
import elFormConfig from '@/components/nf-el-form/el-form-map.js'
import formManage from '@/components/nf-el-form/el-form-manage.js' export default {
name: 'el-form-div',
components: {
...elFormConfig.formItemList
},
props: {
modelValue: Object,
partModel: Object,
meta: Object
},
setup (props, context) {
// Control Dictionary
const ctlList = elFormConfig.formItemListKey // Form management class
const {
formModel, // basis meta, establish Model
formColSpan, // basis meta, establish span
formColSort,
setFormColSpan,
setFormColSort, // Set the component sort
mySubmit
} = formManage(props, context) // Listen for changes in the number of columns
watch(() => props.meta.formColCount, (v1, v2) => {
setFormColSpan()
})
// monitor reload
watch(() => props.meta.reload, (v1, v2) => {
setFormColSpan()
setFormColSort()
}) // Listen for changes in component values ,
// basis ID Get the meta, because model I won't support it 【】 nesting
const getCtrMeta = (id) => {
return props.meta.itemMeta[id] || {}
} return {
formModel,
formColSpan,
formColSort,
ctlList,
getCtrMeta,
mySubmit
}
}
}

It's much simpler here , Because the realization of specific functions js The code is all separated . Or make it into sub components , Or they can form independent js file .

The main task here is to re render the form component .

Form validation

This use el-form The verification function provided .

We haven't summed it up yet el-form Validation of the , Because you need to write the verification data to json Inside , Then read it out and set it .

So it's definitely not difficult , It just takes time .

Support Extension components

The built-in components are certainly not enough , Because the needs of users are always changing , How to add a new component to a form control ? It can be encapsulated into components that meet the requirements according to the interface definition , And make one map Dictionaries , You can set it in .

Because the interface is unified , So it can adapt to the call of form control .

The simple way is , Directly modify two js file .

If it's not convenient to modify , It can also be passed in through attributes . I haven't worked out the details yet , But it doesn't seem too hard .

Source code

https://github.com/naturefwvue/nf-vue-element

Vue3 Components ( Nine )Vue + element-Plus + json = Dynamic rendering of the form control more related articles

  1. Vue.js Learning notes Chapter 7 Form control binding

    This article mainly describes the data binding of form control , There is no new knowledge this time The text box 1. Plain text box <div id="app-1"> <p><input v-model=&q ...

  2. How to dynamically add form Form controls add form validation

    Recently used jQuery Validate It's very convenient to do form validation ,api The address is http://www.runoob.com/jquery/jquery-plugin-validate.html But when it's used, it's also ...

  3. vue.js Basic knowledge (3): Compute properties 、 Form control binding

    Chapter four : Compute properties In order to avoid too much logic resulting in the bloated template , Computational properties can be used to simplify logic . 1. What is calculation property <!DOCTYPE html><html lang="en" ...

  4. Vue.js----- Lightweight and efficient MVVM frame ( 7、 ... and 、 Form control binding )

    Don't talk much , Complete code first : <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  5. Vue# Form control binding

    Use v-model Realize data bidirectional binding on form control . The radio :https://jsfiddle.net/miloer/bs49p0fx/ <input type="checkbox&quo ...

  6. Vue.js Study Item9 – Form control binding

    Basic usage It can be used  v-model  Instruction to create a two-way data binding on a form control element . Depending on the control type, it automatically selects the correct method to update the element . It's kind of magical though ,v-model  It's just grammar candy , Update data in user input events , And special treatment of some ...

  7. Vue Form control binding

    In front of the word This article will introduce in detail Vue Form control binding Basic usage It can be used v-model Instruction to create a two-way data binding on a form control element . It automatically selects the correct method to update the element based on the control type .v-model It's just grammar sugar in essence , It's negative ...

  8. Vue.js Learning notes —— Form control practice

    Recently, I used vue Instead of tedious jquery Handle dom Data update , I like it very much , So I put it into practice on the official website . The following is the practice of form control , From the code , New directly html file , Paste and copy to see the effect ~ <! ...

  9. vue Form control binding ( Automatic collection of form data )

    v-model Instructions You can use it.  v-model  Instruction to create a two-way data binding on a form control element . It automatically selects the correct method to update the element based on the control type . Even though it's magical but  v-model  It's just grammar sugar in essence , It's responsible for monitoring the user's ...

  10. vue v-model Form control binding

    v-model  Instruction to create a two-way data binding on a form control element , Let's explain with examples one by one . 1.v-model Double bind text <!DOCTYPE html> <html> <head ...

Random recommendation

  1. idea Integrate git

    I just used it these days idea Editor . It feels like eclipse There are great advantages . One of the advantages that I think is particularly attractive is the connection with git Integrated development of .git As a platform for code maintenance and idea It's very meaningful for team development to use it in combination . I am a ...

  2. bug Record

    1>-[DYMessageNewsTableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (37 ...

  3. Java IO Programming solution ( One )——Java Of I/O The road of evolution

    Reprint please indicate the source :http://www.cnblogs.com/Joanna-Yan/p/7419117.html JDK1.4 Previous versions ,Java Yes I/O Our support is not perfect , Developers are developing high performance I/O ...

  4. bug The terminator The first week of team work

    bug The terminator The first week of team work Team members and division of labor Team members group leader : 20162323 Zhou Nan Team members : 20162302 Yang Jingdian 20162322 Zhu Yalin 20162327 Wang Jinghan 20162328 Cai Wen ...

  5. Apache Methods of setting port mapping and reverse proxy in server

    stay /etc/httpd/conf The next path httpd.conf file ###new add for webui.cong###Include "E:/local/Wamp/bin/apache/A ...

  6. CF176E Archaeology

    CF176E Archaeology There is a tree \(n\) A weighted tree with two points , Every dot is black or white , At first all the dots were white . Yes \(m\) A asked : The point of \(x\) From white to black The point of \(x\) From black ...

  7. [Micropython]TPYBoardV102 DIY Intelligent temperature control small fan

    1. The experiment purpose 1. Learning in PC It is easy to expand in the computer system I/O Interface method . 2. Further study the design method of data output program . 3. Study DS18B20 The wiring method of the system , And make use of DS18B20 Check the current temperature . 4. Learning triode ...

  8. [skill] C What is a language array name

    1. Under normal circumstances , The array name is an address constant . 2. sizeof( Array name ) When , Array names are numbers , The type of type array[], Returns the number of array elements . 3. except 2 Except in the case of , It can be understood as a pointer constant ...

  9. _event_active

    EventId event ID GUID Corresponding creature or gameobject In the table guid, Positive numbers are creatures , Negative numbers are objects ActiveFlag When an organism or an object is activated flag, Usually it is 0 NoticeText ...

  10. Efficient development iOS series -- The unknown KVC

    My profile address :http://www.jianshu.com/p/a6a0abac1c4a valueForKeyPath This article is to explain those unknown , And it's often overlooked , And it's very useful KVC Dry goods tips a ...