下载安装
你可以选择引入开发环境版本还是生产环境版本
<!--开发环境版本,包含了有帮助的命令行警告-->
<script src="https://cdn. jsdelivr . net/npm/vue/dist/vue。js"></script>
<!--生产环境版本,优化了尺寸和速度-->
<script src="https://cdn. jsdelivr . net/npm/vue"></script>
方式二:下载和引入
开发环境https://vuejs . org/js/vue.js
生产环境https://vuejs . org/is/vue .min.js
方式三: NPM安装
■后续通过webpack和CL的使用,我们使用该方式。
<div id="app">
<h2>Hello {
{
name}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
name: 'VueJS'
}
})
</script>
浏览器显示为: Hello VueJS
这些数据可以是我们直接定义出来的.比如像上而这样。
也可能是來自网络.从服务器加载的。
执行到10~13行代码显然出对应的HTML
执行第16行代码创建Vue实例,并且对原HTML进行解析和修改。
<div id= app">
<ul>
<li v-for="item in movies">
{
{
item}}
</Li>
</ul>
</div>
<script srce"../js/vue. js"sc/script>
<script>
let app = new Vue( {
el:'#app' ,
data:{
movies: [' 星际穿越','盗梦空间','大话西游 ']
}
</script>
比如我们现在从服务器请求过来一个列表
希望展示到HTML中。
该指令我们后面会详细讲解,这里先学会使用。
<div id="app">
<h2>当前计数: {
{
counter}}</h2>
<button @cLick="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue .js"></script>
<script>
Let app = new Vue( {
el: ' #app',
data: {
counter : 0
},
methods:{
increment() {
this.counter++
},
decrement() {
this.counter--
}
]
})
</script>
点击+计数器+1
点击-计数器-1
- 新的属性: methods ,该属性用于在Vue对象中定义方法。
- 新的指令: @click,该指令用于监听某个元素的点击事件,并且需要指定当发生点击时,执行的方法(方法通常是methods中定义的方法)
- 这些@click是什么东西?
- Vue对象中又是定义el/data/methods ,到底都有哪些东西可以定义,以及它们的作用是什么?
- 这些疑惑在后续学习中都会一-解开。
通常我们学习-一个概念,最好的方式是去看维基百科(对.千万别看成了百度百科)
https://zh.wikipedia.org/wiki/MVVM
维基百科的官方解释我们这里不再整述。
详细解析: https://cn.vuejs.org/v2/api/#optionMergeStrategies
el:
类型: string | HTMLElement
作用:决定之后Vue实例会管理哪一个DOM.
data:
类型: Object | Function (组件当中data必须是一一个函数)
作用: Vue实例对应的数据对象。
methods:
类型: { [key: string]: Function }
作用:定义属于Vue的一些方法 ,可以在其他地方调用,也可以在指令中使用,
开发中什么时候称之为方法,什么时候称之为函数?
● 方法: method
● 函数: function
Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、运行中、销毁。
实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…
当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
组件的数据绑定、监听…去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以
我们已经学习过了,可以通过Mustache语法(也就是双大括号 { {}} )。
Mustache:胡子/胡须.
这个时候,我们就可以使用一个Vue的指令
该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
该指令表示元素和组件(组件后面才会学习)只渲染-次,不会随着数据的改变而改变。
<body>
<div id="app">
<h2>{
{
message}}</h2>
<h2 v-once >{
{
message}}</h2>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
message:"hello word"
}
})
</script>
</body>
message 改变,界面并没有重新渲染
如果我们直接通过{ {}}来输出,会将HTML代码也一起输出。
但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。
<body>
<div id="app">
<h1>{
{
url}}</h1>
<h2 v-html = "url"></h2>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
url:'百度一下'
}
})
</script>
</body>
v-text作用和Mustache比较相似:都是用于将数据显示在界面中
v-text通常情况下,接受一个string类型
代码部分
<body>
<div id="app">
<h1>{
{
message}}</h1>
<h2 v-text="message"></h2>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
message:'你好啊'
}
})
</script>
</body>
<body>
<div id="app">
<h1>{
{
message}}</h1>
<h1 v-pre>{
{
message}}</h1>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
message:"你好啊"
}
})
</script>
</body>
<style>
[v-cloak]{
display:none;
}
</style>
<div id="app">
<h2 v-cloak>Hello {
{
name}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
set Timeout(() => {
Letapp=new Vue({
eL:' #app',
data: {
name: 'VueJS'
})
},10000 )
</script>
比如动态绑定a元素的href属性
比如动态绑定img元素的src属性
作用:动态绑定属性
缩写: : (冒号)
预期: any (with argument) | Objpct (without argument)
参数: attrOrProp (optional)
<div i1d= app">
<a V-bind:href="link">Vuejs官网</a>
<img v-bind:src="logoURL" alt=">
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue( {
el:'#app'
data: {
logouRL: ' https://vuejs.org/ inages/ logo.png',
link: 'https://vuejs.org/'
}
}]
</script>
在开发中,我们通常会使用语法糖的形式,因为这样更加简洁。
<div id="app">
<a :href="link">Vuejs官网</a>
<img :src="logoURL" alt="">
</div>
当数据为某个状态时,字体显示红色。
当数据另一个状态时,字体显示黑色。
对象语法的含义是:class后面跟的是一个对象。
用法一:直接通过{}绑定一个类
<h2 :class="{'active': isActive}">Hello World</h2>
用法二:也可以通过判断,传入多个值
<h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法三:和普通的类同时存在,并不冲突
注:如果isActive和isline都为true, 那么会有title/active/line三个类
<h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法四:如果过于复杂,可以放在一个methods或者computed中
注: classes是一个计算属性
<h2 class="title" :class="classes">Hello World</h2>
<style type="text/css">
.active {
color: red;
}
.line{
color: blue;
}
style>
<body>
<div id="app">
{
{message}}h2>
<button type="button" @click="btn()">单击改变颜色button>
div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
message:'你好啊!',
active:'active',
num:true
} ,
methods:{
btn:function(){
this.num = !this.num
console.log(this.num) }
}
}
})
script>
body>
<style type="text/css">
.active {
color: red;
}
.line{
color: blue;
}
style>
<body>
<div id="app">
{
{message}}h2>
<button type="button" @click="btn()">单击改变颜色button>
div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
message:'你好啊!',
active:'active',
num:true
},
methods:{
btn:function(){
this.num = !this.num
console.log(this.num)
},
getClass:function(){
return {
active:this.num , line:!this.num}
// 不要忘记加 this
}
}
})
script>
body>
数组语法的含义是:class后面跟的是一个数组。
在 [ ] 里 如果想表示字符串的话可以添加 双引号 (’ ') ,如果不加表示 变量
用法一:直接通过{}绑定一个类
<h2 :class="['active']">Hello World</h2>
用法二:也可以传入多个值
<h2 :class="['active','line']">Hello World</h2>
用法三:和普通的类同时存在,并不冲突
注:会有title/active/line三个类
<h2 class="title" :class="['active','line']">Hello World</h2>
用法四:如果过于复杂,可以放在一个methods或者computed中
注: classes是一个计算属性
<h2 class="title" :class="classes">Hello World</h2>
<style type="text/css">
.active {
color: red;
}
.line{
color: blue;
}
style>
<body>
<div id="app">
<h2 :class="['active',line]">{
{message}}h2>
<h2 :class="getClass()">{
{message}}h2>
div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
message:'你好啊!',
active:'active',
line: 'line',
num:true
} ,
methods:{
getClass:function(){
return {
active:this.active , line:this.line}
// 不要忘记加 this
}
}
})
script>
body>
我们可以利用v-bind:style来绑定一些CSS内联样式。
在写CSS属性名的时候,比如font-size
- 我们可以使用驼峰式(camelCase) fontSize
- 或短横线分隔(kebab-case ,记得用单引号括起来) 'font-size’
绑定class有两种方式:
- 对象语法
- 数组语法
:style = "{color:currentColor,fontSize:fontsize+''px}"
// {
{message}}
style后面跟的是一个对象类型
对象的key 是css属性名称
对象的value 是具体赋的值,值可以来自于data中的属性
代码展示
<body>
<div id="app">
<h2 :style="{
fontsiz:'50px'}">{
{message}}h2>
<h2 :style="{
fontsiz:finaLsize+'px',backgroundColor:finaLcolor}">{
{message}}h2>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: '你好啊',
finaLsize: '100',
finaLcolor: 'red',
}
})
script>
body>
<div v-bing:style = "[baseStyle,overridingstyles]" ></div>
style 后面跟的值是一个数组类型
多个值以,(逗号)分割即可
代码展示
<body>
<div id="app">
<h2 :style="[ baseStyle, bassStyle1,Color1]">{
{message}}h2>
div>
<script>
var app = new Vue({
el: '#app',
data: {
message: '你好啊',
baseStyle: {
backgroundColor: 'red'
},
bassStyle1: {
fontSize: '100px'
},
Color1: {
color: 'pink'
}
}
})
script>
body>
我们知道,在模板中可以直通过插值语法表示一些data中的数据。
但是在某些情况,我们可能需要通过对数据进行一些转化后在显示,或者需要将多个数据结合起来进行显示
- 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
- 但是如果多个地方都需要显示完整的名称,我们需要写多个{ {firstName}}{ {lastName}}
我们可以将上面的代码换成计算属性:
- ok,我们发现计算属性是写在实例的computed选项中的。
<body>
<div id="app">
<h2>{
{firstName+''+lastName}}h2>
<h2>{
{firstName}}{
{lastName}}h2>
<h2>{
{getFullName()}}h2>
<h2>{
{fullName }}h2>
div>
<script>
var app = new Vue({
el: '#app',
data: {
firstName: '123',
lastName: '456'
},
computed: {
fullName: function() {
return this.firstName + '' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + '' + this.lastName
}
}
})
script>
body>
<body>
<div id="app">
<h2>总价格:{
{toTalprice}}h2>
div>
<script>
const app = new Vue({
el: '#app',
data: {
books: [{
id: 110,
name: '编程艺术',
price: 140
}, {
id: 111,
name: '编程艺术',
price: 100
}, {
id: 112,
name: '编程艺术',
price: 120
}, {
id: 113,
name: '编程艺术',
price: 130
}]
},
computed: {
toTalprice() {
let result = 0
for (let i = 0; i < this.books.length; i++) {
result += this.books[i].price
}
return result
}
}
})
script>
body>
每个计算属性都包含一个getter和一个setter
- 在上面的案例中,我们只是使用了getter来读取。
- 在某些情况下,你也可以提供一个setter方法(不常用)。
- 在需要写setter 的时候,代码如下
<body>
<div id="app">
<h2>{
{firstName}}h2>
<h2>{
{lastName}}h2>
<h2>{
{fullName}}h2>
div>
<script>
var app = new Vue({
el: '#app',
data: {
firstName: '123',
lastName: '456'
},
computed: {
fullName: {
get() {
console.log("调用了 get");
return this.firstName + '' + this.lastName
},
set() {
console.log("调用了set");
const names = newValue.split(' ')
this.firstName = names[0]
this.lasttName = names[1]
}
}
}
})
script>
body>
原因: 计算属性(computed)会进行缓存,如果多次使用时,计算属性只会调用一次,但methods 使用一次就调用一次,所以从性能上来看使用 计算属性(computed)比较推荐
事实上var的设计可以看成JavaScript语言设计上的错误.但是这种错误多半不能修复和移除,以为需要向后兼容.
- 大概十年前,Brendan Eich就决定修复这个问题,于是他添加了一个新的关键字: let.
- 我们可以将let看成更完美的var
块级作用域
- JS中使用var来声明一个变量时,变量的作用域主要是和函数的定义有关.
- 针对于其他块定义来说是没有作用域的,比如if/for等,这在我们开发中往往会引起一些问题。
- ES5之前因为if和for都没有块级作用域的概念,所以在很多时候,我们必须借助function的作用域来解决应用外面变量的问题。
所以ES5中的var是没有块级作用域
//监听按钮的点击
var btns = document,getElementsByTagName('button');
for(var i = 0;i<btns.length;i++){
(function(i){
btns[i].onclick = function (){
alert('点击'+i+'个')
}
})(i)
}
- ES6中,加入了let,let它是有if和for的块级作用域
ES6中的let 是由块级作用域的(if/for)
let btns = document,getElementsByTagName('button');
for(let i = 0;i<btns.length;i++){
btns[i].onclick = function() {
alert('点击'+i+'个')
}
}
const关键字
- 在很多语言中已经存在,比如C/C+ +中,主要的作用是将某个变量修饰为常量
- 在JavaScript中也是如此,使用const修饰的标识符为常量,不可以再次赋值.
什么时候使用const呢?
- 当我们修饰的标识符不会被再次赋值时,就可以使用const来保证数据的安全性.
建议:在ES6开发中,优先使用const,只有需要改变某-一个标识符的时候才使用let.
const的注意点
1.const注意一:
const a = 20;
a = 30; //错误:不可以修改。
2.const注意二:
const name; //错误: const修饰的标识符必须赋值.
ES6中,对对象字面量进行了很多增强。
属性初始化简写和方法的简写:
//ES6之前
let name = 'why'
let age = 18
let obj1 = {
name:name,
age:age
}
console.log(obj1);
// ES6之后
let obj2 = {
name,age
}
consle.log(obj2)
//ES6之前
let obj1 = {
test:funtion () {
console.log('obj1的 test函数')
}
}
obj1.test();
// ES6之后
let obj2 = {
test() {
console.log('obj2的 test函数')
}
}
obj2.test();
在前端开发中,我们需要经常和用于交互。
v-on介绍
这里,我们用一个监听按钮的点击事件,来简单看看v-on的使用
<div 1d="app">
<h2>点击次数: {
{ounter}}h2>
<button v-on:click="counter++">按钮点击1< /button>
<button v-on:click="btnClick">按钮点击2 /button>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
counter:0
},
methods:{
btnClick(){
this.counter++
}
}
})
script>
<div 1d="app">
<h2>点击次数: {
{ounter}}h2>
<button @click="counter++">按钮点击1button>
<button @click="btnClick">按钮点击2 /button>
div>
代码展示
<body>
<div id="app">
<span v-if="isUser">
<lable for="username">用户账号:lable>
<input placeholder="用户账号" id="username" type="text">
span>
<span v-else>
<lable for="email">邮箱地址:lable>
<input placeholder="邮箱地址" id="email" type="text">
span>
<button @click="isUser = !isUser">切换类型button>
div>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
},
})
script>
body>
小问题:
- 如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入内容
- 但是按道理讲,我们应该切换到另一个input元素中了。
- 在另一个input元素中,我们并没有输入内容。
- 为什么会出现这个问题
问题解答:
- 这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
- 在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。
解决方案
- 如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key
- 并且我们需要保证key的不同
看上面代码注释部分
v-show的用法和v-if非常相似,也用于决定一个元素是否渲染
v-if 和 v-show 对比
v-if 和 v-show 都可以决定一个元素是否渲染,那么开发中我们如何选择呢?
- v-if 当条件为false时,压根不会有对应的元素在DOM中。
- v-show 当条件为false时,仅仅是将元素的display属性设置为none而已。
开发中如何选择呢?- 当需要在现实与隐藏之间切片很频繁时。使用v-show
- 当只有一次切换时,通过使用 v-if
<body>
<div id="app">
<button @click="isShow = !isShow">切换显示button>
<h2 v-show="isShow">不要显示h2>
div>
<script>
const app = new Vue({
el: "#app",
data: {
isShow: true,
}
})
script>
body>
当我们有一组数组需要进行渲染时,我们就可以使用v-for来完成
- v-for 语法类似于javascript中的for循环
- 格式如下: item in items 的格式
我们来看一个简单的案例
如果在遍历的过程中不需要使用索引值
- v-for = “movie in movies”
- 依次从movies取出movie,并且在元素的内容中,我们可以使用Mustache 语法,来使用movie
如果在遍历的过程中,我们需要拿到元素在数组中的索引值呢?
- 语法格式:v-for = (item ,index )in items
- 其中的index就代表了取出的item在原数组的索引值。
v-for 可以用户遍历对象:
比如某个对象中储存着你的个人信息,我们希望以列表的形式显示出来
<div id="app">
<ul>
<li v-for="(item,key,index) in info">
{
{
item}}-{
{
key}}-{
{
index}}
</li>
</ul>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'yjz',
age: 20,
height: 178
}
}
})
</script>
官方推荐我们在使用v-for时,给对应的元素,或者组件添加上一个:key属性。
为什么需要这个key属性呢(了解)
当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点
所以我们需要使用key 来个每个节点做一个唯一标识
所以一句换,key的作用主要是为了高效的更新虚拟DOM
<body>
<div id="app">
<ul>
<li v-for="item in letters" :key='item'>{
{
item}}</li>
</ul>
<button @click='add()'>添加一个F</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'D', 'E']
},
methods: {
add() {
this.letters.splice(2, 0, 'F')
}
}
})
</script>
</body>
因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新
Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
this.names.push('元素1','元素2');
pop() 方法用于删除并返回数组的最后一个元素。
this.names.pop();
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
this.names.shift()
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
this.names.unshift('元素1','元素2');
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
arrayObject.splice(index,howmany,item1,.....,itemX)
index: 元素位置
howmany : 要操作几个元素
item1…itemx : 替换进去的元素
第二个参数传入你要删除的几个元素(如果没有传,就删除后面所有的元素)
this.names.splice(1,3) //删除第1个元素 之后的三个元素
this.names.splice(1) //删除第1个元素 之后的所有元素
第二个参数,传入0,并且后面跟上要插入的元素
this.names.splice(1,0,'a','b','c')
第二个参数,表示我们要替换几个元素,后面是用于替换前面的元素
this.names.splice(1,3,'a','b','c') // 把第1个元素后面的三个元素 替换掉
sort() 方法用于对数组的元素进行排序。
this.names.sotr() //括号里可以写函数
reverse() 方法用于颠倒数组中元素的顺序。
this.names.revers();
<body>
<div id="app">
<ul>
<li v-for="item in names">{
{item}}li>
ul>
<button @click="btnClick()">点击改变数组button>
div>
<script>
const app = new Vue({
el: "#app",
data: {
names: ['张三', '李四', '王五']
},
methods: {
btnClick() {
this.names[2] = '隔壁老王'
console.log("数组以改变");
console.log(this.names);
}
}
})
script>
body>
虽然数组元素已经发生了变化,但是页面没有刷新
想要修改数组中的一个元素 可以使用splice() 方法 进行替换
或者使用 set() 方法
// set(要修改的对象,索引值,修改后的值)
Vue.set(this.names,3,'隔壁老王')
要实现的效果
代码部分
在Vue中filter过滤器是一个非常强大的功能。
个人觉得称它为加工车间会更加贴切一些。
过滤器可以用来筛选出符合条件的,丢弃不符合条件的;
加工车间既可以筛选,又可以对筛选出来的进行加工。
一、 filter的作用是:对值进行筛选加工。
二、使用的地方有两个位置,和两个方式。
{ { msg | filterA }}
双括号插值内。
v-bind绑定的值的地方。{ { msg }}
(msg为需要filter处理的值,filterA为过滤器。)
方式
{ { msg | filterA }}
单个使用。
{ { msg | filterA| filterB }}
多个连用。
三、过滤器的制作方法:
new Vue({
filters:{
//过滤器一:(使用时没有参数,即{
{msg|filterA}})
filterA(value){
return "¥"+value
}
}
})
//添加filters属性,该属性内的函数就是过滤器。其中value就是{
{msg|filterA}}中的msg。
new Vue({
filters:{
//过滤器二:(使用时有参数,即{
{ msg | filterA( arg1, arg2, arg3.... )}})
filterA (value , ...args){
//其中msg为filterA中的第一个参数value。
for(arg in args{
console.log(arg)
value+=arg
}
return value
}
},
filterB (value , ...args){
for(arg in args{
console.log(arg)
value+=arg
}
return value
}
}
})
(使用时有参数,即{
{
msg | filterA( arg1, arg2, arg3.... ) | filterB( arg1, arg2, arg3.... )}})
此时msg为filterA的第一个参数,filterA执行完后的返回值为filterB的第一个参数,以后也是依次类推。
转自 有一个王小森
map()函数根据一个回调函数创建一个新的函数,它会遍历数组中的每一个值
比如说
var arr1 = [1,3,5,6,8,19]
const map1 = arr1.map(function(singleEl){
return singleEl*2;
})
console.log(map1)
//返回的map1函数数组为[1,6,10,12,16,38]
回调函数可用的参数
var new_array = arr.map(function callback(currentValue[,index[,array]]){
//返回数组中的单个元素
},thisArg)
callback: 生成新数组的函数,其中有三个参数:
currentValue: 回调中正在处理的当前元素
index (可选): 回调中处理的当前元素在源数组中的索引
array (可选): 源数组
thisArg: 回调中使用的this值。
reduce()函数会对参数序列中的元素进行累积,操作如下:用传给reduce的函数function(有两个参数)先对集合中前两个元素进行操作,得到的结果再与第三个数据用function函数运算,最后得到一个结果。
arr.reduce(callback,[initialValue])
callback (执行数组中每个值的函数,包含四个参数)
initialValue (作为第一次调用 callback 的第一个参数。)
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
计算数组中每个元素出现的次数
第一种写法
const str = 'jshdjsihh';
const obj = str.split('').reduce((pre,item) => {
console.log(pre)
console.log("itm:" + item)
console.log(pre + "[" + item + "]" + ":" + pre[item])
pre[item] ? pre[item] ++ : pre[item] = 1
return pre
},{
})
console.log(obj) // {j: 2, s: 2, h: 3, d: 1, i: 1}
①设置了初始值,所以pre初始为{}
②item为数组(即字符串)第一项 j
③pre[item] 记录每个元素出现的次数,第一次使用时无定义,输出为undefind,执行pre[item]=1;当元素第二次出现,pre[item]在该元素第一次出现时记录为,1所以执行 ++,变为2;以此类推
第二种写法
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{
})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
作者:Tammie_a56e
链接:https://www.jianshu.com/p/2d7daa223ea8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
// 编程范式: 命令式编程/声明式编程
// 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)
// filter/map/reduce
// filter中的回调函数有一个要求: 必须返回一个boolean值
// true: 当返回true时, 函数内部会自动将这次回调的n加入到新的数组中
// false: 当返回false时, 函数内部会过滤掉这次的n
const nums = [10, 20, 111, 222, 444, 40, 50]
// let total = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n) => pre + n);
// console.log(total);
let total = nums.filter(function (n) {
return n < 100
}).map(function (n) {
return n * 2
}).reduce(function (prevValue, n) {
return prevValue + n
}, 0)
console.log(total);
// 1.filter函数的使用
// // 10, 20, 40, 50
// let newNums = nums.filter(function (n) {
// return n < 100
// })
// // console.log(newNums);
//
// // 2.map函数的使用
// // 20, 40, 80, 100
// let new2Nums = newNums.map(function (n) { // 20
// return n * 2
// })
// console.log(new2Nums);
//
// // 3.reduce函数的使用
// // reduce作用对数组中所有的内容进行汇总
// let total = new2Nums.reduce(function (preValue, n) {
// return preValue + n
// }, 0)
// console.log(total);
// 第一次: preValue 0 n 20
// 第二次: preValue 20 n 40
// 第二次: preValue 60 n 80
// 第二次: preValue 140 n 100
// 240
// // 1.需求: 取出所有小于100的数字
// let newNums = []
// for (let n of nums) {
// if (n < 100) {
// newNums.push(n)
// }
// }
//
// // 2.需求:将所有小于100的数字进行转化: 全部*2
// let new2Nums = []
// for (let n of newNums) {
// new2Nums.push(n * 2)
// }
//
// console.log(new2Nums);
//
//
// // 3.需求:将所有new2Nums数字相加,得到最终的记过
// let total = 0
// for (let n of new2Nums) {
// total += n
// }
//
// console.log(total);
44
Vue中使用v-model 指令来实现表单元素和数据的双向绑定
如下代码:
<body>
<div id="app">
<input type="text" v-model='message'>
<h2>你输入了:{
{message}}h2>
div>
<script>
const app = new Vue({
el: '#app',
data: {
message: ''
}
})
script>
body>
解析:
当我们输入内容时
- 因为input中 v-model 绑定了message,所以会实时将输入的内容传递给message ,message发生改变
- 当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应式的改变。
- 所以通过v-model 实现了双向的绑定
当然 , 我们也可以将v-model用于textarea 元素
<textarea v-model='message'></textarea>
<h2>你输入了:{
{
message}}</h2>
v-model 其实是一个语法糖,它的背后本质上是包含两个操作:
- v-model 绑定一个 value 属性
- v-on 指令给当前元素绑定input 事件
也就是说下面的代码:等同于下面的代码
- 等同于
当存在多个单选框时
<body>
<div id="app">
<lable for="male">
<input type="radio" name="sex" value="男" v-model='sex'>男
lable>
<lable for="female">
<input type="radio" name="sex" value="女" v-model='sex'>女
lable>
<h2>你选择了:{
{sex}}h2>
div>
<script>
const app = new Vue({
el: '#app',
data: {
sex: '男'
// 这里可以作为默认值 ,打开时就选择
}
})
script>
body>
小技巧:
当input 使用数据绑定的时候 ,可以不用写 name 属性
复选框存在两中情况:单个勾选框和多个勾选框
当使用单勾选框 的时候,可以使用布尔值进行判断
<body>
<div id="app">
<lable for="agree">
<input type="checkbox" id="agree" v-model='toAgree'>同意协议
lable>
<h2>你选择了:{
{toAgree}}h2>
<button :disabled="!toAgree" @click="setclick()">下一步button>
div>
<script>
const app = new Vue({
el: '#app',
data: {
toAgree: false
},
methods: {
setclick() {
console.log('点了一下')
}
}
})
script>
body>
当时使用多个 复勾选框 的时候 ,使用数组来接受数据
<body>
<div id="app">
<input type="checkbox" name="" id="" v-model="hobbies" value="篮球">篮球
<input type="checkbox" name="" id="" v-model="hobbies" value="乒乓球">乒乓球
<input type="checkbox" name="" id="" v-model="hobbies" value="足球">足球
<input type="checkbox" name="" id="" v-model="hobbies" value="羽毛球">羽毛球
<h2>你选择了:{
{hobbies}}h2>
div>
<script>
const app = new Vue({
el: '#app',
data: {
hobbies: []
}
})
script>
body>
和checkbox一样,selcet也分单选和多选两种情况
单选:只能选择一个值
多选:可以选中多个值
动态的给value赋值而已
- 在之前的代码中的value值的时候,都是直接在定义input的时候直接给定的。
- 但是真实开发中,这些input的值可能是从网络获取或者定义在data中的。
- 所以我们可以通过 v-bind:value动态的给value绑定值
- 这不就是v-bind吗?
所以我们可以通过 v-for 进行label 和input 的循环输出 ,并且给input绑定值
<body>
<div id="app">
<label v-for="item in Hobbies" :for='item'>
<input type="checkbox" :value="item" :id="item" v-model="toHobbies">{
{item}}
label>
<h2>你选择了:{
{toHobbies}}h2>
div>
<script>
let app = new Vue({
el: "#app",
data: {
Hobbies: [ //服务器给的数据
'足球',
'篮球',
'乒乓球',
'羽毛球',
'乐高'
],
toHobbies: [] //被选中的数据
}
})
script>
body>
默认情况下,v-model默认是在input事件中同步输入框的数据的。
也就是说,一旦数据发生改变对应的data中的数据就会自动发生改变。
lazy 修饰符可以让input(数据)在失去焦点或者回车时才会更新:
<div id="app">
<p>当前内容:{
{message}}p>
div>
默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当前字符串类型进行处理
但是如果我们希望处理的是数字类型,那么最好直接将内容当做数子类型处理
number修饰符可以让输入框中输入的内容自动转成数字类型:
<div id="app">
年龄:
<p>年龄:{
{age}} 类型:{
{typeof age}}p>
div>
如果输入的内容首尾有很多空格,通常我们希望将其去除
trim 修饰符可以过滤内容左右两边的空格
<div id="app">
<p>当前内容:------{
{message}}------p>
div>