前言
记录平时学到的知识,标题写的大气一点,也算是给自己一点鼓励,希望在技术这条路可以远走越远,路越走越宽~
PS:如果对你有一点帮助,请顺手给个小星星哦,鼓励我继续写下去~
引入的文件文件说明
vue.js——开发版本:包含完整的警告和调试模式
vue.min.js——生产版本:删除了警告,进行了压缩
1. propsData Option 全局扩展的数据传递
propsData在实际开发中使用的并不多,用在全局扩展时进行传递数据,主要搭配Vue.extend使用。
在实际的项目中,使用全局扩展的方式制作自定义标签比较少用,完全可以使用组件来替代。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>propsData Option</title>
</head>
<body>
<h1>propsData Option</h1>
<hr>
<div id="app"></div>
<script type="text/javascript">
var header_a = Vue.extend({
template:`<p>{{message}}</p>`,
data:function(){
return {
message:'Hello,I am Header'
}
}
});
new header_a().$mount('#app');
</script>
</body>
</html>
扩展标签已经做好了,这时要在挂载时传递数据,就用到了propsData。
使用用propsData三步解决传值:
- 在全局扩展里加入props进行接收;
- 传递时用propsData进行传递;
- 用插值的形式写入模板;
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>propsData Option</title>
</head>
<body>
<h1>propsData Option</h1>
<hr>
<div id="app"></div>
<script type="text/javascript">
var header_a = Vue.extend({
template:`<p>{{message}}-{{a}}</p>`,
data:function(){
return {
message:'Hello,I am Header'
}
},
props:['a']
});
new header_a({propsData:{a:1}}).$mount('header');
</script>
</body>
</html>
2.computed Option 计算选项
computed计算属性的主要作用是在数据渲染之前,根据实际需求对数据进行处理,比如:大小写转换,顺序重排,添加符号……。为了不污染data中定义的数据源,在computed里需要新声明一个对象保存处理之后的数据。
computed计算属性的所有getter和setter的this上下文自动地绑定为 Vue 实例。注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。
computed: {
aDouble: vm => vm.a * 2
}
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。
用计算属性反转新闻数据数组,让最近发生的新闻放在前面显示,demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>computed 计算选项</title>
</head>
<body>
<h1>computed 计算选项</h1>
<hr>
<div id="app">
{{newPrice}}
<br>
<br>
<ul>
<li v-for="item in reverseNews">{{item.title}} - {{item.date}}</li>
</ul>
</div>
<script type="text/javascript">
var newsList = [
{title:'香港或就“装甲车被扣”事件追责 起诉涉事运输公司',date:'2017/3/10'},
{title:'日本第二大准航母服役 外媒:针对中国潜艇',date:'2017/3/12'},
{title:'中国北方将有明显雨雪降温天气 南方阴雨持续',date:'2017/3/13'},
{title:'起底“最短命副市长”:不到40天落马,全家被查',date:'2017/3/23'},
];
var app=new Vue({
el:'#app',
data:{
price:100,
newsList: newsList
},
computed:{
newPrice:function(){
return this.price='¥' + this.price + '元';
},
reverseNews:function(){
return this.newsList.reverse();
}
}
})
</script>
</body>
</html>
computed 计算属性是非常有用并且在实际的项目开发中经常使用,它在输出数据前可以根据实际项目需求对数据进行处理,改变数据。
3. methods Option 方法选项
在Vue中,可以使用v-on给元素绑定事件,在methods选项中处理一些逻辑方面的事情。在Vue中的逻辑处理,一般都在Vue的methods选项中来处理,那是因为很多事件处理逻辑代码都很复杂,如果直接把JavaScript代码写在v-on指令中有时并不可行,所以在methods中定义方法,让v-on指令来接收(调用)。
一个数字,每点击一下按钮加2:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>methods Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{ a }}
<p><button @click="add">add</button></p>
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add () {
this.a++
}
}
})
</script>
</body>
</html>
methods中参数的传递:
使用方法和正常的javascript传递参数的方法一样,分为两步:
- 在methods的方法中进行声明,比如给add方法传入一个num参数,就要写出add (num){...};
- 调用方法时直接传递,比如要传递2这个参数,在button上就直接可以写。
<button @click=”add(2)”></button>
;
给add添加num参数,并在按钮上调用传递:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>methods Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{ a }}
<p><button @click="add(2)">add</button></p>
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add (num) {
this.a += num
}
}
})
</script>
</body>
</html>
这时,再点击按钮时结果每次加2。
methods中的$event参数:
传递的$event参数都是关于你点击鼠标的一些事件和属性。传递方法:
<button @click=”add(2,$event)”>add</button> 。
这时候可以打印一下,看看event到底是个怎样的对象。你会发现,它包含了大部分鼠标事件的属性:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>methods Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{ a }}
<p><button @click="add(2,'每次加2', $event)">add</button></p>
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add (num, msg, event) {
console.log('num==>', num)
console.log('msg==>', msg)
console.log('event==>', event)
this.a += num
}
}
})
</script>
</body>
native 给组件绑定构造器里的原生事件:
在实际开发中经常需要把某个按钮封装成组件,然后反复使用,如何让组件调用构造器里的方法,而不是组件里的方法。就需要用到.native修饰器了。
把我们的add按钮封装成组件,声明btn对象:
var btn={
template:`<button>组件Add</button>`
}
在构造器里注册组件:
components:{
"btn":btn
}
用.native修饰器来调用构造器里的add方法:
<p><btn @click.native="add(3)"></btn></p>
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>methods Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{a}}
<p><button @click="add(2, '每次加2', $event)">add</button></p>
<p><btn @click.native="add(3, '每次加3', $event)"></btn></p>
</div>
<script type="text/javascript">
var btn={
template:'<button>外部组件</button>'
}
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add (num, msg, event) {
console.log('num==>', num)
console.log('msg==>', msg)
console.log('event==>', event)
this.a += num
}
},
components:{
"btn":btn
}
})
</script>
</body>
</html>
作用域外部调用构造器里的方法:
这种不经常使用,如果你出现了这种情况,说明你的代码组织不够好。
<button onclick="app.add(4)" >外部调用构造器里的方法</button>
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>methods Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{a}}
<p><button @click="add(2, '每次加2', $event)">add</button></p>
<p><btn @click.native="add(3, '每次加3', $event)"></btn></p>
</div>
<button onclick="app.add(4, '每次加4')">外部访问构造器里的方法</button>
<script type="text/javascript">
var btn={
template:'<button>外部组件</button>'
}
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add (num, msg, event) {
console.log('num==>', num)
console.log('msg==>', msg)
console.log('event==>', event)
this.a += num
}
},
components:{
"btn":btn
}
})
</script>
</body>
</html>
4. Watch 选项 监控数据
使用watch选项来监控数据的变化。watch选项对应一个对象,键是观察表达式,值是对应回调。值也可以是方法名,或者是对象,包含选项。在实例化时为每个键调用 $watch() 。
天气预报的穿衣指数,它主要是根据温度来进行提示,温度大于26度时,建议穿T恤短袖,温度小于26度大于0度时,建议穿夹克长裙,温度小于0度时建议穿棉衣羽绒服:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>watch Option</title>
</head>
<body>
<h1>watch Option</h1>
<hr>
<div id="app">
<p>今日温度:{{temperature}}°C</p>
<p>穿衣建议:{{suggestion}}</p>
<p>
<button @click="add">添加温度</button>
<button @click="reduce">减少温度</button>
</p>
</div>
<script type="text/javascript">
var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
var app=new Vue({
el:'#app',
data:{
temperature:14,
suggestion:'夹克长裙'
},
methods:{
add:function(){
this.temperature+=5;
},
reduce:function(){
this.temperature-=5;
}
},
watch:{
temperature (newVal,oldVal) {
if(newVal>=26){
this.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.suggestion=suggestion[1];
}else{
this.suggestion=suggestion[2];
}
}
}
})
</script>
</body>
</html>
handler方法和immediate属性:
这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 temperature 改变时才执行监听计算。那我们想要一开始就让它最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>watch Option</title>
</head>
<body>
<h1>watch Option</h1>
<hr>
<div id="app">
<p>今日温度:{{temperature}}°C</p>
<p>穿衣建议:{{suggestion}}</p>
<p>
<button @click="add">添加温度</button>
<button @click="reduce">减少温度</button>
</p>
</div>
<script type="text/javascript">
var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
var app=new Vue({
el:'#app',
data:{
temperature:14,
suggestion:'T恤短袖'
},
methods:{
add:function(){
this.temperature+=5;
},
reduce:function(){
this.temperature-=5;
}
},
watch:{
temperature: {
handler (newVal,oldVal) {
if(newVal>=26){
this.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.suggestion=suggestion[1];
}else{
this.suggestion=suggestion[2];
}
},
// 代表在wacth里声明了temperature这个方法之后立即先去执行handler方法
immediate: true
}
}
})
</script>
</body>
</html>
注意到handler了吗,我们给 temperature 绑定了一个handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。
而immediate:true代表如果在 wacth 里声明了 temperature 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。
在上面的事例中把suggestion
的初始数据设置为'T恤短袖',而初始温度是14°C,这时如果没有让watch在最初绑定的时候就执行,那么推荐的穿衣就有问题,因为14°C原本是推荐穿'夹克长裙'的,通过让watch在最初绑定的时候就执行完美解决了这个问题。
deep属性:
watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听,比如我们 data 里有一个obj属性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>watch Option</title>
</head>
<body>
<h1>watch Option</h1>
<hr>
<div id="app">
<p>今日温度:{{obj.temperature}}°C</p>
<p>穿衣建议:{{obj.suggestion}}</p>
<p>
<button @click="add">添加温度</button>
<button @click="reduce">减少温度</button>
</p>
</div>
<script type="text/javascript">
var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
var app=new Vue({
el:'#app',
data: {
obj: {
temperature: 14,
suggestion:'T恤短袖'
}
},
methods:{
add:function(){
this.obj.temperature+=5;
},
reduce:function(){
this.obj.temperature-=5;
}
},
watch: {
obj: {
handler(newVal, oldVal) {
console.log('obj.a changed', newVal.temperature)
if(newVal.temperature>=26){
this.obj.suggestion=suggestion[0];
}else if(newVal.temperature<26 && newVal.temperature >=0)
{
this.obj.suggestion=suggestion[1];
}else{
this.obj.suggestion=suggestion[2];
}
console.log('obj.a 2', newVal.suggestion)
},
immediate: true
}
}
})
</script>
</body>
</html>
当我们在点击添加温度和减少温度按钮改变obj.temperature的值时,发现是无效的。受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
默认情况下 handler 只监听obj这个属性它的引用的变化,我们只有给obj赋值的时候它才会监听到,比如我们在 mounted事件钩子函数中对obj进行重新赋值:
mounted: {
this.obj = {
temperature: 40,
suggestion:'T恤短袖'
}
}
这样我们的 handler 才会执行。
如果需要监听obj里的属性temperature的值,这时候deep属性就派上用场了:
watch: {
obj: {
handler(newVal, oldVal) {
console.log('obj.a changed', newVal.temperature)
if(newVal.temperature>=26){
this.obj.suggestion=suggestion[0];
}else if(newVal.temperature<26 && newVal.temperature >=0)
{
this.obj.suggestion=suggestion[1];
}else{
this.obj.suggestion=suggestion[2];
}
console.log('obj.a 2', newVal.suggestion)
},
immediate: true,
deep: true
}
}
deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。
优化,可以使用字符串形式监听:
watch: {
'obj.temperature': {
handler(newVal, oldVal) {
console.log('obj.a changed', newVal)
if(newVal>=26){
this.obj.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.obj.suggestion=suggestion[1];
}else{
this.obj.suggestion=suggestion[2];
}
console.log('obj.a 2', this.obj.suggestion)
},
immediate: true,
deep: true
}
}
这样Vue.js才会一层一层解析下去,直到遇到属性temperature,然后才给temperature设置监听函数。
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>watch Option</title>
</head>
<body>
<h1>watch Option</h1>
<hr>
<div id="app">
<p>今日温度:{{obj.temperature}}°C</p>
<p>穿衣建议:{{obj.suggestion}}</p>
<p>
<button @click="add">添加温度</button>
<button @click="reduce">减少温度</button>
</p>
</div>
<script type="text/javascript">
var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
var app=new Vue({
el:'#app',
data: {
obj: {
temperature: 14,
suggestion:'T恤短袖'
}
},
methods:{
add:function(){
this.obj.temperature+=5;
},
reduce:function(){
this.obj.temperature-=5;
}
},
// watch: {
// obj: {
// handler(newVal, oldVal) {
// console.log('obj.a changed', newVal.temperature)
// if(newVal.temperature>=26){
// this.obj.suggestion=suggestion[0];
// }else if(newVal.temperature<26 && newVal.temperature >=0)
// {
// this.obj.suggestion=suggestion[1];
// }else{
// this.obj.suggestion=suggestion[2];
// }
// console.log('obj.a 2', newVal.suggestion)
// },
// immediate: true,
// deep: true
// }
// }
//优化使用字符串形式监听
watch: {
'obj.temperature': {
handler(newVal, oldVal) {
console.log('obj.a changed', newVal)
if(newVal>=26){
this.obj.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.obj.suggestion=suggestion[1];
}else{
this.obj.suggestion=suggestion[2];
}
console.log('obj.a 2', this.obj.suggestion)
},
immediate: true,
deep: true
}
}
})
</script>
</body>
</html>
用实例属性写watch监控:
有些时候我们会用实例属性的形式来写watch监控。也就是把我们watch卸载构造器的外部,这样的好处就是降低我们程序的耦合度,使程序变的灵活:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>watch Option</title>
</head>
<body>
<h1>watch Option</h1>
<hr>
<div id="app">
<p>今日温度:{{temperature}}°C</p>
<p>穿衣建议:{{suggestion}}</p>
<p>
<button @click="add">添加温度</button>
<button @click="reduce">减少温度</button>
</p>
</div>
<script type="text/javascript">
var suggestion=['T恤短袖','夹克长裙','棉衣羽绒服'];
var app=new Vue({
el:'#app',
data:{
temperature:14,
suggestion:'夹克长裙'
},
methods:{
add:function(){
this.temperature+=5;
},
reduce:function(){
this.temperature-=5;
}
}
})
app.$watch('temperature',function(newVal,oldVal){
if(newVal>=26){
this.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.suggestion=suggestion[1];
}else{
this.suggestion=suggestion[2];
}
})
</script>
</body>
</html>
注销watch:
为什么要注销 watch?因为我们的组件是经常要被销毁的,比如我们跳一个路由,从一个页面跳到另外一个页面,那么原来的页面的 watch 其实就没用了,这时候我们应该注销掉原来页面的 watch 的,不然的话可能会导致内置溢出。当把 watch 写在组件的选项中的,它会随着组件的销毁而销毁。
但是,如果我们使用上面的这样的方式写 watch:
app.$watch('temperature',function(newVal,oldVal){
if(newVal>=26){
this.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.suggestion=suggestion[1];
}else{
this.suggestion=suggestion[2];
}
})
那么就要手动注销了,这种注销其实也很简单:
var unwatch = app.$watch('temperature',function(newVal,oldVal){
if(newVal>=26){
this.suggestion=suggestion[0];
}else if(newVal<26 && newVal >=0)
{
this.suggestion=suggestion[1];
}else{
this.suggestion=suggestion[2];
}
})
unWatch(); // 手动注销watch
app.$watch调用后会返回一个值,就是unWatch方法,你要注销 watch 只要调用unWatch方法就可以了。
5. mixins 混入选项
混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
mixins一般有两种用途:
- 在你已经写好了构造器后,需要增加方法或者临时的活动时使用的方法,这时用混入会减少源代码的污染。
- 很多地方都会用到的公用方法,用混入的方法可以减少代码量,实现代码重用。
现在有个数字点击递增的程序,假设已经完成了,这时希望每次数据变化时都能够在控制台打印出提示:“数据发生变化”:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Mixins Option</title>
</head>
<body>
<h1>Mixins Option Demo</h1>
<hr>
<div id="app">
<p>num: {{ num }}</p>
<P><button @click="add">增加数量</button></P>
</div>
<script type="text/javascript">
//额外临时加入,用于显示日志
var addLog={
updated:function(){
console.log("数据放生变化,变化成"+this.num+".");
}
}
var app=new Vue({
el:'#app',
data:{
num:1
},
methods:{
add:function(){
this.num++;
}
},
//混入
mixins:[addLog]
})
</script>
</body>
</html>
选项合并:
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合,合并规则:
- 值为对象的选项,例如数据对象data、方法对象methods、组件对象components和自定义指令对象directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Mixins Option</title>
</head>
<body>
<h1>Mixins Option Demo</h1>
<hr>
<div id="app">
<p>num: {{ num }}</p>
<P><button @click="add">增加数量</button></P>
</div>
<script type="text/javascript">
//额外临时加入,用于显示日志
var addLog={
data: function () {
return {
message: 'hello',
foo: 'abc'
}
},
updated () {
console.log("数据放生变化,变化成"+this.num+".");
},
created () {
console.log('混入对象的钩子被调用==>', this.$data)
}
}
var app=new Vue({
el:'#app',
data:{
num:1,
message: 'goodbye',
bar: 'def'
},
methods:{
add:function(){
this.num++;
}
},
created () {
console.log('实例钩子被调用==>', this.$data)
},
//混入
mixins:[addLog]
})
</script>
</body>
</html>
打开控制台可以看到,混入的created钩子函数和实例的created钩子函数打印出的this.$data都为{bar: "def", foo: "abc", message: "goodbye", num: 1}
。
- 由1的例子可以看出,同名钩子函数将混合为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
mixins的调用顺序:
从执行的先后顺序来说,都是混入的先执行,然后构造器里的再执行,需要注意的是,这并不是方法的覆盖,而是被执行了两边。
同名钩子函数将混合为一个数组,因此都将被调用。混入对象的钩子将在组件自身钩子之前调用。
全局API混入方式:
可以全局注册混入对象。但应注意使用!因为一旦使用全局混入对象,将会影响到所有之后创建的 Vue 实例。
定义全局的混入,然后在需要这段代码的地方直接引入js,就可以拥有这个功能了:
Vue.mixin({
updated:function(){
console.log('我是全局被混入的');
}
})
注意:全局混入的执行顺序要前于混入和构造器里的方法。
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Mixins Option</title>
</head>
<body>
<h1>Mixins Option Demo</h1>
<hr>
<div id="app">
<p>num: {{ num }}</p>
<P><button @click="add">增加数量</button></P>
</div>
<script type="text/javascript">
//全局混入
Vue.mixin({
created () {
console.log('我是全局混入');
}
})
//额外临时加入,用于显示日志
var addLog={
data: function () {
return {
message: 'hello',
foo: 'abc'
}
},
updated () {
console.log("数据放生变化,变化成"+this.num+".");
},
created () {
console.log('混入对象的钩子被调用==>', this.$data)
}
}
var app=new Vue({
el:'#app',
data:{
num:1,
message: 'goodbye',
bar: 'def'
},
methods:{
add:function(){
this.num++;
}
},
created () {
console.log('实例钩子被调用==>', this.$data)
},
//混入
mixins:[addLog]
})
</script>
</body>
</html>
6. extends Option 扩展选项
通过外部增加对象的形式,对构造器进行扩展。允许声明扩展另一个组件(可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend。这主要是为了便于扩展单文件组件。和 mixins 类似。
选项合并:
当组件和扩展对象含有同名选项时,这些选项将以恰当的方式混合,合并规则:
- 值为对象的选项,例如数据对象data、方法对象methods、组件对象components和自定义指令对象directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
- 同名钩子函数将混合为一个数组,因此都将被调用。另外,扩展对象的钩子将在组件自身钩子之前调用。
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Extends Optin</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>Extends Optin Demo</h1>
<hr>
<div id="app">
{{message}}
<p><button @click="add">add</button></p>
</div>
<script type="text/javascript">
var bbb={
created () {
console.log("我是扩展出来的钩子函数");
},
methods:{
add () {
console.log('我是被扩展出来的方法!');
}
}
};
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!'
},
methods:{
add () {
console.log('我是原生方法');
}
},
created () {
console.log("我是原生的钩子函数");
},
extends:bbb
})
</script>
</body>
</html>
打开控制台可以看到,扩展出来的钩子函数先执行,然后是实例的钩子函数;点击按钮之后只有实例的方法被执行。
7. delimiters 选项
delimiters的作用是改变插值的符号。Vue默认的插值是双大括号{{}}。但有时我们会有需求更改这个插值的形式。
比如后台渲染模板如swig,也使用“{{ }}“作为渲染,与前端vue的数据绑定“Mustache”语法 (双大括号)产生冲突,此时只要在新建Vue对象时,添加delimiters: ['${', '}'],就搞定了。
现在插值形式就变成了${}。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>delimiters Option</title>
</head>
<body>
<h1>delimiters Option</h1>
<hr>
<div id="app">
<ul>
<li v-for=" aa in arr">${aa}</li>
</ul>
</div>
<script type="text/javascript">
var outData={
arr:['aaa','bbb','ccc'],
};
var app=new Vue({
delimiters: ['${', '}'],
el: '#app',
data: outData
})
</script>
</body>
</html>