Vue指令之v-model
v-model 和 v-show 是 Vue 核心功能中内置的、开发者不可自定义的指令。我们可以使用 v-model 为可输入元素(input & textarea)创建双向数据绑定,它会根据元素类型自动选取正确的方法来更新元素。例如,在输入框上使用时,输入的内容会实时映射到绑定的数据上。
v-model使用方法如下:
<div id="app">
<h4>{{ msg }}</h4>
<input type="text" style="width: 100%" v-model="msg">
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
msg:'大家都是好学生,爱敲代码,爱学习'
},
methods:{}
});
</script>
提示: 使用 v-model 后,表单控件显示的值只依赖所绑定的数据,不再关心初始化时的value属性。
注意: v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V 中,无法实现数据的双向绑定。使用 v-model 可以实现 表单元素和 Model 中数据双向绑定,但是,v-model 只能运用在 表单元素中 [input\select\checkbox\textArea] 。
在Vue中使用样式
- 使用class样式
<head>
<style>
.red{
color: red;
}
.thin{
font-weight: 200;
}
.italic{
font-style: italic; /*设置文字倾斜*/
}
.active{
letter-spacing: 0.5em; /*设置中文字符间距*/
}
</style>
</head>
<body>
<div id="app">
<!-- 第一种使用方式,直接传递一个数组。注意:这里的 class 需要使用 v-bind 做数据绑定-->
<h1 :class="['red','thin','italic']">使用 v-bind 实现为元素属性绑定样式</h1>
<!-- 第二种使用方式,在数组中使用三元表达式-->
<h1 :class="['red','thin',flag?'active':'']">在数组中使用三元表达式</h1>
<!-- 第三种使用方式,在数组中使用 对象 来代替三元表达式,提高代码可读性-->
<h1 :class="['thin',{'active':flag}]">在数组中使用对象替代三元表达式</h1>
<!-- 第四种使用方式,在为 class 使用 v-bind 绑定 对象 的时候,对象的属性是类名,由于 对象 的属性可带引号,也可不带引号。属性值 是一个标识符,true 表示显示样式-->
<h1 :class="objStyle">第三种方式实现更改 class 样式</h1>
</div>
<script>
// 创建 Vue 实例
let vm = new Vue({
el:'#app',
data:{
flag:true,
// 绑定到 h1 的 class 属性上
objStyle:{red:true, thin:true, italic:false, active:true}
},
methods:{}
});
</script>
</body>
- 使用内联样式
<div id="app">
<!-- 方式1:直接在元素上通过 :style 设置样式对象。对象就是无序键值对的集合-->
<h1 :style="styleObj1">这是一个h1</h1>
<!-- 方式2:在 :style 中通过数组,引用多个 data 上的样式对象-->
<h1 :style="[styleObj1,styleObj2]">这是一个h1</h1>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
//【如果键中包含 - ,则必须要加引号,这是规定】
styleObj1:{color:'red', 'font-weight':200 },
styleObj2:{'font-style':'italic'}
},
methods:{}
});
</script>
列表渲染指令 v-for 和 key 属性
当需要将一个数组遍历或枚举一个对象循环显示时,就会用到列表渲染指令 v-for 它的表达式需结合 in 来使用,类似 item in items 的形式。如下:
<div id="app">
<p v-for="item in list">{{ item }}</p>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
list:[1,2,3,4,5,6]
},
methods:{}
});
</script>
在表达式中,list 是数据,item 是当前数组元素的别名,循环出的每一个 p 标签内的元素都可以访问到对应的当前数据 item。
除了可以循环普通数组外,它还可以循环对象数组、对象以及迭代数字。
- 循环对象数组如下:
<div id="app">
<!--<p v-for="user in list">账号:{{ user.id }} --- 姓名:{{ user.name }}</p>-->
// (user,i):第一个参数表示当前的数组元素的别名;第二个参数代表当前的索引值,默认从0开始
<p v-for="(user,i) in list">索引:{{ i }} --- 账号:{{ user.id }} --- 姓名:{{ user.name }}</p>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
list:[
{id:1, name:'zs'},
{id:2, name:'wyf'},
{id:3, name:'ls'}
]
},
methods:{}
});
</script>
- 循环对象如下:
<div id="app">
<!-- 注意:在遍历对象身上的键值对时,参数分别为 值 键 索引-->
<p v-for="(val, key, index) in user">值:{{ val }} === 键:{{ key }} === 索引:{{ index }}</p>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
user:{
id:1,
name:'wyf'
}
},
methods:{}
});
</script>
- 迭代数字 如下:
<div id="app">
<!-- in 后面可以放 普通数组、对象数组、对象、数字
注意:如果使用 v-for 迭代数字,count 从 1 开始
-->
<p v-for="count in user">这是第 {{ count }}次循环</p>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
user:{
id:1,
name:'wyf'
}
},
methods:{}
});
</script>
注意:v-for 循环时,key 属性只能使用 number获取string。key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值。在组件中,使用 v-for 循环时,或者在一些特殊情况中,如果 v-for 有问题,必须在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值
<p v-for="item in list" :key="item.id">
<input type="checkbox">{{item.id}} === {{item.name}}
</p>
条件渲染指令 v-if 和 v-show 的使用和特点
<div id="app">
<input type="button" @click="toggle" value="切换">
<!--
v-if 特点:每次都会重新删除或创建DOM元素
v-show特点:每次不会重新进行DOM的删除和创建操作,知识切换了元素的 display:none 样式
v-if 有较高的切换性能消耗
v-show 有较高的初始渲染消耗
如果元素涉及到频繁的切换,最好不要使用 v-if,而是推荐使用 v-show
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if
-->
<h3 v-if="flag">这是用 v-if 控制的元素</h3>
<h3 v-show="flag">这是用 v-show 控制的元素</h3>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
flag:true
},
methods:{
toggle() {
this.flag =!this.flag;
}
}
});
</script>
总结: v-if 和 v-show 具有类似的功能,不过 v-if 才是真正的条件渲染,它会根据表达式适当的销毁或重建元素及绑定的事件或子组件。若表达式初始值为 false,则一开始元素/组件并不会渲染,只有当条件第一次变为 true 时才开始编译。
而 v-show 只是简单的 CSS 属性切换,无论条件真与否,都会被编译。相比之下,v-if 更适合条件不经常改变的场景,因为它切换开销相对较大,而 v-show 适用于频繁切换条件。
过滤器
Vue.js支持在 {{ }} 插值的尾部添加一个管道符 “(|)” 对数据进行过滤,经常用于格式化文本,比如字母全部大写、货币千位使用逗号分隔等。过滤的规则是自定义的,通过给 Vue 实例添加选项 filters 来设置。
- 全局过滤器代码实现如下:
<div id="app">
<p>{{ msg | msgFormat('疯狂','123') | test }}</p>
</div>
<script>
// 定义一个 Vue 全局过滤器,名字叫做 msgFormat
// 过滤器中的 function 方法,第一个参数 已经被规定死了,永远都是 过滤器管道符( | )前面 传递过来的数据
Vue.filter('msgFormat',function (msg,arg,arg2) {
// 将 “单纯” 替换为 “疯狂123”
return msg.replace(/单纯/g,arg+arg2);
});
Vue.filter('test',function (msg) {
return msg + "=========";
});
new Vue({
el:'#app',
data:{
msg:'曾经,我也是一个单纯的少年,单纯的我,傻傻的问,谁是世界上最单纯的人'
},
methods:{}
});
</script>
说明:过滤器可以串联,而且可以接收参数。例如:
<!-- 串联 -->
{{ message | filterA | filterB }}
<!-- 接收参数 -->
{{ message | filterA('arg1','arg2') }}
这里的字符串 arg1 和 arg2 将分别传给过滤器的第二个和第三个参数,因为第一个参数是固定的,表示数据本身。
2. 私有过滤器
<div id="app2">
<p>{{ msg | dataFormat}}</p>
</div>
<script>
new Vue({
el:'#app2',
data:{
msg:new Date()
},
methods: {},
filters:{ // 定义私有过滤器,过滤器有两个条件【过滤器名称】和【处理函数】
// 过滤器调用的时候,采用的是就近原则。
// 如果私有过滤器和全局过滤器名称一样,这时候 优先调用私有过滤器
dataFormat(data,pattern = "") {
let dt = new Date(data);
let y = dt.getFullYear();
let m = dt.getMonth()+1;
let d = dt.getDate();
if(pattern.toLowerCase() === "yyyy-mm-dd"){
return `${y}-${m}-${d}`;
}else{
let hh = dt.getHours();
let mm = dt.getMinutes();
let ss = dt.getSeconds();
return `${y}-${m}-${d}-${hh}:${mm}:${ss}==========`;
}
}
}
});
</script>