个人小总结: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. Java高级类特性(二)

    一.static关键字 static关键字用来声明成员属于类,而不是属于类的对象.1). static (类)变量类变量可以被类的所有对象共享,以便与不共享的成员变量区分开来. static变量也称作 ...

  2. matlab的解方程的例子

    syms x y z=exp(2*x+y)+cos(3*x*y)-exp(1)-1; zz=subs(z,x,1) solve(zz)

  3. Nginx学习笔记(二)--- 配置虚拟主机

    Linux下安装Nginx  https://www.cnblogs.com/dddyyy/p/9780705.html 1.虚拟主机介绍 一台服务器分成多个"独立"的主机,每台虚 ...

  4. 纯css3实现的动画导航菜单

    测试咯 css3 前端特效代码 网页模板 图片素材 css3 前端特效代码 网页模板 图片素材 css3 前端特效代码 网页模板 图片素材 css3 前端特效代码 网页模板 图片素材 css3 前端特 ...

  5. javascript基础知识学习

    javascript中几种基础函数的介绍 1.typeof 注意: ① typeof 是操作符,不是函数: ② typeof 操作符 接收一个参数,用来判断参数数据类型,存在六种返回值类型,非别是:u ...

  6. 虚拟机安装ubuntu18.04及其srs服务器的搭建

    第一次写博客,有些地方可能不太完善. 1.安装VMware,我用的是VMware12. 2.下载Ubuntu镜像(自Ubuntu 17.10开始桌面版本不再提供32位安装镜像,Ubuntu Serve ...

  7. Fit项目图片上传和云存储的调通

    项目中关于动作的说明需要相应的配图,这样可以更直观的说明动作要点.本篇主要为项目中动作的新增和编辑做准备,确定适合场景的上传操作逻辑以及图片的存储和加载的方法. 一 上传方案 a) 本来所用的模板中是 ...

  8. java设计模式学习

    每次面试都需要看设计模式,每次都很好的理解了,但是实际开发中没有应用总是忘记.现在把它汇总一下. 二十三种设计模式 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模 ...

  9. python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie)

    python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie) 主要包括两部分内容:(1)利用python中的dict实现Trie:(2) ...

  10. Spring boot 入门篇

    详见:https://www.cnblogs.com/ityouknow/p/5662753.html 什么是Spring Boot Spring Boot 是由 Pivotal 团队提供的全新框架, ...