Vue基础03模板语法
学习Vue的模板语法(插值文本、列表渲染、表单输入绑定、事件处理、class与style绑定)及了解模板语法是如何实现的
1 模板语法
Vue.js使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue.js的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。
什么是模板语法?能够把Vue中声明的数据动态的展示在页面中。
下面以实现一个购物车为例介绍模板语法
1.1 插值文本,显示标题
数据绑定的实现方式
- 文本,双大括号
- 原始html,v-html
- 属性,v-bind
- 使用Javascript表达式,只能访问全局变量的一个白名单,如Date,Math
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
</head>
<body>
<div id="app">
<p>使用插值文本:{{title}}</p>
<p>使用指令v-html:<span v-html="title"></span></p>
<p>使用指令v-bind:<span v-bind:title="title" v-html="title"></p>
<p>使用js表达式: {{title.split('').reverse().join('')}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '<span style="color:red">购物车</span>',
count: 1,
}
}
})
</script>
</body>
</html>
1.2 列表渲染,显示课程列表
使用v-for指令基于一个数组来渲染一个列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
</head>
<body>
<div id="app">
<h2>{{title}}</h2>
<ul>
<li v-for="c in courses" :key="c">{{c}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '购物车',
courses: ['Java开发', 'Vue开发']
}
}
})
</script>
</body>
</html>
1.3 输入绑定,显示课程表单
使用v-model指令在表单input、textarea、select上实现数据双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
</head>
<body>
<div id="app">
<h2>{{title}}</h2>
<input v-model="course"> {{course}}
<div v-for="item in courses" :key="item">
{{ item }}
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '购物车',
courses: ['Web开发', 'Java开发'],
course: ''
}
}
})
</script>
</body>
</html>
1.4 事件处理,新增课程
使用v-on指令监听DOM事件,并在触发时运行JavaScript代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
</head>
<body>
<div id="app">
<h2>{{title}}</h2>
<input v-model="course" v-on:keydown.enter="addCourse">
<button v-on:click="addCourse">新增</button>
<div v-for="item in courses" :key="item">
{{ item }}
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '购物车',
courses: ['web开发', 'java开发'],
course: ''
}
},
methods: {
addCourse() {
if (this.course == '' || this.courses.indexOf(this.course) > -1) {
return
}
this.courses.push(this.course)
this.course = ''
}
},
})
</script>
</body>
</html>
1.5 class与style绑定,选中效果
class和内联样式的绑定
class实现选中效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
<style>
.active {
background-color: #ddd;
}
</style>
</head>
<body>
<div id="app">
<h2>{{title}}</h2>
<input type="text" v-model="course" v-on:keydown.enter="addCourse">
<button v-on:click="addCourse">新增</button>
<div v-for="item in courses" :key="item" @click="selectedCourse = item" :class="{active: selectedCourse == item}">
{{ item }}
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '购物车',
courses: ['web开发', 'java开发'],
course: '',
selectedCourse: ''
}
},
methods: {
addCourse() {
if (this.course == '' || this.courses.indexOf(this.course) > 0) {
reutrn
}
this.courses.push(this.course)
this.course = ''
}
},
})
</script>
</body>
</html>
style实现选中效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
</head>
<body>
<div id="app">
<h2>{{title}}</h2>
<input type="text" v-model="course" v-on:keydown.enter="addCourse">
<button v-on:click="addCourse">新增</button>
<div v-for="item in courses" :key="item"
@click="selectedCourse = item"
:style="{backgroundColor: (selectedCourse === item ? '#ddd' : 'transparent')}">
{{ item }}
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '购物车',
courses: ['web course', 'java course'],
course: '',
selectedCourse: ''
}
},
methods: {
addCourse() {
if (this.course == '' || this.courses.indexOf(this.course) > 0) {
return
}
this.courses.push(this.course)
this.course = ''
}
},
})
</script>
</body>
</html>
1.6 条件渲染,课程为空时提示无课程
使用v-if指令根据条件来显示内容
v-if与v-show的区别?
v-if使用注意事项
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车</title>
</head>
<body>
<div id="app">
<h2>{{title}}</h2>
<input type="text" v-model="course" v-on:keydown.enter="addCourse">
<button @click="addCourse">新增</button>
<div v-if="this.courses.length == 0">没有课程</div>
<div v-if="this.courses.length > 0">
<div v-for="item in courses" :key="item">
{{ item }}
</div>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data() {
return {
title: '购物车',
courses: [],
course: '',
selectredCourse: ''
}
},
methods: {
addCourse() {
if (this.course == '' || this.courses.indexOf(this.course) > -1) {
return
}
this.courses.push(this.course)
this.course = ''
}
},
})
</script>
</body>
</html>
2 模板语法是如何实现的
在底层的实现上,Vue将模板编译成虚拟DOM渲染函数.结合响应系统,Vue能够智能地计算出最少需要重新渲染多少组件,并把DOM操作次数减到最少
// 输出vue替我们生成的渲染函数
console.log(app.$options.render)
重写渲染函数
结论:Vue通过它的编译器将模板编译成渲染函数,在数据发生变化的时候再次执行渲染函数,通过对比两次执行结果得出要做的dom操作.