48·灵魂前端工程师养成-Vue表单和v-model

2022-11-08 17:14:14 浏览数 (1)

  • 官方文档

  • 创建项目
  • Vue表单
  • 修饰符
  • v-model
  • Ant Design of Vue
    • 快速上手

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


官方文档


文档很健全

直接查看「表单输入绑定」章节


基本用法

代码语言:javascript复制
input
textarea
checkbox
radio
select
form

修饰符

代码语言:javascript复制
.lazy
.number
.trim

v-model

面试官问你Vue的双向绑定,其实就是在问v-model 但是实际上v-modelv-bind:valuev-on:input的语法糖 v-on:input="xxx=$event.target.value" 这里需要自己背下来

创建项目


创建一个vue项目

代码语言:javascript复制
MacBook-pro:HTML driverzeng$ vue create vue-model-1

使用webstrom打开项目


官方文档拷贝文本

App.vue

代码语言:javascript复制
<template>
    <div id="app">
        <input v-model="message" placeholder="edit me">
        <p>Message is: {{ message }}</p>
    </div>
</template>

<script>
    export default {
        name: 'App',
        components: {
        }
    }
</script>

输入内容没有任何反应。

Vue表单


文本

代码语言:javascript复制
<template>
    <div id="app">
        <input v-model="message" placeholder="edit me">
        <p>Message is: {{ message }}</p>
        <p><button @click="message='zls'">set message to zls</button></p>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                message: 'hi'
            }
        },
        components: {}
    }
</script>


多行文本

代码语言:javascript复制
<template>
    <div id="app">
        <textarea v-model="message" placeholder="edit me"/>
        <p>Message is: {{ message }}</p>
        <p><button @click="message='zls'">set message to zls</button></p>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                message: 'hi'
            }
        },
        components: {}
    }
</script>


复选框

代码语言:javascript复制
<template>
    <div id="app">
        <label>
            <input type="checkbox" v-model="x">
            <span>x:{{ x }}</span>
        </label>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                x: true
            }
        },
        components: {}
    }
</script>


多个复选框

代码语言:javascript复制
<template>
    <div id="app">
        爱好:{{x}}
        <label>
            <input type="checkbox" v-model="x" value="1">
            <span>抽烟</span>
        </label>
        <label>
            <input type="checkbox" v-model="x" value="2">
            <span>喝酒</span>
        </label>
        <label>
            <input type="checkbox" v-model="x" value="3">
            <span>烫头</span>
        </label>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                x: []
            }
        },
        components: {}
    }
</script>

如果数据库用的是数字的类型,那么就使用:value="1"

代码语言:javascript复制
<template>
    <div id="app">
        爱好:{{x}}
        <label>
            <input type="checkbox" v-model="x" :value="1">
            <span>抽烟</span>
        </label>
        <label>
            <input type="checkbox" v-model="x" :value="2">
            <span>喝酒</span>
        </label>
        <label>
            <input type="checkbox" v-model="x" :value="3">
            <span>烫头</span>
        </label>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                x: []
            }
        },
        components: {}
    }
</script>


单选框

代码语言:javascript复制
<template>
    <div id="app">
        你想要:{{x}}
        <label>
            <input name="want" type="radio" v-model="x" :value="1">
            <span>抽烟</span>
        </label>
        <label>
            <input name="want" type="radio" v-model="x" :value="2">
            <span>喝酒</span>
        </label>
        <label>
            <input name="want" type="radio" v-model="x" :value="3">
            <span>烫头</span>
        </label>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                x: ''
            }
        },
        components: {}
    }
</script>


选择框

下拉列表

代码语言:javascript复制
<template>
    <div id="app">
        你想要:{{x}}
        <hr>
        <select v-model="x">
            <option value="">请选择...</option>
            <option :value="1">抽烟</option>
            <option :value="2">喝酒</option>
            <option :value="3">烫头</option>
        </select>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                x: ''
            }
        },
        components: {}
    }
</script>

使用循环

代码语言:javascript复制
<template>
    <div id="app">
        你想要:{{x}}
        <hr>
        <select v-model="x">
            <option value="">请选择...</option>
            <option v-for="item in array" :value="item.value" :key="item.value">{{item.text}}</option>

        </select>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                array: [
                    {text: "抽烟", value: 1},
                    {text: "喝酒", value: 2},
                    {text: "烫头", value: 3},
                ],
                x: ''
            }
        },
        components: {}
    }
</script>

多选菜单

代码语言:javascript复制
<template>
    <div id="app">
        你想要:{{x}}
        <hr>
        <select multiple v-model="x">
            <option value="">请选择...</option>
            <option v-for="item in array" :value="item.value" :key="item.value">{{item.text}}</option>

        </select>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                array: [
                    {text: "抽烟", value: 1},
                    {text: "喝酒", value: 2},
                    {text: "烫头", value: 3},
                ],
                x: []
            }
        },
        components: {}
    }
</script>


登录框

代码语言:javascript复制
<template>
    <div id="app">
        登录
        <form>
            <label>
                <span>用户名:</span>
                <input type="text" v-model="user.username" placeholder="用户名/邮箱/手机">
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model="user.password" placeholder="请输入密码">
            </label>
            <button>登录</button>
        </form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: '',
                    password: ''
                },
                x: []
            }
        },
        components: {}
    }
</script>

保存数据

监听form的submit

代码语言:javascript复制
<template>
    <div id="app">
        登录
        <form @submit.prevent="onSubmit">
            <label>
                <span>用户名:</span>
                <input type="text" v-model="user.username" placeholder="用户名/邮箱/手机">
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model="user.password" placeholder="请输入密码">
            </label>
            <button type="submit">登录</button>
        </form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: '',
                    password: ''
                },
                x: []
            }
        },
        methods:{
            onSubmit(){
                console.log(this.user.username);
                console.log(this.user.password);
            }
        },
        components: {}
    }
</script>

修饰符


.lazy

代码语言:javascript复制
<template>
    <div id="app">
        {{user}}
        <hr>
        登录
        <form @submit.prevent="onSubmit">
            <label>
                <span>用户名:</span>
                <input type="text" v-model="user.username" placeholder="用户名/邮箱/手机">
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model="user.password" placeholder="请输入密码">
            </label>
            <button type="submit">登录</button>
        </form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: '',
                    password: ''
                },
                x: []
            }
        },
        methods:{
            onSubmit(){
                console.log(this.user);
            }
        },
        components: {}
    }
</script>

上面在输入的过程中,就能同时看到变化,如果想阻止这种实时的变化就可以使用.lazy

一般可以用在富文本编辑器的时候,当框内失去焦点的时候,一次性拿出数据。

代码语言:javascript复制
<template>
    <div id="app">
        {{user}}
        <hr>
        登录
        <form @submit.prevent="onSubmit">
            <label>
                <span>用户名:</span>
                <input type="text" v-model.lazy="user.username" placeholder="用户名/邮箱/手机">
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model.lazy="user.password" placeholder="请输入密码">
            </label>
            <button type="submit">登录</button>
        </form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: '',
                    password: ''
                },
                x: []
            }
        },
        methods:{
            onSubmit(){
                console.log(this.user);
            }
        },
        components: {}
    }
</script>

.number

number 的意思就是,我只要数字。

代码语言:javascript复制
<template>
    <div id="app">
        {{user}}
        <hr>
        登录
        <form @submit.prevent="onSubmit">
            <label>
                <span>用户名:</span>
                <input type="text" v-model.number="user.username" placeholder="用户名/邮箱/手机">
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model.number="user.password" placeholder="请输入密码">
            </label>
            <button type="submit">登录</button>
        </form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: 0,
                    password: ''
                },
                x: []
            }
        },
        methods:{
            onSubmit(){
                console.log(this.user);
            }
        },
        components: {}
    }
</script>


.trim

去掉输入两边的空格

代码语言:javascript复制
<template>
    <div id="app">
        {{user}}
        <hr>
        登录
        <form @submit.prevent="onSubmit">
            <label>
                <span>用户名:</span>
                <input type="text" v-model.trim="user.username" placeholder="用户名/邮箱/手机">
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model.trim="user.password" placeholder="请输入密码">
            </label>
            <button type="submit">登录</button>
        </form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: 0,
                    password: ''
                },
                x: []
            }
        },
        methods: {
            onSubmit() {
                console.log(this.user);
            }
        },
        components: {}
    }
</script>

v-model


v-model介绍

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:

代码语言:javascript复制
Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

v-model原生写法

代码语言:javascript复制
<input type="text" :value="user.username" placeholder="用户名/邮箱/手机" @input="user.username = $event.target.value">

自制input

创建一个MyInput.vue

代码语言:javascript复制
<template>
    <div class="red wrapper">
        <input :value="value" @input="onInput">
    </div>
</template>

<script>
    export default {
        name: "MyInput",
        props: {
            value: {
                type: String
            }
        },
        methods: {
            onInput(e) {
                const value = e.target.value;
                this.$emit('input', value)
            }
        }
    }
</script>

<style scoped>
    .red {
        background: red;
    }

    .wrapper {
        display: inline-block;
    }
</style>

App.vue引入MyInput

代码语言:javascript复制
<template>
    <div id="app">
        {{user}}
        <hr>
        登录
        <form @submit.prevent="onSubmit">
            <label>
                <span>用户名:</span>
                <MyInput v-model="user.username"/>
            </label>
            <label>
                <span>密码:</span>
                <input type="password" v-model.trim="user.password" placeholder="请输入密码">
            </label>
            <button type="submit">登录</button>
        </form>
    </div>
</template>

<script>
    import MyInput from "./MyInput";

    export default {
        name: 'App',
        data() {
            return {
                user: {
                    username: '',
                    password: ''
                },
                x: []
            }
        },
        methods: {
            onSubmit() {
                console.log(this.user);
            }
        },
        components: {MyInput}
    }
</script>

Ant Design of Vue

因为饿了么团队目前已经没有在维护Element UI了。

所以我们使用Ant Design。

官方网站:TP GitHub:TP

快速上手


安装ant design

代码语言:javascript复制
## npm安装
MacBook-pro:vue-model-1 driverzeng$ npm i --save ant-design-vue

## yarn安装
MacBook-pro:vue-model-1 driverzeng$ yarn add ant-design-vue

完整引入

main.js

代码语言:javascript复制
import Vue from 'vue';
import App from './App.vue';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';

Vue.config.productionTip = false
Vue.use(Antd)

new Vue({
    render: h => h(App),
}).$mount('#app')

菊部引入

main.js

代码语言:javascript复制
import Vue from 'vue';
import App from './App.vue';
import {Button, message} from "ant-design-vue";

Vue.config.productionTip = false
Vue.use(Button)
Vue.prototype.$message = message

new Vue({
    render: h => h(App),
}).$mount('#app')

Copy一个input

App.vue

代码语言:javascript复制
<template>
    <div id="app">
        <a-input placeholder="Basic usage"/>
    </div>
</template>

<script>
    export default {
        name: 'App',
    }
</script>


input结合from

代码语言:javascript复制
<template>
    <div id="app">
        <a-form
                id="components-form-demo-normal-login"
                :form="form"
                class="login-form"
                @submit.prevent="onSubmit">
            <a-form-item>
                <a-input
                        v-decorator="['username',{rules:[{required:true,message: '你丫没写 用户名 憨皮'}]},]"
                        type="text"
                        placeholder="用户名/邮箱/手机号">
                    <a-icon slot="prefix" type="user" style="color: green"/>
                </a-input>
            </a-form-item>
            <a-form-item>
                <a-input
                        v-decorator="['password',{ rules: [{ required: true, message: '你丫没写 密码 憨皮' }] },]"
                        type="password"
                        placeholder="密码">
                    <a-icon slot="prefix" type="lock" style="color: green"/>
                </a-input>
            </a-form-item>
            <a-form-item>
                <a-checkbox
                        v-decorator="['remember',{valuePropName: 'checked',initialValue: true,},]">记住密码
                </a-checkbox>
                <a class="login-form-forgot" href="">
                    忘记密码
                </a>
                <a-button type="primary" html-type="submit" class="login-form-button">
                    登录
                </a-button>
                Or
                <a href="">
                    现在注册
                </a>
            </a-form-item>
        </a-form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        beforeCreate() {
            this.form = this.$form.createForm(this, {name: 'normal_login'});
        },
        methods: {
            onSubmit() {
                this.form.validateFields((err, values) => {
                    if (!err) {
                        console.log('用户名密码如下:', values);
                    }
                })
            },
        },
    }
</script>


校验密码长度

代码语言:javascript复制
<template>
    <div id="app">
        <a-form
                id="components-form-demo-normal-login"
                :form="form"
                class="login-form"
                @submit.prevent="onSubmit">
            <a-form-item>
                <a-input
                        v-decorator="['username',{rules:[{required:true,message: '你丫没写 用户名 憨皮'}]},]"
                        type="text"
                        placeholder="用户名/邮箱/手机号">
                    <a-icon slot="prefix" type="user" style="color: green"/>
                </a-input>
            </a-form-item>
            <a-form-item>
                <a-input
                        v-decorator="['password',{ rules: [{ required: true, message: '你丫没写 密码 憨皮'},{min:8,message: '最少8位密码 憨皮'}] },]"
                        type="password"
                        placeholder="密码">
                    <a-icon slot="prefix" type="lock" style="color: green"/>
                </a-input>
            </a-form-item>
            <a-form-item>
                <a-checkbox
                        v-decorator="['remember',{valuePropName: 'checked',initialValue: true,},]">记住密码
                </a-checkbox>
                <a class="login-form-forgot" href="">
                    忘记密码
                </a>
                <a-button type="primary" html-type="submit" class="login-form-button">
                    登录
                </a-button>
                Or
                <a href="">
                    现在注册
                </a>
            </a-form-item>
        </a-form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        beforeCreate() {
            this.form = this.$form.createForm(this, {name: 'normal_login'});
        },
        methods: {
            onSubmit() {
                this.form.validateFields((err, values) => {
                    if (!err) {
                        console.log('用户名密码如下:', values);
                    }
                })
            },
        },
    }
</script>


必须包含大小写字母

代码语言:javascript复制
<template>
    <div id="app">
        <a-form
                id="components-form-demo-normal-login"
                :form="form"
                class="login-form"
                @submit.prevent="onSubmit">
            <a-form-item>
                <a-input
                        v-decorator="['username',{rules:[{required:true,message: '你丫没写 用户名 憨皮'}]},]"
                        type="text"
                        placeholder="用户名/邮箱/手机号">
                    <a-icon slot="prefix" type="user" style="color: green"/>
                </a-input>
            </a-form-item>
            <a-form-item>
                <a-input
                        v-decorator="['password',{ rules: [
                            { required: true, message: '你丫没写 密码 憨皮'},
                            {min:8,message: '最少8位密码 憨皮'},
                            {pattern:/[a-zA-Z]/,message:'必须包含大小写字母'}

                        ] },]"
                        type="password"
                        placeholder="密码">
                    <a-icon slot="prefix" type="lock" style="color: green"/>
                </a-input>
            </a-form-item>
            <a-form-item>
                <a-checkbox
                        v-decorator="['remember',{valuePropName: 'checked',initialValue: true,},]">记住密码
                </a-checkbox>
                <a class="login-form-forgot" href="">
                    忘记密码
                </a>
                <a-button type="primary" html-type="submit" class="login-form-button">
                    登录
                </a-button>
                Or
                <a href="">
                    现在注册
                </a>
            </a-form-item>
        </a-form>
    </div>
</template>

<script>
    export default {
        name: 'App',
        beforeCreate() {
            this.form = this.$form.createForm(this, {name: 'normal_login'});
        },
        methods: {
            onSubmit() {
                this.form.validateFields((err, values) => {
                    if (!err) {
                        console.log('用户名密码如下:', values);
                    }
                })
            },
        },
    }
</script>

0 人点赞