kechenhh's blog kechenhh's blog
首页
  • 前端文章

    • JavaScript
    • Vue
  • Node.js
  • SQL
  • python
  • HTML
  • CSS
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 友情链接
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

kechenhh

前端CV工程师
首页
  • 前端文章

    • JavaScript
    • Vue
  • Node.js
  • SQL
  • python
  • HTML
  • CSS
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 友情链接
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript文章

  • Vue文章

    • vueAPI
      • 教程
      • Vue实例传入的options
      • 什么是MVVM?
      • 计算属性
      • Mustache语法-插值操作(双大括号)
      • 插值操作-其它指令
        • v-once
        • v-html
        • v-text
        • v-pre
        • v-cloak
      • v-bind:属性/:属性 动态绑定属性
        • v-bind动态绑定class(对象语法)
        • v-bind动态绑定style(对象语法)
      • v-on:click/@click 监听点击事件
        • 案列:计数器
        • v-on的参数传递
        • v-on的修饰符
      • v-if和v-else-if和v-else使用
        • 小案例:切换登录方式
        • 案例input的问题
      • v-for 列表展示
        • 遍历数组
        • 遍历对象
        • 数组中哪些方法是响应式的?
        • 案例:列表选中激活
      • v-model表单绑定
        • input类型
        • radio类型
        • checkbox类型
        • select类型
        • v-model修饰符
      • 组件化开发
        • 基本使用
        • 全局组件和局部组件
        • 父组件和子组件
        • 组件的语法糖注册方式
        • 组件中的data必须是函数
        • 组件通信----父传子(props)
        • props中的驼峰标识
        • 组件通信---子传父(自定义事件名称)
        • 父子组件通信-结合双向绑定案例
        • 组件访问--父访问子
        • 组件访问--子访问父
      • 组件化高级
        • slot插槽的基本使用
        • slot具名插槽
        • 什么是编译的作用域
        • 作用域插槽
      • Vue Mixins(混入)
      • 生命周期函数
      • 前端模块化
        • ES6的模块化实现
      • Webpack
        • 安装
        • Loader
      • 脚手架创建Vue项目
      • 引入组件
      • vue-resource 请求数据
      • axios 请求数据
        • 解决vue动态绑定audio/video的src不能播放
      • 非父子组件
      • 双向绑定原理
      • 自定义指令
      • 核心业务
      • Vue优化
      • 解除严格模式
    • vue-cli(脚手架)创建Vue项目
    • Vuex学习
    • vue路由
    • vue的插槽
    • Vue CLi3 修改webpack配置
    • Vue中的scoped和scoped穿透
    • Vue项目使用mock数据的几种方式
  • 前端
  • Vue文章
kechenhh
2021-07-13
目录

vueAPI

# 教程

2019Vue、Vuejs最详细教程-入门到项目实战 (opens new window)

官方文档 (opens new window)

# Vue实例传入的options

	<script type="text/javascript">
		const app = new Vue({
			el:'#app',//确定管理的DOM(string/HTMLElement)
 			//组件中,data必须是个函数
			data:{
				//存放数据(Object/Function)
                message:'Hello Vue',
				arr : ['生活','心情','日记','天空']
			},
             methods:{
                     //定义的方法
                 add:function(){},
            	 sub:function(){},
             },
             //计算属性
			computed:{
				fullName:function(){
					return this.firstName + ' ' + this.lastName
			},
             //注册组件
            components:{
				cpn
			},
            //生命周期
             created:function(){},
             mounted:function(){}
             
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 什么是MVVM?

■view层: 视图层

在我们前端开发中,通常就是DOM层

主要的作用是给用户展示各种信息

■Mode层:数据层 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。

在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。

■ VueModel层:视图模型层 视图模型层是vew和Mode沟通的桥梁。

一方面它实现了 Data Binding,也就是数据绑定,将Mode的改变实时的反应到vew中

另一方面它实现了 DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。

# 计算属性

简单用法:

<div id="app">
	<h2>{{firstName}} {{lastName}}</h2>
    <!--传入的是对象,不加小括号-->
	<h2>{{fullName}}</h2>
</div>

<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	const app = new Vue({
		el:'#app',
		data:{
			message:'你好Vue',
			firstName:'Lebron',
			lastName:'James'
		},
		//计算属性
		computed:{
			fullName:function(){
				return this.firstName + ' ' + this.lastName
			}
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

复杂用法:

<div id="app">
	总价格:{{totalPrice}}
</div>

<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	const app = new Vue({
		el:'#app',
		data:{
			message:'你好Vue',
			books:[
				{id:110,name:'西游记',price:15},
				{id:111,name:'水浒传',price:47},
				{id:112,name:'红楼梦',price:45},
				{id:113,name:'三国演义',price:26},
			]
		},
		computed:{
			totalPrice:function(){
				let result = 0
				
				// for (let i=0; i<this.books.length; i++){
				// 	result += this.books[i].price
				// }
				
				//es6语法
				// for (let i in this.books){
				// 	result += this.books[i].price
				// }
				
				for (let book of this.books){
					result += book.price
				}
				
				return result

			}
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

计算属性的setter和getter:

		//计算属性一般是没有set方法,只读属性
		computed:{
			
			// fullName:{
			// 	get:function(){
			// 		return this.firstName + ' ' + this.lastName
			// 	}
			// }
			
			//下面是简写
			fullName:function(){
				return this.firstName + ' ' + this.lastName
			}
		}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

计算属性和 methods的对比:

  • methods和 computed看起来都可以实现我们的功能,
  • 那么为什么还要多一个计算属性这个东西呢?
  • 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次

# Mustache语法-插值操作(双大括号)

Mustache:胡子/胡须

	<div id="app">
		<h2>{{message}}</h2>
		<h2>{{name_one}} {{name_two}}</h2>
		<h2>{{name_one + ' ' + name_two}}</h2>
		<h2>{{counter *2}}</h2>  //200
	</div>
		
	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				name_one:'jack',
				name_two:'john',
				counter:100
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 插值操作-其它指令

# v-once

只渲染一次,不随数据改变

	<div id="app">
		<h2>{{message}}</h2>
		<h2 v-once>{{message}}</h2> <!--只渲染一次,不随数据改变 -->
	</div>
1
2
3
4

# v-html

可以渲染html代码

	<!-- 可以渲染html代码-->
	<div id="app">
		<h2>{{url}}</h2>	<!-- <a href="http://www.baidu.com">百度一下</a> -->
		<h2 v-html="url"></h2>	<!-- 百度一下 -->
	</div>
	
	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				url:'<a href="http://www.baidu.com">百度一下</a>'
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# v-text

与mustache语法类似

	<!-- 与mustache语法类似 -->	
	<div id="app">
		<h2>{{message}}</h2>	<!-- 你好Vue -->
		<h2 v-text="message"></h2>	<!-- 你好Vue -->
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# v-pre

不解析mustache语法,原样输出

	<!--不解析mustache语法-->	
	<div id="app">
		<h2>{{message}}</h2>	<!-- 你好Vue -->
		<h2 v-pre>{{message}}</h2>	<!-- {{message}} -->
	</div>
	
	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# v-cloak

cloak:斗篷

在vue解析之前,div中有一个属性 v-cloak 在vue解析之后,属性v-cloak消失

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
            /* 设置隐藏 */
			[v-cloak]{
				display: none;
			}
		</style>
	</head>
	<body>
		
	<div id="app" v-cloak>
		<h2>{{message}}</h2> 
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		//在vue解析之前,div中有一个属性v-cloak
		//在vue解析之后,div中没有一个属性v-cloak
		setTimeout(function(){
			const app = new Vue({
				el:'#app',
				data:{
					message:'你好Vue'
				}
			})
		},2000)
	</script>
	</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# v-bind:属性/:属性 动态绑定属性

基本使用:

	<div id="app">
	<!--<img v-bind:src="imgurl">
		<a v-bind:href="aUrl">百度一下</a> -->
		
		<img :src="imgurl">
		<a :href="aUrl">百度一下</a>
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				imgurl:'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7c5524bbd8d8e2d8b4fec3774915d2fb.jpg',
				aUrl:'http://ww.baidu.com'
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# v-bind动态绑定class(对象语法)

<div id="app">
		<!-- class中传入对象 -->
		<!-- <h2 :class="{类名1:true,类名2:false}">{{message}}<h2> -->
		<h2 :class="{active:isActive,line:isLine}">{{message}}<h2>
		
		<!-- 传入方法 -->
		<h2 :class="getClasses()">{{message}}<h2>
		
		<button @click="btnClick">切换</button>
		
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				isActive:false,
				isLine:true
			},
			methods:{
				btnClick:function(){
					this.isActive = !this.isActive
				},
				getClasses:function(){
					return {active:this.isActive,line:this.isLine}
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# v-bind动态绑定style(对象语法)

<div id="app">
	<!-- <h2 :style="{key(属性名):value(属性值)}">{{message}}</h2> -->
	
	<!-- '50px'表示字符串,50px会被解析成变量 -->
	<!-- <h2 :style="{fontSize:'50px'}">{{message}}</h2> -->
	
	<h2 :style="{fontSize:finalSizeA}">{{message}}</h2>
	<h2 :style="{fontSize:finalSizeB + 'px', color:finalColor}" >{{message}}</h2>
</div>

<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	const app = new Vue({
		el:'#app',
		data:{
			message:'你好Vue',
			finalSizeA:'50px',
			finalSizeB:50,
			finalColor:'red'
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# v-on:click/@click 监听点击事件

# 案列:计数器

	<div id="app">
		<h2>当前计数{{counter}}</h2>
	<!--<button type="button" v-on:click="counter++">+</button>
		<button type="button" v-on:click="counter--">-</button> -->
		
		<button type="button" v-on:click="add">+</button>
		<button type="button" @click="sub">-</button>
		
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				counter:0
			},
			methods:{
				add:function(){
					console.log('add执行');
					this.counter++ 
				},
				sub:function(){
					console.log('sub被执行');
					this.counter--
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# v-on的参数传递

<div id="app">
		<!-- 事件调用的方法没有参数 -->
		<button @click="btn1Click()">按钮1</button>
		<button @click="btn1Click">按钮2</button> <!-- 没有参数,括号可省略 -->
		
		
		<button @click="btn2Click('jack')">按钮3</button>	<!-- 	---- jack -->
		<button @click="btn2Click()">按钮4</button>	 <!-- 	---- undefined -->
		<button @click="btn2Click">按钮5</button>	 <!-- MouseEvent对象 -->
		
		<!-- 同时需要event对象和其它参数 -->
		<!-- $event--手动获取event对象 -->
		<button @click="btn3Click('jack',$event)">按钮6</button>
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
			},
			methods:{
				btn1Click:function(){
					console.log("btn1Click")
				},
				btn2Click:function(name){
					console.log("----",name)
				},
				btn3Click:function(name,event){
					console.log("----",name,event)
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# v-on的修饰符

  • .stop修饰符,阻止冒泡
  • .prevent修饰符,阻止默认事件
  • @keyup.enter(或者键的编码)监听某个键盘的键帽弹起
  • .once 只能执行一次
<div id="app">
		<!-- .stop修饰符,阻止冒泡 -->
		<div @click="divClick">
		aaaa
		<!-- .stop修饰符,阻止冒泡,只让按钮的方法生效 -->
		<button @click.stop="btnClick">按钮</button>
		</div>
		
		<!-- .prevent修饰符,阻止默认事件 -->
		<form action="baidu" >
			<!-- 阻止自动提交 -->
			<input type="submit" value="提交" @click.prevent="submitClick"/>
		</form>
		
		<!-- @keyup.enter(或者键的编码)监听某个键盘的键帽 -->
		<!-- 监听回车键的弹起 -->
		<input type="text" @keyup.enter="keyUp">
		
		<!-- .once 只能执行一次 -->
		<button type="button" @click.once="btn2Click">一次性按钮</button>
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			methods:{
				btnClick(){
					console.log("btnClick")
				},
				divClick(){
					console.log("divClick")
				},
				submitClick(){
					console.log('submitClick')
				},
				keyUp(){
					console.log('keyUp')
				},
				btn2Click(){
					console.log('btn2Click')
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

#

# v-if和v-else-if和v-else使用

	<div id="app">
		<div v-if="isShow">------这是v-if显示------</div>
		<div v-else>-----这是v-else显示------</div>
		
		<button type="button" @click="isShow = !isShow">切换</button>
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				isShow:true
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 小案例:切换登录方式

	<div id="app">
		<!-- {{message}} -->
		<span v-if="isUser">
			<label for="username">用户账户</label>
			<!-- 加上key,处理DOM复用的问题 -->
			<input type="" name="" id="username" value=""  placeholder="用户账户" key="username"/>
		</span>
		<span v-else>
			<label for="userEmail">用户邮箱</label>
			<input type="" name="" id="userEmail" value=""  placeholder="用户邮箱" key="userEmail"/>
		</span>
		<button type="button" @click="change">切换登录</button>
	</div>
	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const vue = new Vue({
			el:"#app",
			data:{
				message:"你好,Vue",
				isUser:true
			},
			methods:{
				change(){
					return this.isUser = !this.isUser
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 案例input的问题

如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容。

但是按道理讲,我们应该切换到另外一个 input元素中了

在另一个input元素中,我们并没有输入内容

为什么会出现这个问题呢? ■问题解答:

这是因为ue在进行DOM道染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素

在上面的案例中,Vue内部会发现原来的 input元素不再使用,直接作为else中的 input来使用了 ■解决方案 如果我们不希望Vue出现类似重复利用的问题,可以给对应的 input添加key

并且我们需要保证key的不同

# v-for 列表展示

# 遍历数组

	<div id="app">
		<ul>
            <!--将arr数组循环遍历-->
			<li v-for="(item,index) in arr">{{index+1}}----{{item}}</li>
		</ul>
	</div>
		
	<template>

	</template>
		
	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				arr : ['生活','心情','日记','天空']
			}
		})
	</script>
	输出:
    1----生活
    2----心情
    3----日记
    4----天空
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 遍历对象

	<div id="app">
		<!-- 1.在遍历对象的过程中,如果只是获取一个值,那么获取到的是value -->
		<ul>
			<li v-for="item in info" :key="item">{{item}}</li>
		</ul>
		
		<!-- 2.获取key和value   (value,key)-->
		<ul>
			<li v-for="(value,key) in info">{{key}}----{{value}}</li>
		</ul>
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				info :{
					name:'jack',
					age:18,
					height:1.88
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 数组中哪些方法是响应式的?

	<div id="app">
		<ul>
			<li v-for="item in letters" >{{item}}</li>
		</ul>	
		<button type="button" @click="btnClick">按钮</button>	
	</div>

	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				letters:['a','b','c','d']
			},
			methods:{
				btnClick(){
					//通过索引值修改数组中的元素
					// this.letters[0] = 'bbb'
					
					// 1.push方法--末尾添加元素,可以添加多个元素
					// this.letters.push('aaa')
					//this.letters.push('aaa','bbb','ccc')
					
					//2.pop方法----删除末尾的元素
					// this.letters.pop()
					
					// 3.shift方法---删除开头的元素
					// this.letters.shift()
					
					//4.unshift方法---在开头添加
					// this.letters.unshift('aaaa')
					
					//5.splice方法---作用:删除元素/插入元素/替换元素
					//删除元素:第二个参数传入要删除几个元素
					//splice(start,删除个数)
					// this.letters.splice(1,1)
					//替换元素 b,c,d => x,y,z
					// this.letters.splice(1,3,'x','y','z')
					//插入元素:第二个参数,传入0,后面跟上要插入的元素
					//a和b之间插入 m
					// this.letters.splice(1,0,'m')
					
					//6.sort方法---排序
					// this.letters.sort()
					
					//7.reverse方法---反转
					// this.letters.reverse()
					
					//Vue中的set方法--替换
					Vue.set(this.letters,0,'bbbb')
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# 案例:列表选中激活

	<div id="app">
		<ul>
			<li v-for="(book,index) in books" :class="{active:isActive(index)}" @click="liClick(index)">{{index}}--{{book}}</li>
		</ul>
	</div>
	<script src="vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				books:['水浒传','三国演义','红楼梦','西游记'],
				currentIndex:0
			},
			methods:{
				isActive(index){
					return index === this.currentIndex
				},
				liClick(index){
					this.currentIndex = index
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# v-model表单绑定

# input类型

	<div id="app">
		
		<!-- <input type="text" v-model="message"> -->
		<!-- 事件绑定 -->
		<!-- <input type="text" @input="valueChange" :value="message"> -->
		<!-- <input type="text" :value="message" @input="message = $event.target.value"> -->
		
		<h2>{{message}}</h2>
	</div>

	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:''
			},
			methods:{
				valueChange(event){
					this.message = event.target.value;
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# radio类型

<div id="app">
	<label for="male">
        <!-- name相同时,只能选一个,有v-model时 name可以省略 -->
		<input type="radio" id="male" value="男" v-model="sex" name="sex">男
	</label>
	<label for="female">
		<input type="radio" id="female" value="女" v-model="sex" name="sex">女
	</label>
	<h2>选择的性别是:{{sex}}</h2>
</div>

<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	const app = new Vue({
		el:'#app',
		data:{
			message:'你好Vue',
			sex:'男'
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# checkbox类型

	<div id="app">
		<!-- 1.checkbox单选框 -->
		<label for="agree">
			<input type="checkbox" name="" id="agree" value="" v-model="isAgree"/>同意协议
		</label>
		<h2>你选择的是:{{isAgree}}</h2>
		<button type="button" :disabled="!isAgree">下一步</button>
		<br>
		<!-- 2.checkbox多选框 -->
			<input type="checkbox" name="" id="" value="篮球"  v-model="hobbies"/>篮球
			<input type="checkbox" name="" id="" value="足球" v-model="hobbies"/>足球
			<input type="checkbox" name="" id="" value="乒乓球" v-model="hobbies"/>乒乓球
			<input type="checkbox" name="" id="" value="羽毛球" v-model="hobbies"/>羽毛球
			<h2>爱好</h2>
			<ul>
				<li v-for="hobby in hobbies">{{hobby}}</li>
			</ul>
			
			<label v-for="item in originHobbies" :for="item">
				<input type="checkbox"  :id="item" :value="item" v-model="hobbies"/>{{item}}
			</label>
	</div>
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				isAgree:false,//单选框
				hobbies:[],//多选框,
				originHobbies:['篮球','足球','铅球']
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# select类型

<div id="app">
	<!-- 1.选择一个 -->
	<select name="abc" v-model="fruit">
		<option value ="苹果">苹果</option>
		<option value ="香蕉">香蕉</option>
		<option value ="榴莲">榴莲</option>
		<option value ="葡萄">葡萄</option>
	</select>
		<h2>你选择的是:{{fruit}}</h2>
		
		<!-- 1.选择多个-->
		<select name="abc" v-model="fruits" multiple>
			<option value ="苹果">苹果</option>
			<option value ="香蕉">香蕉</option>
			<option value ="榴莲">榴莲</option>
			<option value ="葡萄">葡萄</option>
		</select>
			<h2>你选择的是:{{fruits}}</h2>
</div>
<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	const app = new Vue({
		el:'#app',
		data:{
			message:'你好Vue',
			fruit:'苹果',
			fruits:[]
			
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# v-model修饰符

<div id="app">
	<!-- 1.修饰符: .lazy -->
	<!-- 让数据在失去焦点或者回车时才会更新 -->
	<input type="text" v-model.lazy="message">
	<h2>{{message}}</h2>
	
	<!-- 2.修饰符: .number -->
	<!-- 让在输入框中输入的内容自动转成数字类型 -->
	<input type="number" v-model.number="age">
	<h2>年龄:{{age}}----{{typeof age}}</h2>
	
	<!-- 3.修饰符: trim -->
	<!-- 去除内容两边的空格 -->
	<input type="text" v-model.trim="name">
	<h2>名字:{{name}}</h2>
</div>
<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	const app = new Vue({
		el:'#app',
		data:{
			message:'',
			age:0,
			name:''
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 组件化开发

步骤:

1.创建组件的构造器对象

2.注册组件

3.使用组件

# 基本使用

<div id="app">
    //3.使用组件
	<my-cpn></my-cpn>
</div>	
<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	//1.创建组件的构造器对象
	const cpnC = Vue.extend({
		template:`
		<div>
		<h2>标题</h2>
		<p>内容哈哈</p>
		<p>内容呵呵呵</p>
		</div>
		`
	})
	
	//2.注册组件
	// Vue.component('组件的标签名','构造器')
	Vue.component('my-cpn',cpnC)
	
	const app = new Vue({
		el:'#app',
		data:{
			message:'你好Vue'
		}
	})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 全局组件和局部组件

	<div id="app">
		<cpn></cpn>
	</div>	
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		//1.创建组件的构造器对象
		const cpnC = Vue.extend({
			template:`
			<div>
			<h2>标题</h2>
			<p>内容哈哈</p>
			<p>内容呵呵呵</p>
			</div>
			`
		})
		
		//2.注册组件(全局组件,可以在多个Vue的实例下使用)
		// Vue.component('组件的标签名','构造器')
		// Vue.component('cpn',cpnC)
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			//局部组件
			components:{
				//cpn使用组件时的标签名
				cpn:cpnC
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 父组件和子组件

	<div id="app">
		<cpn2></cpn2>
	</div>
	
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		//子组件
		const cpnC1 = Vue.extend({
			template:`
			<div>
			<h2>标题</h2>
			<p>内容哈哈</p>
			</div>
			`
		})	
		//父组件
		const cpnC2 = Vue.extend({
			template:`
			<div>
			<h2>标题</h2>
			<p>内容呵呵呵</p>
			<cpn1></cpn1>
			</div>
			`,
			components:{
				cpn1:cpnC1
			}
		})
				
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			components:{
				cpn2:cpnC2
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 组件的语法糖注册方式

	<div id="app">
		<cpn1></cpn1>
		<cpn2></cpn2>
	</div>
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		// 注册全局组件(语法糖)
		Vue.component('cpn1',{
			template:`
			<div>
			<h2>标题</h2>
			<p>内容哈哈</p>
			</div>
			`
		})
			
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			// 注册局部组件(语法糖)
			components:{
				'cpn2':{
					template:`
					<div>
					<h2>标题</h2>
					<p>内容呵呵</p>
					</div>
					`
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 组件中的data必须是函数

	<div id="app">
		<cpn1></cpn1>
	</div>
	<template id="cpn1">
		<div>
		<h2>{{title}}</h2>
		<p>内容哈哈</p>
		</div>
	</template>
	
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		// 注册全局组件
		Vue.component('cpn1',{
			template:'#cpn1',
			//这里data必须是函数,否则会报错
			data(){
				return{
					title:'abc标题'
				}
			}
		})
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 组件通信----父传子(props)

	<div id="app">
       <!--2.绑定-->
		<cpn :cmovies='movies'></cpn>
	</div>
		
	<template id="cpn">
		<div>
			<ul>
				<li v-for="item in cmovies">{{item}}</li>
			</ul>
		</div>
	</template>
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		//父传子:props==>properties 属性
		// 子组件
		const cpn = {
			template:'#cpn',
			//1.定义
			props:['cmovies'],
		}
		// 父组件(Vue实例)
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				movies:['海王','超人']
			},
			components:{
				cpn
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# props中的驼峰标识

	<div id="app">
		<!-- 不支持驼峰标识  cInfo转换为c-info,childMyMessage转换为child-my-message-->
		<cpn :c-info="info"></cpn>
	</div>
		
	<template id="cpn">
		<!-- 模板有多个标签时,必须包含根标签(例:div) -->
		<div>
			<h2>{{cInfo}}</h2>
		</div>
	</template>
		
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const cpn = {
			template:'#cpn',
			props:{
				//驼峰标识
				cInfo:{
					type: Object,
					default(){
						return{name:'某人'}
					}
				}
			}
		}
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				info:{
					name:'jack',
					age:18
				}
			},
			components:{
				cpn
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 组件通信---子传父(自定义事件名称)

	<div id="app">
		<!-- 2.监听事件 -->
		<cpn @item-click="cpnClick"></cpn>
	</div>
		
	<template id="cpn">
		<div>
			<button type="button" v-for="item in categories" @click="btnClick(item)">
				{{item.name}}
			</button>
		</div>
	</template>
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">

		const cpn = {
			template:'#cpn',
			data(){
				return{
					categories:[
						{id:'aaa',name:'热门推荐'},
						{id:'bbb',name:'手机数码'},
						{id:'ccc',name:'家用家电'},
						{id:'ddd',name:'电脑办公'},
					]
				}
			},
			methods:{
				btnClick(item){
					//1.发射事件	this.$emit('自定义事件名称',item)
					this.$emit('item-click',item)
				}
			}
		}

		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
			},
			components:{
				cpn
			},
			methods:{
				cpnClick(item){
					console.log(item.name)
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 父子组件通信-结合双向绑定案例

	<div id="app">
		<cpn :number1="num1"
				:number2="num2"
				@number1change="number1change"
				@number2change="number2change"/>
	</div>
		
	<template id="cpn">
		<div>
			<h2>props:{{number1}}</h2>
			<h2>data:{{dnumber1}}</h2>
			<!-- <input type="text" v-model="dnumber1"> -->
			<input type="text" :value="dnumber1" @input="num1Input">	
			<h2>props:{{number2}}</h2>
			<h2>data:{{dnumber2}}</h2>
			<!-- <input type="text" v-model="dnumber2"> -->
			<input type="text" :value="dnumber2" @input="num2Input">
		</div>
	</template>

	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const cpn = {
			template:'#cpn',
			props:{
				number1:Number,
				number2:Number
			},
			data(){
				return{
					dnumber1:this.number1,
					dnumber2:this.number2,
				}
			},
			methods:{
				num1Input(event){
					//1.将input中的value赋值到dnumber中
					this.dnumber1 = event.target.value
					//2.为了让父组件可以修改值,发出一个事件
					this.$emit('number1change',this.dnumber1)
				},
				num2Input(event){
					this.dnumber2 = event.target.value
					this.$emit('number2change',this.dnumber2)
				},
			}
		}
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				num1:0,
				num2:1
			},
			components:{
				cpn
			},
			methods:{
				number1change(value){
					this.num1= parseFloat(value)
				},
				number2change(value){
					this.num2= parseFloat(value)
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

# 组件访问--父访问子

	<div id="app">
		<!-- 加上ref -->
		<cpn ref="aaa"></cpn>
		<cpn></cpn>
		<button type="button" @click="btnClick">按钮</button>
	</div>
	<template id="cpn">
		<div>
			我是子组件
		</div>
	</template>
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const cpn = {
			template:"#cpn",
			methods:{
				showMessage(){
					console.log('这是子组件showMessage');
				}
			},
			data(){
				return{
					name:'子组件name'
				}
			}
		}
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			components:{
				cpn
			},
			methods:{
				btnClick(){
					// 1.$children(使用较少)
					// console.log(this.$children);
					//调用子组件的方法
					// this.$children[0].showMessage();
					//调用子组件的属性
					// console.log(this.$children[0].name);
					//遍历
					// for(let c of this.$children){
					// 	console.log(c.name);
					// 	c.showMessage()
					// }
					
					// 2.$refs
					console.log(this.$refs.aaa.name)
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# 组件访问--子访问父

	<div id="app">
		<cpn></cpn>
	</div>
		
	<template id="cpn">
		<div>
			我是cpn组件
			<ccpn></ccpn>
		</div>
	</template>
	
	<template id="ccpn">
		<div>
			<h2>我是子组件</h2>
			<button type="button" @click="btnClick">按钮</button>
		</div>
	</template>
		
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		//子组件
		const ccpn = {
			template:"#ccpn",
			methods:{
				btnClick(){
					//1.访问父组件$parent(使用较少)
					console.log(this.$parent.name);
					//2.访问根组件$root(使用较少)--访问Vue实例
					console.log(this.$root.message);
				}
			},
		}
		//父组件
		const cpn = {
			template:"#cpn",
			components:{
				ccpn
			},
			data(){
				return{
					name:'cpn组件的name'
				}
			}
		}
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			components:{
				cpn
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# 组件化高级

# slot插槽的基本使用

	<div id="app">
		<cpn></cpn>
		<cpn><span>添加</span></cpn>
		<cpn><i>haha </i></cpn>
		<cpn>
			<del>aaa</del>
			<del>bbbb</del>
			<div>ccc</div>
		</cpn>
	</div>
		
	<template id="cpn">
		<div>
			<h2>我是组件</h2>
			<p>哈哈</p>
			<!-- 插槽,可以放入默认值 -->
			<slot><button type="button">按钮</button></slot>
		</div>
	</template>
		
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好'
			},
			components:{
				cpn:{
					template:'#cpn'
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# slot具名插槽

	<div id="app">
		<!-- 只会替换没有名字的插槽 -->
		<cpn><span>标题</span></cpn>
		
		<!-- 替换name为center的插槽 -->
		<cpn><span slot="center">中间标题</span></cpn>

	</div>
		
	<template id="cpn">
		<div>
			<slot name="left"><span>左边</span></slot>
			<slot name="center"><span>中间</span></slot>
			<slot name="right"><span>右边</span></slot>
			<slot>哈哈哈</slot>
		</div>
	</template>
		
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好'
			},
			components:{
				cpn:{
					template:'#cpn'
				}
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 什么是编译的作用域

	<div id="app">
		<!-- isShow使用的是实例中的,从当前模板中查找 -->
		<cpn v-show="isShow"></cpn>
	</div>
		
	<template id="cpn">
		<div>
			<h2>我是子组件</h2>
			<p>哈哈</p>
		</div>
	</template>
		
	<script src="../vue.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		
		const cpn = {
			template:"#cpn",
			data(){
				return{
					isShow:false
				}
			}
		}
		
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue',
				isShow:true
			},
			components:{
				cpn
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 作用域插槽

# Vue Mixins(混入)

作用:复用组件的功能

# 生命周期函数

注意:生命周期函数和methods同级,不要放在methods中

mounted 加载时执行

	<script type="text/javascript">
		const app = new Vue({
			el:'#app',
			data:{
				message:'你好Vue'
			},
			beforeCreate:function(){
				console.log('beforeCreate');
			},
			created:function(){
				console.log('created');
			},
			mounted:function() {
				console.log('mounted');
			}
		})
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 前端模块化

# ES6的模块化实现

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	// type="module"模块化
	<script src="aaa.js" type="module"></script>
	<script src="mmm.js" type="module"></script>
	</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13

aaa.js

let name = '小明'
let age =18
let flag = true

function sum(num1,num2){
	return num1+num2
}
//导出
export{
	flag,
	age,
	sum
}

const address = '北京市'
//export default 导出(导入时,可以自己命名,只能有一个export default)
export default address
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

mmm.js

//导入
import {flag, age, sum} from "./aaa.js"
import addr from "./aaa.js"
//全部导出,命名为aaa对象
import * as aaa from './aaa.js'

if(flag){
	console.log(`${name}今年${age}岁了`);
	console.log(sum(10,20));
}
//addr是自己命名的
console.log(addr)
//通过aaa对象取值
console.log(aaa.flag)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Webpack

# 安装

安装webpack(指定版本号3.6.0,因为vue cli2依赖该版本)

-g 全局安装

npm install webpack@3.6.0 -g
1

局部(本地)安装

npm install webpack@3.6.0 --save -dev
1

--save -dev(--save 写入package.json,-dev开发时依赖)

打包

webpack / npm run build
1
//package.json  
"scripts": {
    "build": "webpack"//将webpack和npm run build对应,配置后,运行时,优先使用本地webpack
  }
1
2
3
4

webpack.config.js

const path = require('path')

module.exports = {
	entry:'./src/main.js',
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'bundle.js'
	}
}
1
2
3
4
5
6
7
8
9

项目初始化(安装node的包)

npm init
1

# Loader

npm install --save-dev less
npm install --save-dev less-loader
npm install --save-dev css-loader
npm install --save-dev style-loader
1
2
3
4

这些loader的作用如下:

  • 安装less-loader后可以在js中使用require的方式来加载less文件了;
  • 安装css-loader后可以在js中加载css文件;
  • 安装style-loader的目的是为了让加载的css作为style标签内容插入到html中。

# 配置loader

webpack.config.js代码如下:

module.exports = {
    devtool: 'eval-source-map',
    entry:  __dirname + "/src/main.js",  //入口文件
    output: {
        path: __dirname + "/dist",  //打包后的文件存放的地方
        filename: "bundle.js" //打包后输出文件的文件名
    },
    module: {
        rules: [
            {
                test: /\.less$/,
                use: ['style-loader','css-loader', 'less-loader']
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 引入图片 url -loader

    module: {
        rules: [
            {
                test: /\.(png|jpg|gif|jpeg)$/,
                use: [{
                    loader:'url-loader',
                    option:{
                        limit:13000
                    }
                }]
            }
        ]
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

当加载的图片小于limit时,会将图片编译成base64字符串形式当加载的图片,

大于limit时,需要使用file-loader(需要安装,不用配置)模块进行加载。

# 脚手架创建Vue项目

根据package.json配置文件中的依赖配置下载安装 npm install

vue cli 3.0 安装cli npm i @vue/cli -g

vue create 项目名		**名字中不能有大写也不能用驼峰命名**

运行	npm run serve

vue cli 2.0 安装cli npm install -g @vue/cli-init

安装webpack	npm **install** webpack -g

vue init webpack 项目名

运行	npm run dev

打包	npm run build

vue cli 4.0

打开可视化网页 vue ui

# 引入组件

import Header from './Header.vue';

	components:{
		'v-header':Header,
		}

使用

<v-header></v-header>
1

# vue-resource 请求数据

1.安装

cnpm install vue-resource --save

//--save 表示加入package.json中

2.main.js 加入

import VueResource from 'vue-resource'

Vue.use(VueResource)

3.方法

	methods:{
		getData(){
			//请求数据
			var api = 'http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1';
			this.$http.get(api).then((response)=>{
				window.console.log(response);
			},(err)=>{
				window.console.log(err);
			})
		}
	}
1
2
3
4
5
6
7
8
9
10
11

4.展示

		<ul>
			<li v-for="item in list" :key='item'>
				{{item.title}}
			</li>
		</ul>
1
2
3
4
5

网络请求 http://httpbin.org/ (opens new window)

http://123.207.32.32:8000/home/multidata (opens new window)

# axios 请求数据

vue全局使用axios的方法 (opens new window)

axios的使用小技巧:如何绕过字符串拼接,直接传递对象 (opens new window)

安装

npm install axios --save
1

引入(在main.js中)

import axios from 'axios' //也可以在组件中按需引入
Vue.prototype.$axios = axios; //使用原型的定理 将axios方法设定为Vue对象的方法(全局使用)
1
2

组件中使用

1.先设置跨域(/config/index.js中)

		proxyTable: {
			'/api': {
				target: 'https://api.qq.jsososo.com/', //设置你调用的接口域名和端口号 
				changeOrigin: true, //跨域
				pathRewrite: {
					'^/api': '/' 
                    //这里理解成用‘/api’代替target里面的地址,后面组件中我们调接口时直接用api代替 					比如我要调用'http://10.1.5.11:8080/xxx/duty?id=3',直接写‘/api/xxx/duty?						id=3’即可
				},
			}
		},
1
2
3
4
5
6
7
8
9
10

2.组件中

<script type="text/javascript">
	export default {
		data() {
			return {
				qq_urls: []
			}
		},
		methods: {
			getList() {
				this.$axios.get('/api/recommend/playlist').then(res => {
					console.log(res.data)
					var result = res.data.result
					var list = res.data.data.list
					if (result == 100) {
						this.qq_urls = list
					}

				}).catch(err => {
					console.log(err)
				})
			}
		},
		created: function() {
			this.getList()
		}

	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

拼接url传递参数

<script type="text/javascript">
	export default {
		data() {
			return {
				singer:'周杰伦'
			}
		},
		methods: {
			getList() {
				this.$axios({
					methods:'get',
					url:'/api/search',
					//是params才能拼接到url上
					params:{
						key:this.singer
					}			
				}).then(res => {
					console.log(res)
				}).catch(err => {
					console.log(err)
				})
			}
		},
		created: function() {
			this.getList()
		}

	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 解决vue动态绑定audio/video的src不能播放

参考:http://www.fly63.com/article/detial/6914

<template>
	<div>
		<audio controls="controls" id="audioPlay" ref="audio">
		</audio>
		<input type="text" placeholder="输入链接id" v-model="music_id">
		<button @click="getList()">播放</button>
	</div>
	
</template>

<script type="text/javascript">
	export default {
		data() {
			return {
				music_id: '',
				music_src: ""
			}
		},
		methods: {
			getList() {
				this.$axios({
					methods: 'get',
					url: '/api/song/urls',
					//是params才能拼接到url上
					params: {
						id: this.music_id
					}
				}).then(res => {
					var result = res.data.result
					//获取播放链接
					const key = this.music_id
					var music_url = res.data.data
		
					if (result == 100) {
						console.log(music_url[key])
						//方法一
						// let ado = document.getElementById("audioPlay")
						// ado.src=music_url[key];
						// ado.play();
						//方法二
						this.$refs.audio.src = music_url[key]
					}
				}).catch(err => {
					console.log(err)
				})
			}
		}
	}
</script>

<style>
</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//1.axios的基本使用
axios({
	url:'http://123.207.32.32:8000/home/multidata',
	//默认get请求
	methods:'get'
}).then(res =>{
	console.log(res);
})

axios({
	url:'https://api.uomg.com/api/rand.music',
	params:{
		sort:'热歌榜',
		format:'json'
	}
}).then(res =>{
	console.log(res);
})

//2.axios发送 并发请求
axios.all([axios({
	url:'http://123.207.32.32:8000/home/multidata'
}),axios({
	url:'https://api.uomg.com/api/rand.music',
	params:{
		sort:'热歌榜',
		format:'json'
	}
})]).then(axios.spread((res1, res2) => {
		console.log(res1);
		console.log(res2);
	}))

//3.使用全局配置进行网络请求
axios.default.baseURL = 'http://123.207.32.32:8000'
axios.default.timeout = 5000

axios.all([axios({
	url:'/home/multidata',
}),axios({
	url:'/data',
	params:{
		type: 'sell',
		page:5
	}
})]).then(axios.spread((res1, res2) => {
		console.log(res1);
		console.log(res2);
	}))

// 4.创建对应的axios的实例
const instancel = axios.create({
	baseURL:'http://123.207.32.32:8000',
	timeout :5000
})

instancel({
	url: '/home/multidata'
}).then(res =>{
	console.log(res);
})

instancel({
	url:'/home/data',
	params:{
		type:'pop',
		page:1
	}
}).then(res=> {
	console.log(res)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

# 非父子组件

src/model下创建 VueEvent.js,并添加

import Vue from 'vue'

var VueEvent = new Vue()

export default VueEvent
1
2
3
4
5

Home.vue 中,广播

<button @click="emitNews()">给News组件广播数据</button>
<script>
import VueEvent from '../model/vueEvent.js'
//方法
emitNews(){
				//广播数据
				VueEvent.$emit('to-news',this.msg)
			}

</script>
1
2
3
4
5
6
7
8
9
10

News.vue中,接收

import VueEvent from '../model/vueEvent.js'

		mounted(){
			VueEvent.$on('to-news',function(data){
				window.console.log(data);
			})
		}
1
2
3
4
5
6
7

# 双向绑定原理

vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调

https://www.bilibili.com/video/BV1oJ411t7zQ

let obj = {}
Object.defineProperty(obj,'val',{
  get:function(){
    console.log('ggg')
    return 'xx123'
  },
  set:function(){
    console.log('sss')
  }
})
//写入时触发 set
obj.val = 123

//读取时触发 get
console.log(obj.val)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 自定义指令

导航点击高亮功能

https://www.bilibili.com/video/BV1dk4y1q7D7

src/view/doing/index.vue

<template>
  <div class="nav-bar" 
    v-nav-current="{
      curIdx,
      className:'nav-item',
      activeClass:'nav-current'
    }">
    指令
    <!-- :class="['nav-item',{'nav-current':index === curIdx}]" -->
    <div 
      class="nav-item"
      v-for="(item, index) of items"
      :key="index"
      @click="changeNav(index)">
      {{ item }}
    </div>
  </div>
</template>

<script>
import navCurrent from "@/directives/navCurrent";

export default {
  name: "doing",
  directives: {
    navCurrent,
  },
  data() {
    return {
      curIdx: 0,
      items: ["选项一", "选项二","选项三"],
    };
  },
  methods:{
    changeNav(index){
      this.curIdx = index
    }
  }
};
</script>


<style scoped>
.nav-item{
  background-color: #fff;
  display: block;
  width: 50px;
}
.nav-current{
  background-color: rgb(110, 17, 17);
  color: #fff;
}
</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

src/directives/navCurrent.js

export default {
  bind(el,binding, vnode){
    const _ops = binding.value,
          _c = el.getElementsByClassName(_ops.className)
    _c[_ops.curIdx].className += ` ${_ops.activeClass}`
  },
  update(el,binding, vnode){
    const _ops = binding.value,
          _oOps = binding.oldValue,
          _c = el.getElementsByClassName(_ops.className)

    _c[_oOps.curIdx].className = `${_oOps.className}`
    _c[_ops.curIdx].className += ` ${_ops.activeClass}`
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 核心业务

权限管理、上传类(视频、图片、表格)、下载/导出类(图片、Excel、PDF)、websocket类/第三方音视频sdk、echarts

# Vue优化

1、v-for 正确设置key值 2、封装复用的模块(http请求)、组件(ui库) 3、路由懒加载:component:() = import(./xxx.vue) 提高首屏加载速度 4、productionSourceMap: false config/index.js中 5、启用gzip压缩,打包体积更小 config/index.js中 6、keep-alive 缓存不活跃组件 7、插件CDN方式引入,减小项目体积 8、图片使用CDN地址,图片懒加载

# 解除严格模式

在build/webpack.base.conf.js中

 // ...(config.dev.useEslint ? [createLintingRule()] : []),
      ...(config.dev.useEslint ? [] : []),
1
2

vue-cli4.0关闭eslint

  • 在项目文件夹下新建一个文件vue.config.js,然后输入将下面的代码copy进入

    module.exports = {
       lintOnSave: false
    };
    
    
    1
    2
    3
    4
  • 然后重新启动项目(一定要重启,不然不会生效)就可以了

去GitHub编辑 (opens new window)
上次更新: 2021/07/21, 15:54:33
四级文件(测试)
vue-cli(脚手架)创建Vue项目

← 四级文件(测试) vue-cli(脚手架)创建Vue项目→

最近更新
01
sql语句基础
10-21
02
express基础
10-21
03
转换文件
08-27
更多文章>
Theme by Vdoing | Copyright © 2021-2023 kechenhh | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×