跳转到主要内容

主页内容

Vue基础(三)双向数据绑定与样式绑定

由 webadmin 发布于 阅读 97 次

1、表单输入绑定(双向数据绑定)

1.1、基础用法

当用户修改model数据时,页面dom发生变化;
当用户修改页面dom时,model数据发生变化;

v-model是v-on和v-bind两个指令的语法糖(集合指令)

可以用 v-model 指令在表单 <input>、<textarea> 及 <select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

v-model会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。所以应该通过JavaScript 在组件的 data 选项中声明初始值。

v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。
1.1.1、单行文本和多行文本

单行文本和多行文本不用指定namevalue,直接使用v-model绑定属性名称即可。

<div id="root">
        <div>
            <p>输入框的默认值:{{inputValue}}</p>
            <input type="text" v-model="inputValue">
            <p>多行文本框默认值:{{textareaText}}</p>
            <textarea  v-model="textareaText"></textarea>

        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                inputValue: "",
                textareaText:""
            }

        });
</script>

运行结果:

1.1.2、单选框和复选框

(1)、单选框

单选框需要指定namevalue

<div id="root">
        <div>
            <p>单选框的值:{{radioValue}}</p>
            <input type="radio" name="gender" value="男" v-model="radioValue" />男
            <input type="radio" name="gender" value="女" v-model="radioValue" />女
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                radioValue: '',
            }
        });
</script>

运行结果:

(2)、单个复选框 

如果是单个复选框,需要绑定的值是bool类型,单个复选框不需要指定namevalue

<div id="root">
        <div>
            <p>单复选框的值:{{checked}}</p>
            <!-- 
                如果是单个复选框,需要绑定的值是bool类型,单个复选框不需要指定name和value
            -->
            <input type="checkbox" v-model="checked">是否同意协议
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                checked: true,//单个复选框,true代表默认勾选,false默认不勾选
            },
        });
</script>

运行结果:

(3)、多个复选框

如果是多个复选框需要绑定的是数组,多个复选框的时候,需要指明namevalue

<div id="root">
        <div>
            <h4>多复选框的值:{{hobbies}}</h4>
            <!-- 
                如果是多个复选框需要绑定的是数组
                多个复选框的时候,需要指明name和value
            -->
            <input type="checkbox" name="hobby" value="篮球" v-model="hobbies">篮球
            <input type="checkbox" name="hobby" value="足球" v-model="hobbies">足球
            <input type="checkbox" name="hobby" value="乒乓球" v-model="hobbies">乒乓球
            <input type="checkbox" name="hobby" value="羽毛球" v-model="hobbies">羽毛球
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                hobbies: []
            }
        });
</script>

运行结果:

1.1.3、选择框

对于选择框,无需定义namevalue可有可无。如果没有value,选择的值以option选择的文本作为值,如果有value则以value的值作为值。

(1)、选择框单选时

如果v-model表达式的初始值未能匹配任何选项,<select>元素将被渲染为“未选中“状态。在iOS中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发change 事件。因此,更推荐像下面这样提供一个值为空的禁用选项。

<div id="root">
        <div>
            <p>选择框单选的值:{{selectValue}}</p>
            <select v-model="selectValue">
                <option value="" disabled>请选择</option>
                <option>A</option>
                <option>B</option>
                <option>C</option>
                <option>D</option>
                <option>E</option>
            </select>
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                selectValue: ''
            }
        });
</script>

运行结果:

(2)、选择框多选时

多选时,绑定的是数组。

<div id="root">
        <div>
            <h4>选择框多选时的值:{{selectMultiple}}</h4>
            <!-- 
                多选时,绑定的是数组
            -->
            <select v-model="selectMultiple" multiple>
                <option value="" disabled>请选择</option>
                <option>刘德华</option>
                <option>张学友</option>
                <option>梁朝伟</option>
                <option>黎明</option>
                <option>郑少秋</option>
            </select>
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                selectMultiple:[]
            }
        });
</script>

运行结果:

1.1.4、v-for渲染动态选项
<div id="root">
        <div>
            <h4>v-for渲染动态选项:{{options}}</h4>
            <select v-model="options">
                <option v-for="option in options" :value="option.value">
                	{{option.option}}
                </option>
            </select>
        </div>
</div>
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                options:[
                    {'option':'刘德华','value':'liudehua'},
                    {'option':'张学友','value':'zhangxueyou'},
                    {'option':'黎明','value':'liming'},
                    {'option':'周润发','value':'zhourunfa'}
                ]
            }
        });
</script>

运行结果:

1.2、修饰符
1.2.1、.lazy修饰符

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步(除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在change 事件之后进行同步:

<div id="root">
        <div>
            <p>输入框的默认值:{{inputValue}}</p>
            <!-- 
                使用了.lazy修饰符,不再是一边输入一边更新了,而是在输入完成焦点离开input框以后才更新 
            -->
            <input type="text" v-model.lazy="inputValue">
        </div>
</div>
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                inputValue: '',
            }
        });
</script>
1.2.2、.number修饰符

如果需要自动将用户的输入值转为数值类型,可以给v-model添加number修饰符:

<div id="root">
        <div>
            <p>.number修饰符使用</p>
            <!-- 
                如果需要自动将用户的输入值转为数值类型,可以给v-model添加number修饰符: 
            -->
            <input type="text" v-model.number="age">
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                age: ''
            }
        });
</script>

运行结果:

这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法parseFloat()解析,则会返回原始的值。

1.2.3、.trim修饰符

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<div id="root">
        <div>
            <p>.trim修饰符使用</p>
            <!-- 
               如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符  
            -->
            <input type="text" v-model.trim="trimValue">
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                trimValue: ''
            }
        });
</script>

运行结果:

2、class和style绑定

操作元素的class 列表和内联样式是数据绑定的一个常见需求。因为它们都是attribute,所以我们可以用v-bind处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将v-bind 用于classstyle 时,Vue.js做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

2.1、绑定html的class
2.1.1、对象语法

我们可以传给 v-bind:class (简写::class="")一个对象,以动态地切换 class

<style type="text/css">
        .my-class{
            width: 200px;
            height: 200px;
            background-color: red !important;
        }
        .active{
            width: 200px;
            height: 200px;
            background-color: #00ff;
        }
</style>
<div id="root">
        <div>
            <h4>对象语法动态绑定class类</h4>
            <!-- 
                对象语法:键值对(key:value)
                样式类名为对象名称(key),值(value)为boolean类型:true表示样式类生效,
                false表示样式类无效样式类名中有特殊符号需要使用引号包裏 
            -->
            <div :class="{active : isActive, 'my-class': isMyclass}">
                <p>div的内容</p>
            </div>
        </div>
</div>
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                isActive: false,
                isMyclass: true
            }
        });
</script>

上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActive 的真假。"my-class"也是一样取决于isMyclass属性。

可以在对象中传入更多字段来动态切换多个 class。此外, v-bind:class 指令也可以与普通的 class attribute共存。当有如下模板:

<div class="box" :class="{active : isActive, 'my-class': isMyclass}">
     <p>div的内容</p>
</div>

isActive 或者 isMyclass 变化时,class 列表将相应地更新。例如,如果 isMyclass 的值为true, class 列表将变为 "box my-class"

绑定的数据对象不必内联定义在模板里:

<div id="root">
        <div>
            <h4>对象语法动态绑定class类</h4>
            <div class="box" :class="classObj">
                <p>div的内容</p>
            </div>
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                classObj:{
                    active: false,
                    'my-class': true
                }  
            }
        });
</script>

运行结果:

2.1.2、数组语法

可以把一个数组传给 :class,以应用一个 class 列表:

<div id="root">
        <div>
            <h4>数组写法</h4>
            <!-- 
                数组写法:样式类名以字符串的方法定义在数组
            -->
            <div :class="[box,myClass,active]">数组写法内容</div>
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                box: 'box',
                myClass:'my-class',
                active: 'active'
            }
        });
</script>

无论使用数组写法还是对象写法都不影响使用class属性静态绑定的样式。

2.1.3、使用内联样式

(1)、对象写法

:style 的对象语法十分直观,看起来非常像CSS,但其实是一个JavaScript 对象。CSS property 名可以用驼峰式(camelCase) 或短横线分隔(kebab-case,需要用引号括起来)来命名:

<div id="root">
        <div>
            <h2>使用内联样式</h2>
            <!-- 
                对象属性名称为样式属性名,值为样式值,可以为字符串类型、数值等类型
                样式属性名中带有特殊符号,那么需要使用引号包裹或者使用驼峰写法 
            -->
            <h4>对象语法:</h4>
            <div :style="{backgroundColor: bgColor, width: Whidth, height: Height, fontSize: fontSize}">
                对象语法写法测试
            </div>
        </div>
</div> 
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                bgColor: 'red',
                Whidth: '200px',
                Height: '150px',
                fontSize: 18+'px'
            }
        });
</script>

运行结果:

(2)、数组写法

:style 的数组语法可以将多个样式对象应用到同一个元素上:

<div id="root">
        <div>
            <h4>数组的写法:</h4>
            <div :style="[baseStyle, fontStyle]">数组写法测试</div>
        </div>
</div>
<script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data:{
                baseStyle:{
                    width: '200px',
                    height: '150px',
                    backgroundColor: 'red'
                },
                fontStyle:{
                    fontSize: 18+'px',
                    color: 'white'
                }
            }
        });
</script>

运行结果:

:style 使用需要添加浏览器引擎缀的CSS property 时,如transformVue.js 会自动侦测并添加相应的前缀。