Dynamic input box components
Install Ant Design of Vue
First of all, the steps of creating Vue 3.0 will not be described, there are many related articles on the Internet, directly start to install dependencies, after installing please pay attention to introduce the project, for details, please refer to the official documentation of Ant Design of Vue 2.0.
// The default installation command v2 cannot be installed
npm install ant-design-vue --save
If the version is not V2, the upgrade can be performed
npm i --save ant-design-vue@next
Copy the code
//main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
/ / ant - design - vue component library
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
const app = createApp(App);
app.use(router);
app.use(Antd);
app.mount('#app');
Copy the code
2. Create folders and files
Create a new DynamicInput directory in Components
/ / path: SRC/components/DynamicInput
Copy the code
Create a new js directory in DynamicInput
/ / path: SRC/components/DynamicInput/js
Copy the code
Create index.ts in the js directory under DynamicInput
/ / path: SRC/components/DynamicInput/js/index. The ts
Copy the code
Create a new index.vue file in DynamicInput
/ / path: SRC/components/DynamicInput/index. The vue
Copy the code
Index. vue infrastructure under DynamicInput
//src/components/DynamicInput/index.vue
<template>
<a-row>
</a-row>
</template>
<script lang="ts">
import {defineComponent} from 'vue'
export default defineComponent({
components: {},props: {},emits: [].setup(){
return{}}})</script>
<style scoped>
</style>
Copy the code
New SRC/view/DynamicInputPage. Vue
//src/vie/DynamicInputPage.vue
<template>
<div>
<DynamicInput/>
</div>
</template>
<script>
import DynamicTags from '@/components/DynamicInput/index.vue'
export default {
components:{
DynamicInput,
}
}
</script>
<style scoped>
</style>
Copy the code
Third, the idea of function realization
- Dynamic input box total score is four parts
- Content entry box
- Quantity input box
- Deletes the current row button
- Add the next button
- Each is built from components in the component library
- a-input
- a-input-number
- a-button && MinusOutlined
- a-button && PlusOutlined
- Store each row of data through the Data array
//data data structure
[
/ / the first line
{
"name": "111"."count": 1
},
/ / the second line
{
"name": "2222"."count": 3}]Copy the code
- Each row is iterated through the Data array
- Delete current row button each row is displayed
- Add next line button last line display
- Focus the newly added input box by automatically getting focus
- Automatically delete input fields by losing focus and determining that there is no input
Four, complete source code
- Under DynamicInput index. Vue
//src/components/DynamicInput/index.vue
<template>
<div class="container">
<a-space direction="vertical" ref="inputBoxDom" style="width: 100%" v-if="data.length>0">
<a-row class="item-row" :gutter="20" v-for="(item,index) in data" :key="index">
<a-col :span="16">
<a-input :maxLength="20" v-model:value="item.name" @blur="inputBlur(item,index)"/>
</a-col>
<a-col :span="4">
<a-input-number :min="1" v-model:value="item.count" />
</a-col>
<a-col :span="4">
<a-space>
<a-button type="danger" shape="circle" @click="ItemInputDelBtn(index)">
<template #icon><MinusOutlined /></template>
</a-button>
<a-button type="primary" shape="circle" v-if="index+1==data.length" @click="ItemInputAddBtn(index)">
<template #icon><PlusOutlined /></template>
</a-button>
</a-space>
</a-col>
</a-row>
</a-space>
<a-tag v-else @click="addInput">
<plus-outlined/>Add content</a-tag>
</div>
</template>
<script lang="ts">
import {defineComponent} from 'vue'
import {PlusOutlined,MinusOutlined} from '@ant-design/icons-vue';
import dynamicInput from './js/index';
export default defineComponent({
components:{
PlusOutlined,
MinusOutlined
},
emits: ['change'].setup(props,context){
const {
inputBoxDom,
data,
addInput,
ItemInputAddBtn,
ItemInputDelBtn,
inputBlur,
} = dynamicInput(props,context);
return {
inputBoxDom,
data,
addInput,
ItemInputAddBtn,
ItemInputDelBtn,
inputBlur,
}
}
})
</script>
<style scoped>
</style>
Copy the code
- Create index.ts in the js directory under DynamicInput
/ / path: SRC/components/DynamicInput/js/index. The ts
import {ref,toRaw,watch,nextTick} from 'vue'
import { message } from 'ant-design-vue';
export default function dynamicInput(props: any,context: any) {
const inputBoxDom: any = ref(null);
const data = ref<object[]>([]);
// Add input
const addInput = () = >{
data.value.push({
name:' '.count:1});// Auto focus input box
nextTick(() = > {
const dom = inputBoxDom.value;
const lastIndex = dom.$el.children.length-1;
console.log(dom.$el.children[lastIndex].getElementsByClassName("ant-input") [0].focus());
});
};
// Input box loses focus
const inputBlur = (item: any,index: number) = >{
if(! item.name || ! item.name.trim()){ message.config({maxCount:1}); message.error('Please enter content');
data.value.splice(index,1);
return false;
}
return true;
};
// Add button to input box
const ItemInputAddBtn = (index: number) = >{
if(inputBlur(data.value[index],index)){
data.value.push({
name:' '.count:1}); }// Auto focus input box
nextTick(() = > {
const dom = inputBoxDom.value;
const lastIndex = dom.$el.children.length-1;
console.log(dom.$el.children[lastIndex].getElementsByClassName("ant-input") [0].focus());
});
};
// Input box delete button
const ItemInputDelBtn = (index: number) = >{
data.value.splice(index,1);
};
watch(data.value, (newValue: any, oldValue: any) = > {
context.emit('change',toRaw(newValue))
});
return {
inputBoxDom,
data,
addInput,
ItemInputAddBtn,
ItemInputDelBtn,
inputBlur,
}
}
Copy the code
- src/view/DynamicInputPage.vue
//src/view/DynamicInputPage.vue
<template>
<div class="container">
<div class="formBox">
<DynamicInput @change="inputChange" />
</div>
<div class="jsonCode">
<pre>{{jsonData}}</pre>
</div>
</div>
</template>
<script>
import {ref} from 'vue'
import DynamicInput from '@/components/DynamicInput/index.vue'
export default {
components:{
DynamicInput,
},
setup(){
const jsonData = ref([]);
const inputChange = e= >{
jsonData.value = e;
console.log(e)
};
return{
jsonData,
inputChange
}
}
}
</script>
<style scoped>
.container{
display: flex;
box-sizing: border-box;
margin: 0 auto;
padding: 20px 10px;
width: 100%;
max-width: 1200px;
}
.formBox{
width: 50%;
max-width: 600px;
}
.jsonCode{
box-sizing: border-box;
padding: 20px;
width: 50%;
max-width: 600px;
min-height:200px;
background: # 333;
color: #fff;
}
</style>
Copy the code
Project source code: github.com/jiangzetian…
Demo video of this article: Click browse
More front-end content welcome to pay attention to the public number: day small day personal network