在 Vue全家桶之Vue基础(1) 一文中我们已经学习过 对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 文本: 演示效果如下: 演示效果如下: 单个复选框,绑定到布尔值: 演示效果如下: 演示效果如下: 演示效果如下: 选择框单选时: 演示效果如下: 多选时(绑定到一个数组): 演示效果如下: 演示效果如下: 如以下例子所示: 这通常很有用,因为即使在 为何需要自定义指令? 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 自定义指令用法: 接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。 指令钩子函数会被传入以下参数: 除了 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如: 在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 演示效果如下: 你可以打开浏览器的控制台,自行修改例子中的 你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果: 我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 这也同样意味着下面的计算属性将不再更新,因为 相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。 演示效果如下: 好得多了,不是吗?虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 演示效果如下: 演示效果如下: 所谓的 你可以在一个组件的选项中定义本地的过滤器: 或者在创建 注意: 下面这个例子用到了 在这个例子中, 这里, 这里, 音乐播放器小案例.mp4 在 通过这种方法,可以把指定的音频数据直接嵌入在网页上,其中 目录
1. Vue常用特性
1.1 表单输入绑定
v-model
的用法。我们可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建 双向数据绑定
。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。v-model
会忽略所有表单元素的 value
、checked
、selected
attribute 的初始值而总是将 Vue
实例的数据作为数据来源。你应该通过 JavaScript
在组件的 data
选项中声明初始值。如下图所示:
v-model
在内部为不同的输入元素使用不同的 property
并抛出不同的事件:
value
property 和 input
事件checked
property 和 change
事件value
作为 prop 并将 change
作为事件v-model
不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input
事件。
在后续关于表单输入绑定操作中用到的 js
代码如下:<script src="js/vue.js"></script> <script> let vm = new Vue({ el: "#app", data: { message: "", //文本以及多行文本 checked: false, //单个复选框绑定到bool值 checkedNames: [], //多个复选框绑定到同一个数组 picked: "", //单选按钮 selected: "", //选择框单选 selected2: [], //选择框多选 selected3: "A", //动态渲染选项 options: [{ text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' }] } }); </script>
<!-- placeholder:向用户显示描述性说明或者提示信息 --> <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
多行文本:<span>Multiline message is:</span> <!-- white-space: pre-line: 合并空白符序列,但是保留换行符。 --> <p style="white-space: pre-line;">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
在文本区域插值 <textarea>{{text}}</textarea>)
并不会生效,应用 v-model
来代替。<input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label>
多个复选框,绑定到同一个数组:<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span>
单选按钮:<input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span>
补充:
<label>
标记用于在表单元素中定义标签,这些标签可以对其他一些表单控件元素(如单行文本框、密码框等)进行说明。<label>
标记可以指定 id/style/class
等核心属性,也可以指定 onclick
等事件属性。除此之外,<label>
标记还有一个 for
属性,该属性指定 <label>
标记与哪个表单控件相关联。<label>
标记定义的标签只是输出普通的文本,但 <label>
标记生成的标签还有一个另外的作用,那就是当用户单击 <label>
生成的标签时,和该标签关联的表单控件元素就会 获得焦点
。也就是说,当用户选择
使用 for
属性,指定 <label>
标记的 for
属性值为所关联的表单控件的 id
属性值。
将普通文本、表单控件一起放在 <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span>
如果 v-model
表达式的初始值未能匹配任何选项,<select>
元素将被渲染为 未选中
状态。在 iOS
中,这会使用户无法选择第一个选项。因为这样的情况下,iOS
不会触发 change
事件。因此,更推荐像上面这样提供一个 值为空的禁用选项
。<!-- multiple: 表示列表/菜单内容可多选 --> <select v-model="selected2" multiple style="width: 50px;"> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected2 }}</span>
用 v-for
渲染的动态选项:<select v-model="selected3"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected3 }}</span>
修饰符:
在默认情况下,v-model
在每次 input
事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy
修饰符,从而转为在 change
事件_之后_进行同步:<!-- 在"change"时而非"input"时更新 --> <input v-model.lazy="msg">
演示效果如下:
如果想自动将用户的输入值转为数值类型,可以给 v-model
添加 number
修饰符:<input v-model.number="age" type="number">
type="number"
时,HTML
输入元素的值也总会返回字符串。如果这个值无法被 parseFloat()
解析,则会返回原始的值。如果要自动过滤用户输入的首尾空白字符,可以给 v-model
添加 trim
修饰符:<input v-model.trim="msg">
1.2 自定义指令
Vue2.0
中,代码复用和抽象的主要形式是 组件
。然而,有的情况下,你仍然需要对普通 DOM
元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:
当页面加载时,该元素将获得焦点 (注意:autofocus
在移动版 Safari
上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能://注册一个全局指令focus Vue.directive("focus", { //当被绑定的元素插入到DOM中时 inserted: function(el) { //聚焦元素 el.focus(); } })
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode
更新时调用,但是可能发生在其子 VNode
更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。VNode
及其子 VNode
全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
el
:指令所绑定的元素,可以用来直接操作 DOM。binding
:一个对象,包含以下 property:
name
:指令名,不包括 v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为 2
。oldValue
:指令绑定的前一个值,仅在 update
和 componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如 v-my-directive="1 + 1"
中,表达式为 "1 + 1"
。arg
:传给指令的参数,可选。例如 v-my-directive:foo
中,参数为 "foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为 { foo: true, bar: true }
。vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。oldVnode
:上一个虚拟节点,仅在 update
和 componentUpdated
钩子中可用。el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset
来进行。 下面通过一个例子来说明:
演示效果如下:
如果想注册局部指令,组件中也接受一个 directives
的选项:directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } }
1.3 计算属性
1.3.1 基本使用
<div id="example"> {{ message.split('').reverse().join('') }} </div>
message
的翻转字符串。当你想要在模板中多包含此处的翻转字符串时,就会更加难以处理。所以,对于任何复杂逻辑,你都应当使用 计算属性
。基础例子如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>计算属性</title> </head> <body> <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> </body> </html> <script src="js/vue.js"></script> <script> let vm = new Vue({ el: "#example", data: { message: "Hello" }, computed: { //计算属性的getter reversedMessage: function() { //this指向vm实例 return this.message.split("").reverse().join(""); } } }); </script>
这里我们声明了一个计算属性 reversedMessage
。我们提供的函数将用作 property vm.reversedMessage
的 getter 函数:console.log(vm.reversedMessage) // => 'olleH' vm.message = 'Goodbye' console.log(vm.reversedMessage) // => 'eybdooG'
vm
。vm.reversedMessage
的值始终取决于 vm.message
的值。如下图所示:
你可以像绑定普通 property 一样在模板中绑定计算属性。Vue
知道 vm.reversedMessage
依赖于 vm.message
,因此当 vm.message
发生改变时,所有依赖 vm.reversedMessage
的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter
函数是没有副作用 (side effect) 的,这使它更易于测试和理解。1.3.2 计算属性缓存 vs 方法
<p>Reversed message: "{{ reversedMessage() }}"</p>
js
代码如下:methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。Date.now()
不是响应式依赖:computed: { now: function () { return Date.now() } }
1.4 侦听属性及侦听器
1.4.1 基本使用
Vue
提供了一种更通用的方式来观察和响应 Vue
实例上的数据变动:侦听属性
。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS
。然而,通常更好的做法是使用 计算属性
命令式的 watch
回调。细想一下这个例子:html
核心代码如下:<body> <div id="app"> <div> <span>姓:</span> <span> <input type="text" v-model="xing"> </span> </div> <div> <span>名:</span> <span> <input type="text" v-model="ming"> </span> </div> <div>全名: {{xingming}}</div> </div> </body>
js
核心代码如下:<script src="js/vue.js"></script> <script> let vm = new Vue({ el: "#app", data: { xing: "Amo", ming: "Xiang", xingming: "Amo Xiang" }, //在这添加一个watch属性 watch: { //watch中的属性 一定是data中已经存在的数据 //这里的xing对应着data中的xing 当data中xing的值发生改变时 会自动触发watch xing: function(val) { this.xingming = val + " " + this.ming; }, //这里的ming对应着data中的ming 当data中ming的值发生改变时 会自动触发watch ming: function(val) { this.xingming = this.xing + " " + val; } } }); </script>
上面代码是命令式且重复的。将它与计算属性的版本进行比较:<script src="js/vue.js"></script> <script> let vm = new Vue({ el: "#app", data: { xing: "Amo", ming: "Xiang", }, computed: { xingming: function() { return this.xing + " " + this.ming; } } }); </script>
watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时 执行异步
或 开销较大
的操作时,这个方式是最有用的。html
结构如下:<body> <div id="app"> <span>用户名: </span> <span> <!-- 使用修饰符将input事件改为change事件 --> <input type="text" v-model.lazy="uname"> </span> <span>{{tip}}</span> </div> </body>
js
代码如下:<script src="js/vue.js"></script> <script> let vm = new Vue({ el: "#app", data: { uname: "", tip: "" }, methods: { checkName: function(uname) { // 调用接口,但是可以使用定时任务的方式模拟接口调用 // 因为定时器内部的this是指向window的 所以这里要使用一个变量来存储this指向的vm实例 let that = this; setTimeout(function() { if (uname == "admin") { that.tip = "用户名已经存在,请更改...."; } else { that.tip = "用户名可以使用"; } }, 2000); } }, watch: { uname: function(val) { this.checkName(val); //调用函数校验用户名的合法性 this.tip = "正在检验用户名是否可用...." } } }); </script>
当需要监听一个对象的改变时,普通的 watch
方法无法监听到对象内部属性的改变,只有 data
中的数据才能够监听到变化,此时就需要 deep
属性对对象进行深度监听 请看下面这个例子:html
结构如下:<body> <div id="app"> <input type="text" v-model="personInfo.name"> <h3>{{personInfo.name}}</h3> </div> </body>
js
代码如下:<script src="js/vue.js"></script> <script> let vm = new Vue({ el: "#app", data: { personInfo: { name: "Amo", age: 18, isBoy: true } }, watch: { personInfo: function(value) { console.log("监听成功"); } } }); </script>
从上面的结果我们可以看出,是没有监听成功的,我们只需要将上面 js
代码中 watch
部分更改一下即可,如下:
演示效果如下:
1.5 过滤器
过滤器
,大家可以这样理解类似于我们家里的 净水器
,净水器
是按对 水
的使用要求对水质
进行深度过滤、净化处理,Vue
中则是按照对数据
的使用要求进行过滤处理,其本质就是对数据的处理,而在 Vue
中数据都是绑定到 Vue
实例的 data
属性中,即过滤器处理 data
属性中的数据然后将其返回。1.5.1 基本使用
Vue.js
允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值 和 v-bind
表达式 (后者从 2.1.0+ 开始支持)。过滤器
应该被添加在 JavaScript
表达式的尾部,由 管道
符号指示:<!-- 在双花括号中 --> {{ message | capitalize }} <!-- 在 `v-bind` 中 --> <div v-bind:id="rawId | formatId"></div>
filters: { capitalize: function (value) { if (!value) return '' value = value.toString() //return必须写,charAt(0):获取字符串中第一个字符 //toUpperCase():将小写字母转换为大写字母 //slice(1): 表示字符串从索引1开始截取到最后的子串 return value.charAt(0).toUpperCase() + value.slice(1) } }
Vue
实例之前全局定义过滤器:Vue.filter('capitalize', function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) }) new Vue({ // ... })
filter
,没有 s
的。而局部过滤器是filters
,是有 s
的capitalize
过滤器:
通过上述 gif
演示的效果图,大家可以看出 过滤器
不改变真正的 data
,而只是改变渲染的结果,并返回过滤后的版本。核心代码如下:
过滤器函数总接收表达式的值(之前的操作链的结果)作为第一个参数。在上述例子中,capitalize
过滤器函数将会收到 message
的值作为第一个参数。过滤器可以串联:{{ message | filterA | filterB }}
filterA
被定义为接收单个参数的过滤器函数,表达式 message
的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB
,将 filterA
的结果传递到 filterB
中。过滤器是 JavaScript
函数,因此可以接收参数:{{ message | filterA('arg1', arg2) }}
filterA
被定义为接收三个参数的过滤器函数。其中 message
的值作为第一个参数,普通字符串 'arg1'
作为第二个参数,表达式 arg2
的值作为第三个参数。格式化日期例子,核心代码如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="app"> <div>{{date | format('yyyy-MM-dd hh:mm:ss')}}</div> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> Vue.filter('format', function(value, arg) { function dateFormat(date, format) { if (typeof date === "string") { var mts = date.match(/(/Date((d+))/)/); if (mts && mts.length >= 3) { date = parseInt(mts[2]); } } date = new Date(date); if (!date || date.toUTCString() == "Invalid Date") { return ""; } var map = { "M": date.getMonth() + 1, //月份 "d": date.getDate(), //日 "h": date.getHours(), //小时 "m": date.getMinutes(), //分 "s": date.getSeconds(), //秒 "q": Math.floor((date.getMonth() + 3) / 3), //季度 "S": date.getMilliseconds() //毫秒 }; format = format.replace(/([yMdhmsqS])+/g, function(all, t) { var v = map[t]; if (v !== undefined) { if (all.length > 1) { v = '0' + v; v = v.substr(v.length - 2); } return v; } else if (t === 'y') { return (date.getFullYear() + '').substr(4 - all.length); } return all; }); return format; } return dateFormat(value, arg); }) var vm = new Vue({ el: '#app', data: { date: new Date() } }); </script> </body> </html>
format
被定义为接收二个参数的过滤器函数。其中 date
的值作为第一个参数,普通字符串 'yyyy-MM-dd hh:mm:ss'
作为第二个参数。程序结果为:
1.6 音乐播放器
1.6.1 功能演示
1.6.2 前置知识
HTML5
中,新增了两个元素——video
元素与 audio
元素。video
元素专门用来播放网络上的视频或电影,而 audio
元素专门用来播放网络上的音频数据。使用这两个元素,就不再需要使用其他任何插件了,只要使用支持 HTML5
的浏览器就可以了。这两个元素的使用方法都很简单,本文使用到的是audio
,所以这里 audio
元素为例,只要把播放音频的 URL
给指定元素的 src
属性就可以了,audio
元素使用方法如下所示。<audio src="./Music/麦小兜-下山.flac">您的浏览器不支持audio元素!</audio>
您的浏览器不支持audio元素!
为在不支持 audio
元素的浏览器中所显示的替代文字。本案例用到的属性及事件介绍如下:
src
属性用于指定媒体数据的 URL
地址。autoplay
属性用于指定媒体是否在页面加载后自动播放。使用方法如下:
<audio src="./Music/汪苏泷-小星星.flac" autoplay></audio>
controls
属性指定是否为视频或音频添加浏览器自带的播放用的控制条。控制条中具有播放、暂停等按钮。使用方法如下:
<audio src="./Music/汪苏泷-小星星.flac" controls></audio>
ended
事件:播放由于媒介结束而停止1.6.3 示例代码
html
结构如下:<body> <div id="app"> <audio :src="currentSrc" controls autoplay @ended="handleEnded"></audio> <ul> <li :class="{active:index===currentIndex}" v-for="(item,index) in musicData" :key="item.id" @click="handle(item,index)"> <h2>{{item.id}}--歌名:{{item.name}}</h2> <p>{{item.author}}</p> </li> </ul> <button @click="handlePre">上一首</button> <button @click="handleNext">下一首</button> </div> </body>
js
代码如下:<script> const musicData = [{ id: 1, name: '下山', author: '麦小兜', songSrc: './Music/麦小兜-下山.flac' }, { id: 2, name: 'Please Dont Go', author: 'Joel Adams', songSrc: './Music/Joel Adams - Please Dont Go.mp3' }, { id: 3, name: '小星星', author: '汪苏泷', songSrc: './Music/汪苏泷-小星星.flac' }, { id: 4, name: '芒种', author: '赵方婧', songSrc: './Music/音阙诗听,赵方婧-芒种.flac' }]; let vm = new Vue({ el: "#app", data: { musicData, currentSrc: "./Music/麦小兜-下山.flac", currentIndex: 0 }, methods: { handle(item, index) { this.currentSrc = item.songSrc; this.currentIndex = index; }, handleEnded() { this.handleNext(); }, handlePre() { this.currentIndex--; if (this.currentIndex < 0) { this.currentIndex = this.musicData.length - 1; } this.currentSrc = this.musicData[this.currentIndex].songSrc; }, handleNext() { this.currentIndex++; if (this.currentIndex === this.musicData.length) { this.currentIndex = 0; } this.currentSrc = this.musicData[this.currentIndex].songSrc; } } }); </script>
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算