目录
3.4 基于axios.get()和axios.post()发起请求
5.0.1 插件1:vue文件代码提示-vetur和vue 2 snippets
5.0.2 插件2:Auto Close Tag用于自动生成闭合标签。
5.0.3 插件3:@路径提示-Path Autocomplete
一、侦听器
1.1 什么是watch侦听器
watch侦听器允许监视数据的变化,从而针对数据的变化做特定的操作。语法格式如下:


1.2 方法格式的侦听器的应用--判断用户名是否被占用
实时监控用户名的输入,判断输入的用户名是否被占用。该方式不能自动触发一次,不建议使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./lib/bootstrap.css">
</head>
<body>
<!-- 步骤一:导入vue的库文件,这样Window全局就有了Vue这个构造函数 -->
<script src="./lib/vue.js"></script>
<script src="./lib/jquery-3.3.1.js"></script>
<!-- 步骤二:创建DOM -->
<div id="app">
<input type="text" v-model="username">
</div>
<!-- 步骤三:创建Vue的实例对象 -->
<script>
const vm = new Vue({
el:'#app',
data:{
username:''
},
watch:{
username(newVal){
if(newVal === '') return
$.get('https://www.escook.cn/api/finduser/'+newVal, function(result){
console.log(result)
})
}
}
})
</script>
</body>
</html>
1.3 immediate属性-对象格式的侦听器
上述案例存在弊端:只有当值发生变化时才会触发,对于默认值不会触发。如设置username初值为admin,并不会触发去后台请求。加入immediate解决该问题
侦听器的格式:
(1)方法格式的侦听器:
缺点1:无法在进入页面的时候自动触发!!!
缺点2:如果侦听的是一个对象,如果其中的属性发生了变化,不会触发侦听器!
(2)对象格式的侦听器:
优点1:通过immediate属性,让侦听器自动触发!!!
优点2:可以通过deep选项,让侦听器深度监听对象中每个属性的变化!!
总结:若方法格式的侦听器可以满足,建议采用方法格式的。


1.4 deep属性-对象格式的侦听器
deep属性用于解决方法格式的侦听器,如果侦听的是一个对象,如果其中的属性发生了变化,不会触发侦听器的问题。

如上,info可能包含多个属性,若我们只想侦听username值得变化。怎么办呢?
如果要侦听的是对象的子属性的变化,必须包裹一层单引号。此时不需要再加deep属性

二、计算属性
computed: {
rgb(){
return `rgb(${this.r},${this.g},${this.b})`
}
}
// 直接使用rgb即可,作为data的一个属性

特点:(1)定义的时候,要被定义为“方法”
(2)在使用计算属性的时候,当普通的属性使用即可
好处:(1)实现了代码的复用
(2)只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值!!
案例:通过修改RGB的值,更改div的颜色,同时更改div中rgb的数值,同时点击按钮,console出rgb的值。有三处都需要获取rgb的值,采用计算属性的好处就是代码可以复用。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./lib/bootstrap.css">
</head>
<body>
<!-- 步骤一:导入vue的库文件,这样Window全局就有了Vue这个构造函数 -->
<script src="./lib/vue.js"></script>
<script src="./lib/jquery-3.3.1.js"></script>
<!-- 步骤二:创建DOM -->
<div id="app">
<div>
<span>R:</span>
<input type="text" v-model.number="r">
</div>
<div>
<span>G:</span>
<input type="text" v-model.number="g">
</div>
<div>
<span>B:</span>
<input type="text" v-model.number="b">
</div>
<div :style="{backgroundColor: rgb}">
{{ rgb }}
</div>
<button @click="show">按钮</button>
</div>
<!-- 步骤三:创建Vue的实例对象 -->
<script>
const vm = new Vue({
el:'#app',
data:{
r: 0,
g: 0,
b: 0
},
methods:{
show(){
console.log(this.rgb)
}
},
computed: {
rgb(){
return `rgb(${this.r},${this.g},${this.b})`
}
}
})
console.log(vm)
</script>
</body>
</html>
三、axios
3.1 axios的基础使用
axios(发音:艾克C奥斯)是前端圈最火的,专注于数据请求的库。

注:接口返回的是result.data。axios在返回的数据外面套了一层

axios请求也可拆分为2步。第一步发请求,第二步处理请求。

3.2 结合async和await调用axios
若方法返回值是Promise,则可以在前面添加await。这样返回的就是接口返回的数据,去除了axios包的外壳。加await还需要在对应的方法前加async修饰

get请求传参用params参数,post请求传参用data

3.3 解构赋值
通过await和async获取去除了axios的外壳,但要获取实际的数据,还需要.data才可以。采用解构赋值的方法将data重命名为res,避免出现data.data

3.4 基于axios.get()和axios.post()发起请求
// axios.get请求
axios.get('URL地址',{
// GET参数
params: {}
})
// axios.post请求
axios.post('url地址',{ post请求数据 })
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./lib/bootstrap.css">
</head>
<body>
<script src="./lib/vue.js"></script>
<script src="./lib/jquery-3.3.1.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
<button id="btnGet">GET请求</button>
<button id="btnPost">POST请求</button>
</div>
<script>
// axios.get请求
document.querySelector('#btnGet').addEventListener('click',async function() {
const { data: res } = await axios.get('http://www.liulongbin.top:3006/api/getbooks',{
params: { id: 1 }
})
console.log(res.data)
})
// axios.post请求
document.querySelector('#btnPost').addEventListener('click',async function() {
const { data: res } = await axios.post('http://www.liulongbin.top:3006/api/post',{ name: 'zs', gender: '女'})
console.log(res)
})
</script>
</body>
</html>
四、vue-cli
4.1 单页面应用程序
单页面应用程序(Single Page Application)简称SPA,指的是一个web网站中只有唯一的一个HTML页面,所有的页面交互都在这一个页面实现
4.2 vue-cli
vue-cli是Vue.js开发的标准工具,简化了程序员对于webpack创建工程化的Vue项目的过程。
中文官网:https://cli.vuejs.org/zh/
4.3 vue-cli的安装和使用
安装:vue-cli是npm上的一个全局包,任意目录下打开cmd窗口,使用npm install -g @vue/cli 命令安装
验证:vue -V,即可验证
使用:
(1)创建项目:进入要创建项目的文件夹,cmd,执行vue create 项目名称
(2)初学者,建议选择配置方式为手工配置

(3)选择配置

(4)vue版本选择,此处选择2.0

(5)选择less

(6)选择第一项

(7)开始安装,若此时点击窗口会导致暂停。此时点击窗口,CTRL+C
(8)cd 项目目录 npm run serve
执行成功如下:

tips:
(1)用vscode打开一个项目,将文件夹直接拖入vscode即可
(2)CTRL+反撇号:调出vscode控制台,执行npm run serve运行项目

4.4 vue项目中src目录的构成
asset文件夹:存放项目中用到的静态资源文件,例如,css样式、图片资源
components文件夹:程序员封装的、可复用的组件,都要放到components文件夹
main.js:程序的入门文件,整个项目的运行,要先执行main.js
App.vue:项目的根组件
4.5 vue项目运行的过程
在工程化的项目中,vue要做的事情很单纯:通过main.js把App.vue渲染到index.html的指定区域中
App.vue是待渲染的模板结构。index.html中需要预留一个el区域,main.js把App.vue渲染到了index.html中预留的区域中
App.vue文件:(样式文件)

index.html文件:(占位文件)

main.js文件:(渲染文件)

Vue实例的$mount和el的作用相同!!!!!!!
4.6 将自己创建的文件渲染至页面而不是App.vue
若不想用App.vue渲染页面,想用自己创建的页面,步骤如下:
(1)src目录下新建test.vue文件.如下:
<template>
<h1>test.vue</h1>
</template>
(2)修改main.js文件:一是引入test.vue文件,二是修改渲染文件为test.vue
import Vue from 'vue'
import App from './App.vue'
import Test from './test.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(Test),
}).$mount('#app')
五、vue组件
5.0 vscode插件
5.0.1 插件1:vue文件代码提示-vetur和vue 2 snippets
vscode中编写.vue文件的时候无代码片段提示时,装上vetur和vue 2 snippets两个插件即可。
在编写vue文档时,输入< 回车,就会生成模板
5.0.2 插件2:Auto Close Tag用于自动生成闭合标签。
如输入div自动生成</div>
5.0.3 插件3:@路径提示-Path Autocomplete
输入@时路径没提示
(1)安装Path Autocomplete插件

(2)打开setting.json文件


(3)配置setting.json文件
{
"path-autocomplete.extensionOnImport": true,
"path-autocomplete.pathMappings": {
"@":"${folder}/src"
}
}
(4)验证:输入@后路径也会自动提示
注:有时候配置后不生效。查看vscode中是否打开的是本项目。若是本项目的上一级目录则不生效

5.1 vue中的组件化开发
vue是一个支持组件化开发的前端框架。vue中规定,组件的后缀名是.vue,之前接触到的App.vue文件本质上就是一个Vue的组件
5.2 vue组件的三个组成部分
(1)template:组件的模板结构
(2)script:组件的JS行为。data() 、methods
(3)style:组件的样式
<template>
<div class="box">
<h1>{{ username }}</h1>
<button @click="change">修改</button>
</div>
</template>
<script>
// 默认导出,固定写法
export default {
// data数据源
// 注:.vue组件中的data不能像之前一样,要写成一个函数
data() {
return {
username: 'admin'
}
},
methods: {
change() {
this.username = 'hello'
}
},
// 当前组件中的侦听器
watch: {},
// 当前组件中的计算属性
computed: {},
// 当前组件中的过滤器
filter: {}
}
</script>
<style>
.box {
background-color: pink;
}
</style>
注:template中只能有一个div
5.3 vue中启用less语法
如上,如想设置h1的样式,直接加上后不生效,需要在style中加入lang=“less”后生效

5.4 vue组件之间的父子关系
vue开发中,除了App.vue外其他的组件都要放到components目录下

组件在封装好后,彼此之间是相互独立的,不存在父子关系,在使用组件的时候,根据彼此之间的嵌套关系,形成了父子、兄弟关系
5.4.1 使用组件的三个步骤
(1)引入(2)注册(3)使用
注:导入多个页面时用逗号分隔

5.5 通过components注册的是私有子组件
如:在组件A的components节点下,注册了组件F
则组件F只能用在组件A中,不能被用在组件C中
5.6 注册全局组件-频繁使用的组件
在vue项目的main.js入口文件中,通过Vue.components()方法,可以注册全局组件。示例代码如下:
(1)新建demo.vue全局组件。
<template>
<div>全局组件</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
(2)main.js中配置全局组件:导入并注册全局组件

(3)使用

5.7 组件的props
props是组件的自定义属性,在封装通用组件的时候,合理使用props可以极大地提高组件的复用性
5.7.1 语法

5.7.2 pops使用场景
一个全局组件需要被多个组件使用,但每个组件想指定不同的初始值,则此时使用props
示例如下:
(1)在全局组件中新增prop节点,并在节点下新增init属性。这里init不是固定属性,随便起

(2)在引用全局组件的文件中给init属性赋初值

存在问题,如上,init="5",实际赋值的是一个字符串5.而我们想要的是数字5.此时需要借助v-bind.如下:

解释:v-bind用于动态赋值,:属性=“”,引号内的是js内容,9则代表是数字
但是这样做存在的问题是init直接被修改,功能无影响,但控制台会报错。

小插曲:
若要实现点击按钮自增1,这种只有一行语句的方法,可以直接将该语句写到DOM,如下
可简写为:去掉methods,将原方法写入click事件
5.7.3 props是只读的
vue规定:组件中封装的自定义属性是只读的,不能直接修改props的值,否则会报错。

props是只读的,但我们有时候又有修改的需求,怎么办呢?
解决办法:将init值赋值给count,count实现自增的运算。如下:

5.7.4 props-default默认值
在声明自定义属性时,可以通过default来自定属性的默认值。若外界在使用init属性时,没有传init的初始值,则使用init的默认值。格式如下:
export default {
props: {
init: {
default: 0
}
},
}
5.7.5 props的type值类型
在声明自定义属性时,可以通过type来定义属性的值类型。示例如下:
若传过来的值不符合此类型,则终端会报错

Type的可选值包括:Number、Boolean、String、Array、Object

5.7.6 props的required必填项
外界在调用组件时,使用props属性时,必须要传初始值

5.8 组件之间的样式冲突问题
存在问题:默认情况下,写在.vue组件中的样式会全局生效,如定义h3标签的样式,则所有vue页面中的h3标签都会生效。因此,很容易造成多个组件之间的样式冲突问题。
导致冲突的根本原因是:(1)单页面应用程序中,所有的DOM结构,都是基于唯一的index.html页面进行呈现的;
(2)每个组件的样式,都会影响整个index.html页面中的DOM元素
解决办法:在style中加一个scoped属性
<style lang="less" scoped>
scoped属性的原理:为同一个页面内的所有标签加一个v-data-xxx的属性。css样式设置时采用属性选择器:h3[v-data-xxx]: {}

5.9 使用deep修改子组件中的样式
A组件调用B组件,A组件的css中加了scope参数,但是A组件想修改B组件的属性,则需要使用/deep/。
应用场景:当使用第三方组件库(如vant等)的时候,如果有修改第三方组件默认样式的需求,用/deep/
<style lang="less" scoped>
/deep/ h3{
color: red;
}
</style>


18万+





