个人小总结:1年多没有写博客,感觉很多知识点生疏了,虽然工作上能解决问题,但是当别人问到某个知识点的时候,还是迷迷糊糊的,所以坚持写博客是硬道理的,因为大脑不可能把所有的知识点记住,有可能某一天忘了,但是我们工作上还是会使用,只是理论忘了,所以写博客的好处是可以把之前的东西重新看一遍后会在大脑里面重新浮现起来,特别在面试的时候,别人问你的知识点的时候答不上来那种尴尬,但是平时经常使用到,只是说不出所以来的,因此写博客是最好的思路。

阅读目录

1.vue属性和方法

每个Vue实例都会代理其 data对象里所有的属性。
如下代码:

var data = {
a: 1
};
var vm = new Vue({
data: data
});
console.log(vm);
console.log(vm.a === data.a); // true // 设置属性也会影响到原始数据
vm.a = 2;
console.log(data.a); //
// 反之
data.a = 3;
console.log(vm.a); //
//除了data属性,Vue实例还暴露了一些有用的实例属性与方法。这些属性与方法都有前缀$, 以便与代理的data属性区分。
var data = { a: 1 }
var vm = new Vue({
el: '#container1',
data: data
})
console.log(vm.$data === data) // true
console.log(vm.$el === document.getElementById('container1')) // true
data.a = 5;
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
// 这个回调将在 `vm.a` 改变后调用
console.log(newVal);
console.log(oldVal);
})

1-1. data 必须是函数
通过Vue构造器传入的各种选项大多数都可以在组件里用。 data 是一个例外,它必须是函数。 如下代码Vue 会停止,并在控制台会报错。

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1"> <component1></component1>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
var data = { counter: 0 };
// 全局注册
Vue.component('component1', {
template: '<span>{{ message }}</span>',
data: {
message: 'hello'
}
});
new Vue({
el: '#container1'
})
</script>
</html>

data是函数解决该方案
代码如下:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<component1></component1>
<component1></component1>
<component1></component1>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
var data = { counter: 0 };
// 全局注册
Vue.component('component1', {
template: '<button v-on:click="counter += 1">{{ counter }}</button>',
// data是一个函数,vue不会报错,但是我们返回给每个组件的实列引用了同一个data对象
data: function() {
return data
}
});
new Vue({
el: '#container1'
})
</script>
</html>

查看效果

由于这三个组件共享了同一个 data , 因此增加一个 counter 会影响所有组件!这不对。我们可以通过为每个组件返回全新的 data 对象来解决这个问题:
代码如下:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<component1></component1>
<component1></component1>
<component1></component1>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
// 全局注册
Vue.component('component1', {
template: '<button v-on:click="counter += 1">{{ counter }}</button>',
// data是一个函数,vue不会报错,但是我们返回给每个组件的实列引用了同一个data对象
data: function() {
return {
counter: 0
}
}
});
new Vue({
el: '#container1'
})
</script>
</html>

查看效果

现在每个 counter 都有它自己内部的状态了.

2.理解组件的通信。

一般情况父子组件是这样的关系,组件A在它的模板中使用了组件B,他们之间必然需要相互通信,父组件要给子组件传递数据,子组件需要将它内部发生的事情告知父组件,为了保证父子组件的解耦,可维护性及可重用性。在vue.js中,父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。

2-1 使用props传递数据
不能在子组件的模板内直接引用父组件的数据,要让子组件使用父组件的数据,我们需要通过子组件的props选项。
如下代码:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<child message="hello!"></child>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
// 全局注册
Vue.component('child', {
// 声明props
props: ['message'],
template: '<span>{{ message }}</span>'
});
new Vue({
el: '#container1'
})
</script>
</html>

结果在页面上会打印 hello。

查看效果

注意: HTML特性是不区分大小写的,所以当使用的不是字符串模板,camelCased(驼峰式) 命名的prop需要转换为相对应的 kebab-case(短横线隔开式)命名:
如下代码:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<!-- kebab-case in HTML-->
<child my-message="hello!"></child>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
// 全局注册
Vue.component('child', {
// 声明props
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
});
new Vue({
el: '#container1'
})
</script>
</html>

2-2 理解动态prop
在模板中,要动态地绑定父组件的数据到子模板的props,使用v-bind,每当父组件的数据变化时,该变化会传递给子组件。

<div id="container1">
<input v-model='parentMsg' />
<br />
<!-- kebab-case in HTML-->
<child v-bind:my-message="parentMsg"></child>
</div>

使用 v-bind 的缩写语法通常更简单:

<child :my-message="parentMsg"></child>

代码如下:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<input v-model='parentMsg' />
<br />
<!-- kebab-case in HTML-->
<child v-bind:my-message="parentMsg"></child>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#container1',
data: {
parentMsg: 'Message'
},
components: {
child: {
props: ['myMessage'],
template: '<span>{{myMessage}}</span>'
}
}
})
</script>
</html>

查看效果

3.理解自定义事件

父组件使用props传递数据给子组件,但是如果子组件需要把数据传回去的话,就需要自定义事件了;
3-1 使用v-on绑定自定义事件
每个vue实例都实现了事件接口,即:
1. 使用 $on(eventName) 监听事件
2. 使用 $emit(eventName) 触发事件
注意: $on 和 $emit 不是 addEventListener 和 dispatchEvent的别名。且 父组件可以在使用组件的地方直接用 v-on 来监听子组件触发的事件。
不能用$on侦听子组件抛出的事件,而必须在模板里直接用v-on绑定,就像以下的例子:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<p> {{ total }} </p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
Vue.component('button-counter', {
template: '<button v-on:click="increment">{{ counter }}</button>',
data: function() {
return {
counter: 0
}
},
methods: {
increment: function() {
this.counter += 1;
this.$emit('increment');
}
},
})
new Vue({
el: '#container1',
data: {
total: 0
},
methods: {
incrementTotal: function() {
this.total += 1;
}
}
})
</script>
</html>

上面代码: 初始化时候 实例化设置 data: {total: 0}, 设置total为0, 子组件button-counter 默认为0, 当点击子组件的时候调用 increment方法,当前的counter自增1, 然后在子组件触发 $emit('increment')事件,当使用 v-on:increment 会监听到事件后,会调用父组件的incrementTotal方法,因此父组件也自增1.

查看效果

上面代码中 子组件已经和它外部完全解耦了。它所做的只是报告自己的内部事件,至于父组件是否关心则与它无关。

4.理解使用自定义事件的表单输入组件

自定义事件可以用来创建自定义的表单输入组件,使用v-modal来进行数据双向绑定。比如如下代码:

<input v-modal="something" />

上面的代码是下面的语法糖;如下代码:

<input v-bind:value="something" v-on:input="something=$event.target.value" />

因此在创建组件中时,相当于下面的简写;如下代码:

<custom-input v-bind:value="something" v-on:input="something=arguments[0]"></custom-input>

所以要让组件的v-model 生效,必须满足下面的条件:
1. 接受一个value属性。
2. 在有新的value时触发input事件。

如下测试代码:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<currency-input v-model="price"></currency-input>
</div>
</body>
<script src="./vue.js"></script>
<script> </script>
<script type="text/javascript">
Vue.component('currency-input', {
template: '\
<span>\
$\
<input\
ref="input"\
v-bind:value="value"\
v-on:input="updateValue($event.target.value)"\
>\
</span>\
',
props: ['value'],
methods: {
// 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
updateValue: function (value) {
var formattedValue = value
// 删除两侧的空格符
.trim()
// 保留 2 小数位
.slice(0, value.indexOf('.') + 3)
// 如果值不统一,手动覆盖以保持一致
if (formattedValue !== value) {
this.$refs.input.value = formattedValue
}
// 通过 input 事件发出数值
this.$emit('input', Number(formattedValue))
}
}
});
new Vue({
el: '#container1',
data: {
price: 0
}
})
</script>
</html>

查看效果

5.单个slot

<slot>标签中的任何内容都被视为 备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有插入的内容时才显示备用内容。
如果<slot>标签中有内容的话,就显示该内容。
比如 my-component 组件有如下代码:

<div class="content">
<h2>this is a component</h2>
<slot>如果没有分发内容,则显示slot中的内容</slot>
<p>asdsadsdad</p>
</div>

父组件有如下代码:

<div id="container1">
<my-component>
<h1>Hello Vue.js</h1>
</my-component>
<my-component></my-component>
</div>

渲染后的结果为:

<div id="container1">
<div class="content">
<h2>this is a component</h2>
<h1>Hello Vue.js</h1>
<p>asdsadsdad</p>
</div>
<div class="content">
<h2>this is a component</h2>
如果没有分发内容,则显示slot中的内容
<p>asdsadsdad</p>
</div>
</div>

所有测试实例代码如下:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head> <div id="container1">
<my-component>
<h1>Hello Vue.js</h1>
</my-component>
<my-component></my-component>
</div> <template id="myComponent">
<div class="content">
<h2>this is a component</h2>
<slot>如果没有分发内容,则显示slot中的内容</slot>
<p>asdsadsdad</p>
</div>
</template> </body>
<script src="./vue.js"></script>
<script type="text/javascript">
Vue.component('my-component', {
template: '#myComponent'
})
new Vue({
el: '#container1'
})
</script>
</html>

查看效果

6.具名slot

<slot> 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃。
比如:假如有一个 my-component 组件,它的模板为:

<template id="myComponent">
<div class='content'>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
</template>

父组件的模板如下:

<div id="container1">
<h1 slot="header">这里可能是一个页面标题</h1>
<p>主要内容的一个段落</p>
<p>另一个主要段落</p>
<p slot='footer'>这里是底部信息</p>
</div>

页面渲染的结果如下:

<div id="container1">
<h1>这里可能是一个页面标题</h1>
<p>主要内容的一个段落</p>
<p>另一个主要段落</p>
<p>这里是底部信息</p>
</div>

所有的代码如下:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head> <div id="container1">
<h1 slot="header">这里可能是一个页面标题</h1>
<p>主要内容的一个段落</p>
<p>另一个主要段落</p>
<p slot='footer'>这里是底部信息</p>
</div> <template id="myComponent">
<div class='content'>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
</template> </body>
<script src="./vue.js"></script>
<script type="text/javascript">
Vue.component('my-component', {
template: '#myComponent'
})
new Vue({
el: '#container1'
})
</script>
</html>

查看效果

7.理解作用域插槽(2.1.0新增的)

在slot分发中,无论是单分发还是具名分发,都是父组件替换子组件的数据,或者没有替换,用子组件默认的数据。 但是通过设置作用域槽,就可以改变这种状况,让子组件可以在父组件进行分发时获取自己的数据,至于是什么数据,由子组件决定,这样就能解耦了。
作用域槽通过slot的一个自定义的属性,官方给出的DEMO是text,但也可以是其他,值为暴露的数据。 这个自定义属性已经存放在子组件的prop对象里了。等待着被父组件获取。
怎么获取呢? 在父组件的模板里,使用一个Vue自带的特殊组件<template> ,并在该组件上使用scope属性,值是一个临时的变量,存着的是由子组件传过来的prop对象,获得由子传过来的prop对象。这时候,父组件就可以访问子组件在自定义属性上暴露的数据了。
如下代码:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head>
<div id="container1">
<parent-component></parent-component>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
// 子组件
Vue.component('child-component', {
template: '<ul><slot name="child-ul" v-for="item in rets" v-bind:text="item.name"></slot></ul>',
data: function() {
return {
rets: [
{name: '我是苹果'},
{name: '我是香蕉'},
{name: '我是橘子'}
]
}
}
});
// 父组件
Vue.component('parent-component', {
template: '<child-component><template scope="props" slot="child-ul"><li>{{props.text}}</li></template></child-component>'
})
new Vue({
el: '#container1'
})
</script>
</html>

页面渲染后的代码如下:

<div id="container1">
<ul>
<li>我是苹果</li>
<li>我是香蕉</li>
<li>我是橘子</li>
</ul>
</div>

查看效果

8.理解动态组件

通过使用保留的<component>元素,动态地绑定到它的 is 特性,我们可以让多个组件使用同一个挂载点,并动态的切换。
keep-alive: 如果把切换出去的组件留在内存中,可以保留它的状态或避免重新渲染,为此我们可以添加一个 keep-alive指令参数。
如下实现的tab切换代码:

<!DOCTYPE html>
<html>
<body>
<head>
<title>演示Vue</title>
</head> <h3>动态组件</h3>
<template id="tab-01">
<div>this is tab01</div>
</template>
<template id='tab-02'>
<div>this is tab02</div>
</template>
<template id="tab-03">
<div>this is tab03</div>
</template> <div id="container1">
<!-- 导航栏 -->
<ul>
<li>
<a href="javascript:void(0)" @click="toggleTabs(tab01Text);">{{ tab01Text }}</a>
</li>
<li>
<a href="javascript:void(0)" @click="toggleTabs(tab02Text);">{{ tab02Text }}</a>
</li>
<li>
<a href="javascript:void(0)" @click="toggleTabs(tab03Text);">{{ tab03Text }}</a>
</li>
</ul>
<!-- 点击导航后要切换的内容 -->
<div class='content' style='height: 200px'>
<!-- 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数 -->
<keep-alive>
<component :is="currentView"></component>
</keep-alive>
</div>
</div>
</body>
<script src="./vue.js"></script>
<script type="text/javascript">
var tab01 = Vue.extend({
template: '#tab-01'
});
var tab02 = Vue.extend({
template: '#tab-02'
});
var tab03 = Vue.extend({
template: '#tab-03'
});
// 新建vue实例
var newVue = new Vue({
el: '#container1',
data: {
tab01Text: "tab01", // 菜单一
tab02Text: "tab02", // 菜单二
tab03Text: "tab03", // 菜单三
currentView: "tab01" // 默认选中的导航栏
},
// 局部注册组件
components: {
tab01: tab01,
tab02: tab02,
tab03: tab03,
},
methods: {
// 绑定tab的切换事件
toggleTabs: function(tabText) {
this.currentView = tabText;
}
}
})
</script>
</html>

查看效果

Vue2 第二天学习的更多相关文章

  1. Vue2基础知识学习

    Vue2基础知识学习 01.初识 new Vue({ el: '#root', //用于指定当前Vue实例为哪个容器服务,值通常为css选择器符 data () { return { } } }); ...

  2. 20145213《Java程序设计》第二周学习总结

    20145213<Java程序设计>第二周学习总结 教材学习内容总结 本周娄老师给的任务是学习教材的第三章--基础语法.其实我觉得还蛮轻松的,因为在翻开厚重的书本,一股熟悉的气息扑面而来, ...

  3. 20145330孙文馨 《Java程序设计》第二周学习总结

    20145330孙文馨第二周学习总结 第二周相比于第一周对java语言有了深一点的了解,也意识到多敲代码才是学习计算机语言的最好方法. 教材内容总结 类型.变量与运算符 *基本类型 整数(short. ...

  4. 20145337 《Java程序设计》第二周学习总结

    20145337 <Java程序设计>第二周学习总结 教材学习内容总结 Java可分基本类型与类类型: 基本类型分整数(short.int.long).字节(byte).浮点数(float ...

  5. 20135328信息安全系统设计基础第二周学习总结(vim、gcc、gdb)

    第三周学习笔记 学习计时:共8小时 读书:1 代码:5 作业:1 博客:7 一.学习目标 熟悉Linux系统下的开发环境 熟悉vi的基本操作 熟悉gcc编译器的基本原理 熟练使用gcc编译器的常用选项 ...

  6. 《Java程序设计》第二周学习总结

    20145224陈颢文<Java程序设计>第二周学习总结 教材学习内容总结 一.类型.变量与运算符 1.类型 整数: 可细分为为short整数(占2字节),int整数(占4字节),long ...

  7. JDBC第二次学习

    脑子太笨,必须得记录下来一些文字,方便回来查询. 这是我的第二次学习JDBC的笔记,看的是传智播客——李勇老师的JDBC系列,已看到第23集. 分析在实际项目中该如何应用JDBC 一个简单用户相关的数 ...

  8. 20155304田宜楠 2006-2007-2 《Java程序设计》第二周学习总结

    20155304田宜楠 2006-2007-2 <Java程序设计>第二周学习总结 教材学习内容总结 一.类型与变量 1.类型 整数: 可细分为为short整数(占2字节),int整数(占 ...

  9. 2017面向对象程序设计(Java)第二周学习总结

    2017面向对象程序设计(Java)第二周学习总结 直系学妹学弟们好!额...不要问我为什么把学妹放前面,我也不知道!我只是你们和蔼可亲的学长一枚而已.也不要问为什么是第二周学习总结而不是第一周,因为 ...

随机推荐

  1. linux最靠谱安装python3

    linux环境编译安装python3, 最靠谱的安装方法了这个 1. 下载编译安装python的依赖软件包,只需要执行即可 yum install gcc patch libffi-devel pyt ...

  2. css3火焰文字样式代码

    css样式: <style type="text/css"> body{background:#000;} *{margin:0;padding:0;transitio ...

  3. React Native中Mobx的使用

    从今天开始我们来搞搞状态管理可否,这几天没怎么写博客,因为被病魔战胜了,tmd,突然的降温让我不知所措,大家最近注意安全,毕竟年底了,查的严,呸,大家注意保暖 特别声明:写该文只是写一下用MobX的思 ...

  4. 【读书笔记】iOS-iOS AirPlay与AppleTV

    享受高清晰影院般的大屏幕电影带来的快乐,单纯的iOS设备实现这些是不可能的.苹果有一套解决方案,iOS设备把这些视频和音效数据无线传输(WiFi或蓝牙)Apple TV,然后由Apple TV将视频和 ...

  5. 理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法

    ajax的4种方法:$.get.$.post.$getJSON.$ajax. 1.$.get $.get()方法使用GET方式来进行异步请求,它的语法结构为: $.get( url [, data] ...

  6. Java并发编程(十三)线程间协作的两种方式:wait、notify、notifyAll和Condition

    在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果 ...

  7. Android View体系(八)从源码解析View的layout和draw流程

    前言 上一篇文章我们讲了View的measure的流程,接下来我们讲下View的layout和draw流程,如果你理解了View的measure的流程,那这篇文章自然就不在话下了. 1.View的la ...

  8. GridView的簡單使用

    項目GitHub地址:https://github.com/leonInShanghai/IMbobo GridView XML佈局: <?xml version="1.0" ...

  9. Video.js web视频播放器

    免费视频播放器videojs中文教程 Video.js是一款web视频播放器,支持html5和flash两种播放方式.更多关于video.js的介绍,可以访问官方网站介绍,我之前也写过一篇关于vide ...

  10. 【第二篇】SAP ABAP7.5x新语法之OPEN SQL

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:SAP ABAP7.5x系列之OPEN SQL ...