承接上节内容 【vue2.x(二)】vue模版语法(上),继续介绍vue模版语法。
v-if/v-show
用来控制元素显示或隐藏,属性为布尔值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>关注微信公众号【程序员战羽】</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
<div id="app">
<button type="button" @click="isShow =!isShow">改变isShow的值</button>
<p v-if="isShow">该元素被v-if控制是否显示</p>
<p v-show="isShow">该元素被v-show控制是否显示</p>
<p v-if='num>0.7'>范围大于0.7的显示</p>
<p v-else-if="0.5<num<=0.7">范围在0.5到0.7的显示</p>
<p v-else>范围小于等于0.5显示</p>
</div>
<script type="text/javascript">
const app = new Vue({
el:'#app',
data:{
isShow:true,
num:Math.random() //随机生成0-1范围内的数字
}
})
</script>
</body>
</html>
v-if 和 v-show 的区别:
-
控制元素显示或隐藏实现原理不同:
v-if 会动态地创建或移除 DOM 元素。
v-show 会动态为元素添加或移除 style=“display: none;” 样式。
-
性能消耗不同:
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
若需要非常频繁地切换,则使用 v-show 较好;若在运行时条件很少改变,则使用 v-if 较好。
v-for
实现页面列表渲染,常用来循环数组。
v-for索引: 可选参数,表示当前项的索引。
v-for的key: 正确维护列表的状态,并能复用现有的DOM元素,提升渲染的性能。
key的注意事项:
①key 的值只能是字符串或数字类型
②key 的值必须具有唯一性(即:key 的值不能重复)
③ 建议把数据项 id 属性的值作为 key 的值( id 具有唯一性)
④ 使用 index 的值当作 key 的值没有任何意义(index 不具有唯一性)
⑤ 建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>关注微信公众号【程序员战羽】</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
<div id="app">
<ul>
<li v-for="(hot,index) in baiduHotList" :key="hot.id">
{{hot.id}} {{hot.title}}
</li>
</ul>
</div>
<script type="text/javascript">
let app = new Vue({
el: '#app',
data: {
baiduHotList: [{
id: 1,
title: '热点新闻一'
},
{
id: 2,
title: '热点新闻二'
},
{
id: 3,
title: '热点新闻三'
}
]
}
})
</script>
</body>
</html>
表单输入绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>关注微信公众号【程序员战羽】</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
<div id="app">
<form @submit.prevent="submit">
账号:<input type="text" v-model.trim="userInfo.account"> <br /><br />
密码:<input type="password" v-model="userInfo.password"> <br /><br />
年龄:<input type="number" v-model.number="userInfo.age"> <br /><br />
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br /><br />
爱好:
学习<input type="checkbox" v-model="userInfo.hobby" value="study">
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br /><br />
学校所在地区
<select v-model="userInfo.city">
<option value="">请选择地区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select>
<br /><br />
其他信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br /><br />
<input type="checkbox" v-model="userInfo.agree">阅读并接受<a
href="http://www.baidu.com">《用户协议》</a><br /><br />
<button>提交</button>
</form>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //关闭控制台提示
const app = new Vue({
el: '#app',
data: {
userInfo: {
account: '',
password: '',
age: 20,
sex: 'female',
hobby: [],
city: 'beijing',
other: '',
agree: ''
}
},
methods: {
submit() {
console.log(JSON.stringify(this.userInfo))
}
}
})
</script>
</body>
</html>
computed计算属性 /watch状态监听
computed计算属性存在缓存机制,只有当其依赖的响应式数据发生变化时才会清空缓存重新计算结果。
缓存机制本质:由dirty属性控制,当dirty为true时,会重新计算结果。dirty只有当其响应式数据发送变化时设置为true,重新计算后会被重置为false。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>关注微信公众号【程序员战羽】</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
<div id="app">
<button @click="changeNum">更新Num的值</button><br><br>
<button @click="getComputedNum">输出computedNum的值</button><br><br>
<input type="text" v-model="name" />
</div>
<script>
const app = new Vue({
el: '#app',
data: {
num: 0,
name:'程序员战羽'
},
methods: {
changeNum() {
this.num++;
},
getComputedNum() {
console.log(this.computedNum);
}
},
computed: {
computedNum() {
return this.num + '-' + Math.random()
}
},
watch: { //监听用户修改的动作
name(newValue, oldValue) {
console.log(newValue, oldValue)
}
}
})
</script>
</body>
</html>
filters过滤器
filters过滤器:在页面中直接操作数据,返回最终结果(并没有改变原本的数据, 是产生新的对应的数据)。常用于文本的格式化。
过滤器用于两处:插值表达式和 v-bind 属性绑定。
过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用。
注意:过滤器仅在 vue 2.x 和 1.x 中受支持,在 vue 3.x 的版本中剔除了过滤器相关的功能。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>关注微信公众号【程序员战羽】</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!--
过滤器:
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据, 是产生新的对应的数据
-->
<div id="app">
<!-- 在双括号中通过管道符调用capitalize过滤器,对message值进行格式化 -->
<!-- 在v-bind中通过管道符调用capitalize过滤器,对info值进行格式化 -->
<p :title="info | capitalize">{{message | capitalize}}</p>
<!-- 过滤器串联、过滤器不传参 -->
<p :title="info | capitalize">{{message | capitalize | maxLength}}</p>
<!-- 过滤器串联、过滤器传参 -->
<p :title="info | capitalize">{{message | capitalize | maxLength(5)}}</p>
</div>
<div id="app2">
<p>{{name | capitalize}}</p>
</div>
<!-- 全局过滤器 独立于每个VM实例之外-->
<script>
// 首字母大写
Vue.filter('capitalize', (str) => {
return str.charAt(0).toUpperCase() + str.slice(1) + '~~~'
})
// 定义控制文本长度的过滤器(有参数len)
Vue.filter('maxLength', (str, len = 10) => {
if (str.length <= len) return str
return str.slice(0, len) + '...'
})
</script>
<script>
// 需求:首字母大写
const vm = new Vue({
el: '#app',
data: {
message: 'hello zhanyu',
info: 'title zhanyu',
},
// 私有过滤器,只能被当前 vm 所控制的区域所使用
filters: {
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
})
</script>
<script>
const vm2 = new Vue({
el: '#app2',
data: {
name: 'zhanyu'
}
})
</script>
</body>
</html>
自定义指令
vue 官方除了提供 v-for、v-model、v-show等常用内置指令,也允许注册自定义指令。
1、用途:用来操作DOM元素。虽然官方推荐数据驱动视图,但有时还是需要自定义指令来操作DOM。
2、可分为两类:局部自定义指令与全局自定义指令。
3、语法
局部指令:
new Vue({
directives:{指令名:配置对象} 或 directives:{指令名:回调函数}
})
全局指令:
Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
4、钩子函数(在特定阶段执行相关的操作)
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:指令与元素成功绑定时调用【只执行1次】。
inserted:指令所在元素被插入页面时调用【只触发一次】。
update:指令所在模板结构被重新解析时调用【可能触发多次】。
5、注意
指令定义时不加v-,但使用时要加v-。
指令名称要使用kebab-case命名规范。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>关注微信公众号【程序员战羽】</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
<div id="app">
<input type="text" v-custom-bind:value="message"><br><br>
<!-- <input type="text" v-custombind:value="message"><br><br> -->
<div v-demo:foo.a.b="message"></div>
</div>
<script type="text/javascript">
//定义全局指令
// Vue.directive('custom-bind',{
// bind(element,binding){
// element.value = binding.value
// },
// inserted(element,binding){
// element.focus()
// },
// update(element,binding){
// element.value = binding.value
// }
// })
Vue.directive('demo',{
bind:function(el,binding,vnode){
console.log(el)
console.log(binding)
console.log(vnode)
el.innerHTML =
'name: ' + binding.name + '<br>' +
'value: ' + binding.value + '<br>' +
'expression: ' + binding.expression + '<br>' +
'argument: ' + binding.arg + '<br>' +
'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
const app = new Vue({
el: '#app',
data: {
message:'程序员战羽'
},
// 定义局部指令
directives:{
'custom-bind':{
bind:function(element,binding){
element.value = binding.value
},
// bind(element,binding){
// element.value = binding.value
// },
inserted(element,binding){
element.focus()
},
update(element,binding){
element.value = binding.value
}
},
//在 bind 和 update 时触发相同行为,可以简写如下
// 'custom-bind':function(el,binding){
// el.style.backgroundColor = 'red'
// }
// 'custom-bind'(el,binding){
// el.style.backgroundColor = 'red'
// }
// custombind(el,binding){
// el.style.backgroundColor = 'red'
// }
}
})
</script>
</body>
</html>