插值
文本插值
文本插值
文本插值中用得最多的就是用双大括号的形式
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 会与实例中的【data】中的属性绑定在一起,并且数据实现同步-->
<h1>{{message}}</h1>
</div>
<script>
// Vue所做的工作也就是把数据填充把页面的标签里面。
var vm = new Vue({
el: "#app",
// data模型数据,值是一个对象。
data: {
message: "I LOVE YOU"
}
})
</script>
</body></html>
上面代码中当 data 中的值更新之后我们不需要操作 html,页面中会自动更新数据。 我们也可以让数据只绑定一次,在以后更新 data 中的属性时不再更新页面数据
使用 v-once 指令插值
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-once只编译一次。显式内容之后不再具有响应式功能。 -->
<!-- v-once的应用场景,如果显式的信息后续不需要再修改,可以使用v-once指令,可以可以提高性能,因为Vue就不需要去监听它的变化了。 -->
<h1 v-once>{{message}}</h1>
</div>
<script>
// Vue所做的工作也就是把数据填充把页面的标签里面。
var vm = new Vue({
el: "#app",
// data模型数据,值是一个对象。
data: {
message: "I LOVE YOU"
}
})
</script>
</body>
</html>
HTML 插值
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你 需要使用 v-htm
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译,在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击 -->
<h1 v-html="msg"></h1>
</div>
</body>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: "<span style='color:blue'>BLUE</span>"//可以使用v-html标签展示html代码。
}
})
</script>
</html>
属性插值
在开发的时候,有时候我们的属性不是写死的,有可能是根据我们的一些数据动态地决 定的,比如图片标签()的 src 属性,我们可能从后端请求了一个包含图片地址的数 组,需要将地址动态的绑定到 src 上面,这时就不能简单的将 src 写死。还有一个例子就是 a 标签的 href 属性。这时可以使用 v-bind:指令
v-bind:
v-bind 动态绑定属性 href
<!DOCTYPE html>
<html xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<img v-bind:src="imgUrl" alt=""/>
<a :href="searchUrl">百度一下</a>
</div>
</body>
<script>
var vm = new Vue({
el: "#app",
data: {
imgUrl:'images/1.jpg',
searchUrl:'http://www.baidu.com'
}
})
</script>
</html>
服务器请求过来的数据,我们一般都会在 data 那里做一下中转,做完中转过后再把需 要的变量绑定到对应的属性上面。
v-bind 除了在开发中用在有特殊意义的属性外(src, href 等),也可以绑定其他一些 属性,如 Class 与 Style 绑定
v-bind 动态绑定属性 class
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" >
<head>
<meta charset="UTF-8">
<title>v-bind动态绑定属性class</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p :class="{fontCol:isName,setBack:!isAge}" class="weight">{{name}}</p>
<i :class="addClass">{{name}}真好看!</i>
</div>
<script>
var vm = new Vue({
el:"#app",
// 条件比较少
data:{
isName:true,
isAge:false,
name:"功守道"
},
//当v-bind:class的表达式过长或者逻辑复杂(一般当条件多于两个的时候),可以考虑采用计算属性,返回一个对象
computed:{
addClass:function(){
return {
checked:this.isName&&!this.isAge
}
}
}
})
</script>
</body>
</html>
v-bind 动态绑定属性 style
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" >
<head>
<meta charset="UTF-8">
<title>v-bind动态绑定属性style</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div :style="{'color': color,'fontSize':fontSize + 'px'}">修饰文本</div>
</div>
<script>
var vm= new Vue({
el: "#app",
data: {
color: 'red',
fontSize: 24
}
})
</script>
</body>
</html>
<优化标签做法>
大多情况下,标签中直接写一长串的样式不便于阅读和维护,所以一般写在 dada 或 computed 里,代码如下:
<div id="app">
<div :style="{'color': color,'fontSize':fontSize + 'px'}">修饰文本</div>
</div>
<script>
var vm= new Vue({1
el: "#app",
data: {
styles:{
color: 'red',
fontSize: 24
}
}
})
</script>
数组语法
应用多个样式对象时,可以使用数组语法。v-bind 绑定多个 style 属性
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" >
<head>
<meta charset="UTF-8">
<title>v-bind动态绑定属性style</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div :style="[styleA,styleB]">文本</div>
</div>
<script>
var vm=new Vue({
el: "#app",
data: {
styleA:{
color: 'red',
fontSize: 24 + 'px'
},
styleB: {
width: 100 + 'px',
border: 1 + 'px ' + 'black ' + 'solid'
}
}
})
</script>
</body>
</html>
插值 Javascript 表达式
在我们的模板中,我们一直都只绑定简单的 property 键值。
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
实际上,对 于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持.
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id">
</div>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就 是,每个绑定都只能包含单个表达式,所以下面的表达式都不会生效,代码如下:
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" >
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ number + 1 }}</p>
<hr>
<p>{{msg + '~~~~~'}}</p>
<hr>
<p>{{flag ? '条件为真' : '条件为假'}}</p>
<hr>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'Hello beixi!',
flag:true,
number:2
}
})
</script>
</body>
</html>
指令
如 【v-bind:】和【v-html】
指令就是值这些带有 v- 前缀的特殊属性。
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。如 v-bind 指令可以用 于响应式地更新 HTML attribute,代码如下:
<a v-bind:href="url">...</a>
在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。
动态参数
从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数,响应式 使得 vue 更加灵活多变,其动态参数也是有其含义的,代码如下:
<a v-bind:[attributeName] = 'url'>...</a>
同样的,当 eventName 的值为‘focus’时,v-on:[eventName]将等价于 v-on:focus。
当然动态参数的值也是有约束的,动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移出绑定。任何其他非字符串类型的值都将会触 发一个警告。
修饰符
修饰符(Modifiers)是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊 方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调 event.preventDefault(), 代码如下:
<form v-on:submit.prevent="onSubmit">...</form>
过滤器
过滤器分全局过滤器和局部过滤器
定义过滤器
全局过滤器
Vue.filter('过滤器名称', function (value1[,value2,...] ) {
//逻辑代码
})
局部过滤器
new Vue({
filters: {
'过滤器名称': function (value1[,value2,...] ) {
// 逻辑代码
}
}
})
过滤器使用的地方
Vue.js 允许自定义过滤器,可被用于一些常见的文本格式化。
过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示,格式代码如下:
<!-- 在双花括号中 -->
<div>{{数据属性名称 | 过滤器名称}}</div>
<div>{{数据属性名称 | 过滤器名称(参数值)}}</div>
<!-- 在 v-bind 中 -->
<div v-bind:id="数据属性名称 | 过滤器名称"></div>
<div v-bind:id="数据属性名称 | 过滤器名称(参数值)"></div>
案例
(局部) 在价格前面加上人民币符号
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" >
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--文本后边需要添加管道符号( | )作为分隔,管道符 | 后边是文本的处理函数,
处理函数的第一个参数是:管道符前边的——文本内容,如果处理函数上边传递参数,则从第二个参数依次往后是传递的参数。-->
<p>电脑价格:{{price | addPriceIcon}}</p>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
price:200
},
filters:{
//处理函数
addPriceIcon(value){
console.log(value)//200
return '¥' + value;
}
}
})
</script>
</body>
</html>
全局
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" >
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>{{viewContent | addNamePrefix}}</h3>
</div>
<script>
/*addNamePrefix是过滤器的名字,也是管道符后边的处理函数;value是参数*/
Vue.filter("addNamePrefix",(value)=>{
return "my name is" + value
})
var vm = new Vue({
el:"#app",
data:{
viewContent:"贝西"
}
})
</script>
</body>
</html>
实例及选项
Vue 是通过构造函数来实例化一个 Vue 对象:var vm=new Vue({})。
在实例化时,我们 会传入一些选项对象,包含数据选项、属性选项、方法选项、生命周期钩子等常用选项。
数据选项
一般地,当模板内容较简单时,使用 data 选项配合表达式即可,涉及到复杂逻辑时, 则需要用到 methods、computed、watch 等方法。 data 是 Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 属性能响应数据变化,代码如下:
<!--部分代码省略-->
<div id="app">
{{ message }}
</div>
<script>
var values = {message: 'Hello Vue!'}
var vm = new Vue({
el: '#app',
data: values
})
console.log(vm);
</script>
Vue 实例创建之后,在控制台输入 vm.$data 访问原始数据对象
在 script 标签中添加一些信输出息查看控制台观察 Vue 实例是否代理了 data对象的所有 属性,代码如下:
<script>
console.log(vm.$data === values);//true
console.log(vm.message);//'Hello Vue!'
console.log(vm.$data.message);//'Hello Vue!'
</script>
被代理的属性是响应的,也就是说值的任何改变都是触发视图的重新渲染。设置属性也 会影响到原始数据,反之亦然。
但是,以_或data._property 的方式访问这些属性,代码如下:
<script>
var values = {
message: 'Hello Vue!',
_name: 'beixi'
}
var vm = new Vue({
el: '#app',
data: values
})
console.log(vm._name); //undefined console.log(vm.$data._name);//'beixi'
</script>
属性选项
Vue 为组件开发提供了属性(props)选项,我们可以使用它为组件注册动态属性,来 处理业务之间的差异性,使代码可以复用相似的应用场景。
props 选项可以是数组或者对象类型,用于接收从父组件传递过来的参数,并允许为其 赋默认值、类型检查和跪着校验等
props 选项的使用
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
<div id="app">
<message content='Hello World'></message>
</div>
</body>
<!-- 测试组件 -->
<script type="text/javascript">
var Message = Vue.extend({
props : ['content'],
data : function(){return {
a: 'it worked'
}},
template : '<h1>{{content}}</h1><h1>{{a}}</h1>'
})
Vue.component('message', Message)
var vm = new Vue({
el : '#app',
})
</script>
</html>
methods 对象来定义方法
我们可以通过选项属性 methods 对象来定义方法,并且使用 v-on 指令来监听 DOM 事 件,
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
<div id="app">
<button v-on:click="test">点我</button>
</div>
</body>
<!-- 测试组件 -->
<script type="text/javascript">
var vm = new Vue({
el : '#app',
methods:{
/*定义了一个test函数*/
test: function () {
console.log(new Date().toLocaleTimeString());
}
}
})
</script>
</html>
计算属性
在项目开发中,我们展示的数据往往需要处理的。除了在模板中绑定表达式或利用过滤器外,
Vue 还提供了计算属性方法,计算属性是当其依赖属性的值发生变化时,这个属性的值会自动更新,与之相关的 DOM 部分也会同步自动更新。
从而减轻了我们在模板中的业务负担,保证模板的结构清晰和可维护性。
有时候我们可能需要在{{}}里进行一些计算在展示出来数据
v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:
v-bind绑定一个value属性
v-on指令给当前元素绑定input事件
案例
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table border="1">
<thead>
<th>学科</th>
<th>分数</th>
</thead>
<tbody>
<tr>
<td>数学</td>
<td><input type="text" v-model="Math"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model="English"></td>
</tr>
<tr>
<td>语文</td>
<td><input type="text" v-model="Chinese"></td>
</tr>
<tr>
<td>总分</td>
<td>{{Math+ English + Chinese}}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{(Math + English + Chinese)/3}}</td>
</tr>
</tbody>
</table>
<script>
var vm = new Vue({
el: '#app',
data: {
Math: 69,
English: 77,
Chinese: 88
}
})
</script>
</div>
</body>
</html>
计算属性是 Vue 实例中的一个 配置选项:computed,通常都是计算相关的函数,返回最后计算出来的值。也就是我们可以 把这些计算的过程写到一个计算属性中去,然后让它动态的计算
案例优化
computed
基础用法:
1.计算属性的getter函数
2.计算属性的setter函数
3.计算属性的cache缓存属性
常见问题
1.计算属性getter不执行的场景
2.在v-for中使用计算属性,起到类似”过滤器的作用”
3.watch与computed的set函数的比较
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<body>
<div id="app">
<table border="1">
<thead>
<th>学科</th>
<th>成绩</th>
</thead>
<tbody>
<tr>
<td>数学</td>
<td><input type="text" v-model.number="Math"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model.number="English"></td>
</tr>
<tr>
<td>语文</td>
<td><input type="text" v-model.number="Chinese"></td>
</tr>
<tr>
<td>总分</td>
<td>{{sum}}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{average}}</td>
</tr>
</tbody>
</table>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
Math:66,
English: 77,
Chinese:88
},
computed:{
<!-- 一个计算属性的getter -->
sum:function(){
<!-- this指向vm实例 -->
return this.Math+ this.English+this.Chinese;
},
average:function(){
return Math.round(this.sum/3);
}
}
});
</script>
</body>
</html>
computed与mothods
计算属性一般是通过其他的数据计算出一个新数据,而且它有一个好处就是能把新的数 据缓存下来了,当其他的依赖数据没有发生改变,它调用的是缓存的数据,这就极大的提高 了我们程序的性能和数据提取的速度。而如果写在 methods 里,数据不会缓存下来,所以每 次都会重新计算。这也是为什么这里我们没用 methods 的原因
计算属性和方法的比较
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head><body>
<div id="app">
<p>原始字符串: "{{ message }}"</p>
<p>计算属性反向字符串: "{{ reversedMessage1 }}"</p>
<p>methods方法反向字符串: "{{ reversedMessage2() }}"</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'beixi'
},
computed:{
reversedMessage1: function () {
return this.message.split('').reverse().join('')
}
},
methods: {
reversedMessage2: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
读取和设置值
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<script>
var vm = new Vue({
data: { a: 1 },
computed: {
// 改函数只能读取数据,vm.aDouble即可读取数据
aDouble: function () {
return this.a * 2
},
// 读取和设置数据
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
console.log(vm.aPlus);//2
vm.aPlus = 3;
console.log(vm.a);//2
console.log(vm.aDouble);//4
</script>
</body>
</html>
表单控件
基础用法
你可以用 v-model 指令在表单 、 ) 并不会生效,应用 v-model 来代 替。
<div id="example-textarea" class="demo">
<span>Multiline message is:</span>
<p style="white-space: pre">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
</div>
<script>
new Vue({
el: '#example-textarea',
data: {
message: ''
}
})
</script>
复选框
单个复选框,绑定到布尔值,代码如下
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<body>
<div id="example-checkbox" class="demo">
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox"> {{checked}} </label>
</div>
<script>
new Vue({
el: '#example-checkbox',
data: {
checked: true
}
})
</script>
</body>
</html>
多个复选框,绑定到同一个数组
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example-checkboxs" class="demo">
<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>
</div>
<script>
new Vue({
el: '#example-checkboxs',
data: {
checkedNames: []
}
})
</script>
</body>
</html>
单选按钮
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example-radio">
<input type="radio" id="runoob" value="Runoob" v-model="picked">
<label for="runoob">Runoob</label>
<br>
<input type="radio" id="google" value="Google" v-model="picked">
<label for="google">Google</label>
<br>
<span>选中值为: {{ picked }}</span>
</div>
<script>
new Vue({
el: '#example-radio',
data: {
picked: 'Runoob'
}
})
</script>
</body>
</html>
选择列表:下拉列表的双向数据绑定
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example-selected">
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '#example-selected',
data: {
selected: ''
}
})
</script>
</body>
</html>
多选列表(绑定到一个数组)
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example-selected" class="demo">
<select v-model="selected" multiple style="width: 50px">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
el: '#example-selected',
data: {
selected: []
}
})
</script>
</body>
</html>
动态选项,用 v-for 渲染
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example-selected" class="demo">
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{option.text}}
</option>
</select>
<span>Selected: {{selected}}</span>
</div>
<script>
new Vue({
el: '#example-selected',
data: {
selected: 'A',
options: [{
text: 'One',
value: 'A'
},
{
text: 'Two',
value: 'B'
},
{
text: 'Three',
value: 'C'
}
]
}
})
</script>
</body>
</html>
绑定 value
对于单选按钮,勾选框及选择列表选项, v-model 绑定的 value 通常是静态字符串
<div id="app" >
<!-- 当选中时,picked 为字符串 "a" -->
<input type="radio" v-model="picked" value="a">
<!-- 当选中时,toggle 为 true 或 false -->
<input type="checkbox" v-model="toggle">
<!-- 当选中时,selected 为字符串 "abc" -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
</div>
<script>
var vm=new Vue({
el: '#app',
data: {
picked:'',
toggle:'',
selected:''
}
})
</script>
复选框2
有时我们想绑定 value 到 Vue 实例的一个动态属性上,这时可以用 v-bind 实现,并且这个属性的值可以不是字符串,代码如下:
<div id="app">
<input type="checkbox" v-model="toggle" v-bind : true-value="a" v-bind : false-value="b">
{ { toggle } }
</div>
<script>
var vm=new vue ( {
el: ' #app ' ,
data : {
toggle : ' ',
a : 'a ' ,
b : 'b'
}
})
</script>
单选按钮2
<input type="radio" v-model="pick" v-bind:value="a">
当选中时在页面控制台输 vm.pick 的值和 vm.a 的值相等。
选列表设置
<select v-model="selected">
<!--内联对象字面量-->
<option v-bind: value=" { number: 123 } ">123</option>
</select>
当选中时在页面控制台输入 typeof vm.selected ,输出’object’;输入 vm.selected.number , 输出值为 123。
修饰符
.lazy
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了 上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件之后进行同 步,代码如下:
<input v-model.lazy="msg"> <!-- 在“change”时而非“input”时更新 -->
.number
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符,代码如下:
<input v-model.number="age" type="number">
这通常很有用,因为即使在 type=”number” 时,HTML 输入元素的值也总会返回字符 串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。
.trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符,代码如 下:
<input v-model.trim="msg">
生命周期钩子的函数
生命周期图
在 beforeCreate 和 created 钩子函数之间的生命周期。
在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到在 created 的时候 数据已经和 data 属性进行绑定<br />
(放在 data 中的属性当值发生改变的同时,视图也会改变)。
注意:此时还是没有 el 选项。
created 钩子函数和 beforeMount 间的生命周期
在这一阶段发生的事情还是比较多的。首先会判断对象是否有 el 选项。如果有的话就 继续向下编译,如果没有 el 选项,则停止编译, 也就意味着停止了生命周期,直到在该 vue 实例上调用 vm.$mount(el)。<br />
此时注释掉代码中:el: '#app',然后可以看到运行到 created 时就停止了
如果我们在后面继续调用 vm.$mount(el),可以发现代码继续向下执行了
template 参数选项的有无对生命周期的影响
如果 vue 实例对象中有 template 参数选项,则将其作为模板编译成 render 函数。
如果没有 template 选项,则将外部 HTML 作为模板编译。
可以看到 template 中的模板优先级要高于 outer HTML 的优先级。
【例 3-19】 Vue 对象中增加了 template 选项
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue生命周期学习</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
</head>
<body>
<div id="app">
<!--html中修改的-->
<h1>{{message + '这是在outer HTML中的'}}</h1>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
template: "<h1>{{message +'这是在template中的'}}</h1>", //在vue配置项中修改的
data: {
message: 'Vue的生命周期'
}
})
</script>
</html>
注意:el 进行 DOM 绑定要在 template 之前,因为 Vue 需要通过 el 找到对应的 outer template。
render
在 Vue 对象中还有一个 render 函数,它是以 createElement 作为参数,然后做渲染操作, 而且我们可以直接嵌入 JSX,代码如下
var vm=new vue ( {
el: '#app ' ,
render : function (createElement) {
return createElement ( 'h1', 'this is createElement ' )
}
})
所以综合排名优先级:render 函数选项 > template 选项 > outer HTML。
beforeMount和mounted 钩子函数间的生命周
可以看到此时是给 Vue 实例对象添加$el 成员,并且替换掉挂在的 DOM 元素。在之前 console 中打印的结果可以看到 beforeMount 之前 el 上还是 undefined。
Mounted 钩子函数
在 mounted 之前 h1 中还是通过{{message}}进行占位的,因为此时还有挂在到页面上, 还是 JavaScript 中的虚拟 DOM 形式存在的。在 mounted 之后可以看到 h1 中的内容发生了变 化,
beforeUpdate 钩子函数和 updated 钩子函数间的生命周期
当 Vue 发现 data 中的数据发生了改变,会触发对应组件的重新渲染,先后调用 beforeUpdate 和 updated 钩子函数。我们在 console 中输入如下信息
vm.message = ‘触发组件更新’
beforeDestroy 和 destroyed 钩子函数间的生命周期
beforeDestroy 钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed 钩子函数在 Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解 绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
模板渲染
当我们获取到后台数据之后,会按照一定的规则加载到前端写好的模板中,显示在浏览 器中,这个过程称之为渲染。
条件渲染
v-if、v-else 和 v-else-if
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" >
<!--if、else、指令-->
<p v-if="status==1">当status为1时,显示该行</p>
<p v-else-if="status==2">当status为2时,显示该行</p>
<p v-else-if="status==3">当status为3时,显示该行</p>
<p v-else>否则显示该行</p>
</div>
<!--script脚本-->
<script>
//创建vue实例
var vm=new Vue({
el: '#app',
data: {
status: 2
}
});
</script>
</body>
</html>
我们需要注意多个 v-if、v-else-if 和 v-else 之间需要紧挨着
v-show
v-show 实际上同 v-if 效果等同,当绑定事件的元素符合引号中的条件时,该元素才显示
<div id="app" > <!--if、else、指令-->
<p v-show="status==1">当 status 为 1 时,显示该行</p>
<p v-show="status==2">当 status 为 2 时,显示该行</p>
</div>
<script>
//创建 vue 实例
var vm=new Vue({
el: '#app',
data: {
status: 2
}
});
</script>
v-if 和 v-show 的区别
控制显示的方法不同:v-show 实际是通过修改 DOM 元素 的 display 属性来实现节点的显示和隐藏的,而 v-if 则是通过添加/删除 DOM 节点来实现的.
编译条件:v-if 是惰性的,只有在条件第一次变为真时才开始局部编译; v-show 是在不管初始条件是什么,都被编译, 然后被缓存,
性能消耗:v-if 有更高的切换消耗;v-show 有更高的初始渲染消耗;
使用场景:如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时 条件很少改变,当只需要一次显示或隐藏,则使用 v-if 较好。
Key
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染
Vue 高效地渲染元素
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" >
<p v-if="ok">
<label>Username</label>
<input placeholder="Enter your username">
</p>
<p v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</p>
<button @click="ok=!ok">切换</button>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#app',
data: {
ok: true,
}
})
</script>
</body>
</html>
页面中输入信息后点击切换按钮时,文本框里的内容并没有清空。
Vue 为我们提供了一种方式来声明“这两个元素是完全独立的—不要复用它们”。只 需添加一个具有唯一值的 key 属性即可,代码如下:
<div id="app" >
<p v-if="ok">
<label>Username</label>
<input placeholder="Enter your username"key="username-input">
</p>
<p v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</p>
<button @click="ok=!ok">切换</button>
</div>
列表渲染
v-for
v-for 循环用于数组
v-for 指令根据一组数组的选项列表进行渲染。
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<ul id="app">
<li v-for="item in items">
{{ item.name }}
</li>
</ul>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
data: {
items: [
{ name: 'beixi' },
{ name: 'jzj' }
]
}
})
</script>
</body>
</html>
我们定义一个数组类型的数据 items,用 v-for 将
v-for 还支持一个可选的第二个参数为当前项的索引,索引从 0 开始
<ul id="app">
<li v-for="(item,index) in items">
{{index}}-- {{ item.name }}
</li>
</ul>
分隔符 in 前的语句使用括号,第二项就是 Items 当前项的索引
v-for 用于对象
用来遍历对象
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<ul id="app">
<li v-for="value in object">
{{ value }}
</li>
</ul>
<script type="text/javascript">
var vm=new Vue({
el: '#app',
data: {
object: {
name: 'beixi',
gender: '男',
age: 30
}
}
})
</script>
</body>
</html>
v-for 用于整数
<ul id="app">
<li v-for="n in 10">
{{n}}
</li>
</ul>
<script type="text/javascript">
var vm=new Vue({
el: '#app',
})
</script>
template 标签用法
Vue 提供了内置标签,可以将多个元素进行渲染
正常v-if Vue 提供了 v-on 指令来监听 DOM 事件,在事件绑定上,类似原生 JavaScript 的 onclick 事件写法,也是在 HTML 上进行监听 注意:@click 等同于 v-on:click,是一个语法糖 注意:@click 等同于 v-on:click,是一个语法糖 通过 v-on 绑定实例选项属性 methods 中的方法作为事件的处理器 点击 button 按钮,即可触发 say 函数,弹出 alert 框’Say Hello’。 Vue 为指令 v-on 提供了多个修饰符,方便我们处理一些 DOM 事件的细节,Vue 主要的 修饰符如下: 正常的点击事件为 v-on:click=“方法名(参数)” 所以在这种情况下直接写点击事件得到的效果就不是你所想要的 如下阻止了 a 标签的默认刷新: 如下实例在点击最里层的点击 6 时,outer 方法先执行,因为 outer 方法在捕获模式执行 的,先与冒泡事件。下列执行顺序 outer->set->inner,因为后俩个还是冒泡模式下触发的事 件 原理是根据 event.target 确定是否当前元素本身,来决定是否触发的事件/函数 。 方式二 //回车执行 //上键执行 //下键执行 //左键执行 //右键执行 图书管理系统 基于 BootStrap 来快速搭建,官网 http://www.bootcss.com/进行学习, bootstrap-3.3.7.css。<div id="app">
<div v-if="ok">
<p>这是第一段代码</p>
<p>这是第二段代码</p>
<p>这是第三段代码</p>
</div>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#app',
data:{
ok:true
}
})
</script>
同样,标签也支持使用 v-for 指令,用来渲染同级的多个兄弟元素
<ul id="app">
<template v-for="item in items">
{ { item . name } }
{ { item.age }}
</template>
</ul>
<script type="text/javascript">
var vm=new vue ( {
el: '#app ',
data: {
items: [
{ name : 'beixi' },
{ age: 18 }
]
}
})
</script>
v-on
基本用法
v-on :事件名.修饰符=方法名()│方法名|简单的JS表达式
简写:@事件名.修饰符=方法名()|方法名|简单的JS表达式
事件名: click | keydown | keyup/mouseover|mouseout|自定义事件名
直接使用:
直接在标签中书写 js 方法:
<div id="app ">
点击次数{ { count } }
<button @click="count++">点击+1</button>
</div>
<script type="text/javascript">
var vm=new vue ( {
el: '#app ' ,
data : {
count : 0
}
})
</ script>
调用 methods 的办法
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="say">点击</button>
</div>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
data:{
msg:'Say Hello'
},
methods:{
say: function () {
alert(this.msg)
}
}
})
</script>
</body>
</html>
方法传参
方法直接在调用时在方法内传入参数
<div id="app">
button @click="say ( 'Hello beixi')">点击</button>
</div>
<script type="text/javascript">
var vm=new vue ( {
el: '#app ',
data : {
msg: 'say Hello'
},
methods: {
say: function (val){
alert (val)
}
}
})
</script>
传入事件对象
<div id="app">
<button data-aid='123' @click="eventFn ($event)">事件对象</button>
</div>
<script type="text/javascript">
var vm= new vue ( {
el : '#app ' ,
methods : {
eventFn : function (e) {
console.log (e) ;
//e.srcElement dom节点
e.srcElement.style.background='red ' ;
console.log (e.srcElement.dataset.aid);/*获取自定义属性的值*/
}
}
})
</script>
事件绑定
修饰符
.stop
.stop:阻止事件继续传播,即阻止它的捕获和冒泡过程@click.stop='handle()' //只要在事件后面加 .stop 就可以阻止事件冒泡
简写为@click=“方法名(参数)”
有些情况下会出现父级元素有点击事件、子元素也有点击事件
这样就会出现点击子元素会执行两次方法
所以就需要增加一个阻断事件、防止事件继续冒泡
在此只需要给@click事件添加stop方法就可以<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8"/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div style="background-color: aqua;width: 100px;height: 100px" v-on:click="outer">
外部点击
<div style="background-color: red;width: 50px;height: 50px" v-on:click.stop="inner">内部点击</div>
</div>
</div>
<script type="text/javascript">
var vm= new Vue({
el: '#app',
methods:{
outer: function () {
console.log("外部点击")
},
inner: function () {
console.log("内部点击")
}
}
})
</script>
</body>
</html>
.prevent:阻止默认事件
@click.prevent='handle()' //只要在事件后面加 .prevent 就可以阻止默认事件。
<a href="" v-on:click.prevent>点击</a>
.capture:添加事件监听器时使用事件捕获模式,即在捕获模式下触发
@click.capture='handle()'
<div v-on : click.capture="outer">外部点击5
<div v-on : click="inner">内部点击5
<div v-on: click="set">点击6</div>
</div>
</div>
.self:当前元素自身时触发处理函数时才会触发函数
如下示例,如果敲击内部点击,冒泡不会执行 outer 方法,因为 event.target 指的是内部 点击的 dom 元素,不是外部点击的,所以不会触发自己的点击事件<div v-on :click.self="outer">
外部点击
<div v-on: click="inner">内部点击</div>
</ div>
.once:只触发一次,代码如下
<div id="app">
<div v-on : click.once="once">点击once</div>
</div>
<script type="text/javascript">
var vm= new vue ( {
el: '#app' ,
methods : {
once: function () {
console.log("点击once" )
}
}
})
</script>
键盘事件
方式一:@keydown=’show($event)’
<div id="app">
<input type="text" @keydown='show ($event) '/>
</div>
<script type="text/javascript">
var vm= new vue ( {
el: '#app ' ,
methods : {
show : function (ev){
/*在函数中获ev.keycode */
console.log (ev.keycode) ;
if (ev.keycode==13) {
alert ('你按了回车键!')
}
}
}
})
</script>
基础 demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--引入bootstrap-->
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/bootstrap-3.4.1-dist/css/bootstrap.css">
<title>图书管理系统</title>
</head>
<body>
<div class="app">
<!-- 面板标题 -->
<div class="panel panel-primary">
<div class="panel-heading">
<!-- <h3 class="panel-title">面板标题</h3> -->
<h2>图书管理系统</h2>
</div>
<!-- 表单,它的所有元素是内联的,向左对齐的,标签并排 -->
<div class="panel-body form-inline">
<label for="">id:<input type="text" class="form-control" v-model="id" />
<label for="">图书名称:<input type="text" class="form-control" v-model="name" />
<label for=""><input type="button" value="添加" class="btn btn-primary" @click="add" />
</div>
</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>id</th>
<th>图书名称</th>
<th>添加时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in arr" :key="item.id">
<td v-text="item.id"></td>
<td v-text="item.name"></td>
<td v-text="item.time"></td>
<td><a href="" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
var vm = new Vue({
el: ".app",
data: {
arr: [{
'id': 1,
'name': '三国演义',
'time': new Date()
},
{
'id': 2,
'name': '红楼梦',
'time': new Date()
},
{
'id': 3,
'name': '水浒传',
'time': new Date()
},
{
'id': 4,
'name': '西游记',
'time': new Date()
},
], // 创建一些初始化数据
id: '',
name: ''
},
methods: {
add(id) {
this.arr.push({'id':this.id,'name':this.name,'time':new Date()}),
this.id = this.name='';
},
del(id) {
var index = this.arr.findIndex(item => {
if (item.id == id) {
return true;
}
})
this.arr.splice(index, 1)
}
}
})
</script>
</body>
</html>