引言
这里, v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
在字符串模板中,如 Handlebars ,我们得像这样写一个条件块:随机生成一个数字,判断是否大
于0.5,然后输出对应信息:
Vue.js 事件处理器
事件监听可以使用 v-on 指令:
v-on <div id="app"> <button v-on:click="counter += 1">增加 1</button> <p>这个按钮被点击了 {{ counter }} 次。</p> </div> <script> new Vue({ el: '#app', data: { counter: 0 } }) </script>
通常情况下,我们需要使用一个方法来调用 JavaScript 方法。
v-on 可以接收一个定义的方法来调用。
v-on
<div id="app"> <!-- `greet` 是在下面定义的方法名 --> <button v-on:click="greet">Greet</button> </div> <script> var app = new Vue({ el: '#app', data: { name: 'Vue.js' }, // 在 `methods` 对象中定义方法 methods: { greet: function (event) { // `this` 在方法里指当前 Vue 实例 alert('Hello ' + this.name + '!') // `event` 是原生 DOM 事件 if (event) { alert(event.target.tagName) } } } }) // 也可以用 JavaScript 直接调用方法 app.greet() // -> 'Hello Vue.js!' </script>
除了直接绑定到一个方法,也可以用内联 JavaScript 语句:
v-on <div id="app"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div> <script> new Vue({ el: '#app', methods: { say: function (message) { alert(message) } } }) </script>
事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。
Vue.js 通过由点 . 表示的指令后缀来调用修饰符。
.stop - 阻止冒泡
.prevent - 阻止默认事件
.capture - 阻止捕获
.self - 只监听触发该元素的事件
.once - 只触发一次
.left - 左键事件
.right - 右键事件
.middle - 中间滚轮事件
<!-- 阻止单击事件冒泡 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件侦听器时使用事件捕获模式 --> <div v-on:click.capture="doThis">...</div> <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 --> <div v-on:click.self="doThat">...</div> <!-- click 事件只能点击一次,2.1.4版本新增 --> <a v-on:click.once="doThis"></a>
按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<!-- 只有在 keyCode 是 13 时调用 vm.submit() --> <input v-on:keyup.13="submit">
记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
<!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 缩写语法 --> <input @keyup.enter="submit">
全部的按键别名:
.enter
.tab
.delete (捕获 "删除" 和 "退格" 键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
实例
<p><!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div>
Vue.js 条件语句
条件判断
v-if
条件判断使用 v-if 指令:
v-if 指令
在元素 和 template 中使用 v-if 指令:
<div id="app"> <p v-if="seen">现在你看到我了</p> <template v-if="ok"> <h1>菜鸟教程</h1> <p>学的不仅是技术,更是梦想!</p> <p>哈哈哈,打字辛苦啊!!!</p> </template> </div> <script> new Vue({ el: '#app', data: { seen: true, ok: true } }) </script>
这里, v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
在字符串模板中,如 Handlebars ,我们得像这样写一个条件块:
<!-- Handlebars 模板 --> {{#if ok}} <h1>Yes</h1> {{/if}}
v-else
可以用 v-else 指令给 v-if 添加一个 "else" 块:
v-else 指令
随机生成一个数字,判断是否大于0.5,然后输出对应信息:
<div id="app"> <div v-if="Math.random() > 0.5"> Sorry </div> <div v-else> Not sorry </div> </div> <script> new Vue({ el: '#app' }) </script>
v-else-if
v-else-if 在 2.1.0 新增,顾名思义,用作 v-if 的 else-if 块。可以链式的多次使用:
v-else 指令
判断 type 变量的值:
<div id="app"> <div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div> </div> <script> new Vue({ el: '#app', data: { type: 'C' } }) </script>
v-else 、v-else-if 必须跟在 v-if 或者 v-else-if之后。
v-show
我们也可以使用 v-show 指令来根据条件展示元素:
v-show 指令
Vue.js 实例
本章节为大家介绍几个 Vue.js 实例,通过实例练习来巩固学到的知识点。
导航菜单实例
导航菜单
创建一个简单的导航菜单:
<div id="main"> <!-- 激活的菜单样式为 active 类 --> <!-- 为了阻止链接在点击时跳转,我们使用了 "prevent" 修饰符 (preventDefault 的简称)。 --> <nav v-bind:class="active" v-on:click.prevent> <!-- 当菜单上的链接被点击时,我们调用了 makeActive 方法, 该方法在 Vue 实例中创建。 --> <a href="#" class="home" v-on:click="makeActive('home')">Home</a> <a href="#" class="projects" v-on:click="makeActive('projects')">Projects</a> <a href="#" class="services" v-on:click="makeActive('services')">Services</a> <a href="#" class="contact" v-on:click="makeActive('contact')">Contact</a> </nav> <!-- 以下 "active" 变量会根据当前选中的值来自动变换 --> <p>您选择了 <b>{{active}} 菜单</b></p> </div> <script> // 创建一个新的 Vue 实例 var demo = new Vue({ // DOM 元素,挂载视图模型 el: '#main', // 定义属性,并设置初始值 data: { active: 'home' }, // 点击菜单使用的函数 methods: { makeActive: function(item){ // 模型改变,视图会自动更新 this.active = item; } } }); </script>
编辑文本实例
文本编辑
点击指定文本编辑内容:
<!-- v-cloak 隐藏未编译的变量,直到 Vue 实例准备就绪。 --> <!-- 元素点击后 hideTooltp() 方法被调用 --> <div id="main" v-cloak v-on:click="hideTooltip"> <!-- 这是一个提示框 v-on:click.stop 是一个点击事件处理器,stop 修饰符用于阻止事件传递 v-if 用来判断 show_tooltip 为 true 时才显示 --> <div class="tooltip" v-on:click.stop v-if="show_tooltip"> <!-- v-model 绑定了文本域的内容 在文本域内容改变时,对应的变量也会实时改变 --> <input type="text" v-model="text_content" /> </div> <!-- 点击后调用 "toggleTooltip" 方法并阻止事件传递 --> <!-- "text_content" 变量根据文本域内容的变化而变化 --> <p v-on:click.stop="toggleTooltip">{{text_content}}</p> </div> <script> var demo = new Vue({ el: '#main', data: { show_tooltip: false, text_content: '点我,并编辑内容。' }, methods: { hideTooltip: function(){ // 在模型改变时,视图也会自动更新 this.show_tooltip = false; }, toggleTooltip: function(){ this.show_tooltip = !this.show_tooltip; } } }) </script>
订单列
表实例
订单列表
创建一个订单列表,并计算总价:
<form id="main" v-cloak> <h1>Services</h1> <ul> <!-- 循环输出 services 数组, 设置选项点击后的样式 --> <li v-for="service in services" v-on:click="toggleActive(service)" v-bind:class="{ 'active': service.active}"> <!-- 显示订单中的服务名,价格 Vue.js 定义了货币过滤器,用于格式化价格 --> {{service.name}} <span>{{service.price | currency}}</span> </li> </ul> <div class="total"> <!-- 计算所有服务的价格,并格式化货币 --> Total: <span>{{total() | currency}}</span> </div> </form> <script> // 自定义过滤器 "currency" Vue.filter('currency', function (value) { return '$' + value.toFixed(2); }); var demo = new Vue({ el: '#main', data: { // 定义模型属性 // 视图将循环输出数组的数据 services: [ { name: 'Web Development', price: 300, active:true },{ name: 'Design', price: 400, active:false },{ name: 'Integration', price: 250, active:false },{ name: 'Training', price: 220, active:false } ] }, methods: { toggleActive: function(s){ s.active = !s.active; }, total: function(){ var total = 0; this.services.forEach(function(s){ if (s.active){ total+= s.price; } }); return total; } } }); </script>
搜索页面实例
搜索页面
在输入框输入搜索内容,列表显示配置的列表:
<form id="main" v-cloak> <div class="bar"> <!-- searchString 模型与文本域创建绑定 --> <input type="text" v-model="searchString" placeholder="输入搜索内容" /> </div> <ul> <!-- 循环输出数据 --> <li v-for="article in filteredArticles"> <a v-bind:href="article.url"><img v-bind:src="article.image" /></a> <p>{{article.title}}</p> </li> </ul> </form> <script> var demo = new Vue({ el: '#main', data: { searchString: "", // 数据模型,实际环境你可以根据 Ajax 来获取 articles: [ { "title": "What You Need To Know About CSS Variables", "url": "https://www.kxdang.com/topic//css/css-tutorial.html", "image": "https://static.kxdang.com/images/icon/css.png" }, { "title": "Freebie: 4 Great Looking Pricing Tables", "url": "https://www.kxdang.com/topic//html/html-tutorial.html", "image": "https://static.kxdang.com/images/icon/html.png" }, { "title": "20 Interesting JavaScript and CSS Libraries for February 2016", "url": "https://www.kxdang.com/topic//css3/css3-tutorial.html", "image": "https://static.kxdang.com/images/icon/css3.png" }, { "title": "Quick Tip: The Easiest Way To Make Responsive Headers", "url": "https://www.kxdang.com/topic//css3/css3-tutorial.html", "image": "https://static.kxdang.com/images/icon/css3.png" }, { "title": "Learn SQL In 20 Minutes", "url": "https://www.kxdang.com/topic//sql/sql-tutorial.html", "image": "https://static.kxdang.com/images/icon/sql.png" }, { "title": "Creating Your First Desktop App With HTML, JS and Electron", "url": "https://www.kxdang.com/topic//js/js-tutorial.html", "image": "https://static.kxdang.com/images/icon/html.png" } ] }, computed: { // 计算属性,匹配搜索 filteredArticles: function () { var articles_array = this.articles, searchString = this.searchString; if(!searchString){ return articles_array; } searchString = searchString.trim().toLowerCase(); articles_array = articles_array.filter(function(item){ if(item.title.toLowerCase().indexOf(searchString) !== -1){ return item; } }) // 返回过滤后的数据 return articles_array;; } } }); </script>
切换不同布局实例
切换不同布局
点击右上角的按钮来切换不同页面布局:
<form id="main" v-cloak> <div class="bar"> <!-- 两个按钮用于切换不同的列表布局 --> <a class="list-icon" v-bind:class="{ 'active': layout == 'list'}" v-on:click="layout = 'list'"></a> <a class="grid-icon" v-bind:class="{ 'active': layout == 'grid'}" v-on:click="layout = 'grid'"></a> </div> <!-- 我们设置了两套布局页面。使用哪套依赖于 "layout" 绑定 --> <ul v-if="layout == 'grid'" class="grid"> <!-- 使用大图,没有文本 --> <li v-for="a in articles"> <a v-bind:href="a.url" target="_blank" rel="noopener noreferrer"><img v-bind:src="a.image.large" /></a> </li> </ul> <ul v-if="layout == 'list'" class="list"> <!-- 使用小图及标题 --> <li v-for="a in articles"> <a v-bind:href="a.url" target="_blank" rel="noopener noreferrer"><img v-bind:src="a.image.small" /></a> <p>{{a.title}}</p> </li> </ul> </form> <script> var demo = new Vue({ el: '#main', data: { // 视图模型,可能的值是 "grid" 或 "list"。 layout: 'grid', articles: [{ "title": "HTML 教程", "url": "https://www.kxdang.com/topic//html/html-tutorial.html", "image": { "large": "https://static.kxdang.com/images/mix/htmlbig.png", "small": "https://static.kxdang.com/images/icon/html.png" } }, { "title": "CSS 教程", "url": "https://www.kxdang.com/topic//css/css-tutorial.html", "image": { "large": "https://static.kxdang.com/images/mix/cssbig.png", "small": "https://static.kxdang.com/images/icon/css.png" } }, { "title": "JS 教程", "url": "https://www.kxdang.com/topic//js/js-tutorial.html", "image": { "large": "https://static.kxdang.com/images/mix/jsbig.jpeg", "small": "https://static.kxdang.com/images/icon/js.png" } }, { "title": "SQL 教程", "url": "https://www.kxdang.com/topic//sql/sql-tutorial.html", "image": { "large": "https://static.kxdang.com/images/mix/sqlbig.png", "small": "https://static.kxdang.com/images/icon/sql.png" } }, { "title": "Ajax 教程", "url": "https://www.kxdang.com/topic//ajax/ajax-tutorial.html", "image": { "large": "https://static.kxdang.com/images/mix/ajaxbig.png", "small": "https://static.kxdang.com/images/icon/ajax.png" } }, { "title": "Python 教程", "url": "https://www.kxdang.com/topic//pyhton/pyhton-tutorial.html", "image": { "large": "https://static.kxdang.com/images/mix/pythonbig.png", "small": "https://static.kxdang.com/images/icon/python.png" } }] } }); </script>
总结
Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!