Vue基础
一、Vue.js是什么?
**vue官网:**https://cn.vuejs.org/guide/introduction.html
vue.js:是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。
vue的渐进式表现为:
声明式渲染——组件系统——客户端路由——-大数据状态管理——-构建工具
二、库和框架的区别
库(Library)
库,本质上是一些函数的集合。每次调用函数,实现一个特定的功能,接着把 控制权交给使用者
代表:jQuery
jQuery这个库的核心:DOM操作,即:封装DOM操作,简化DOM操作
框架(Framework)
框架,是一套完整的解决方案,使用框架的时候,需要把你的代码放到框架合适的地方,框架会在合适的时机调用你的代码
框架规定了自己的编程方式,是一套完整的解决方案
使用框架的时候,由框架控制一切,我们只需要按照规则写代码
主要区别
核心点:谁起到主导作用(控制反转)
框架中控制整个流程的是框架
使用库,由开发人员决定如何调用库中提供的方法(辅助)
框架的侵入性很高(从头到尾)
框架与库之间最本质区别在于控制权:you call libs, frameworks call you(控制反转)
三、vue的基本语法
常用内置指令
v-text | 更新元素的 tex |
---|---|
v-html | 更新元素的 inn |
v-if | 如果为 true, 当前标签才会输出 |
v-else | 如果为 false, 当前标签才会输出到页面 |
v-show | 通过控制 display 样式来控制 |
v-for | 遍历数组/对象 |
v-on | 绑定事件监听, 一般简写为@ |
v-bind | 绑定解析表达式, 可以省略 v-bin |
v-model | 双向数据绑定 |
v-cloak | 防止闪现, 与 css 配合: [v-cloak] { display: |
1.钩子函数(created和distory)
钩子函数:就是vue定义好的事件,与Serlvet的init(初始化)和distory(销毁)方法相似
案例:创建一个
<script type="text/javascript">
var test = new Vue({
el:"#test",
//钩子函数created,该方法在页面显示之后,自动执行
created() {
console.log("初始化成功...");
}
});
</script>
2.插值语法({{}})
插值语法:将定义好的数据,显示在页面上
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>插值语法</title>
</head>
<body>
<div id="test">
<h1>{{ name }}</h1>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var test = new Vue({
el : "#test",
data:{
name: "欢迎光临"
}
});
</script>
</html>
3.显示数据(v-text和v-html)
v-text和v-html专门用来展示数据, 其作用和插值表达式类似。v-text和v-html可以避免插值闪烁问题.
v-text:<span v-text="msg"></span> <!-- 相当于<span>{{msg}}</span> -->
v-html:<span v-html="msg"></span> <!-- 相当于<span>{{msg}}</span> -->
4.双向数据绑定(v-model)
v-model的双向绑定可以实现数据变化的时候, 页面会自动刷新, 页面变化的时候,数据也会自动变化
注意:
1. 双向绑定, 只能绑定**“文本框,单选按钮,复选框,文本域,下拉列表”**等
2. 文本框/单选按钮/textarea, 绑定的数据是字符串类型
3. 单个复选框, 绑定的是boolean类型
4. 多个复选框, 绑定的是数组
5. select单选对应字符串,多选对应也是数组
4.1绑定文本框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="test">
输入文本框:<input type="text" v-model="inputText"/>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var test = new Vue({
el:"#test",
data:{
inputText:""
}
});
</script>
</html>
4.2绑定单个复选框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="agree">同意<br>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
agree:true
}
});
</script>
</html>
4.3绑定多个复选框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="checkbox" value="Java" v-model="language">Java<br>
<input type="checkbox" value="Python" v-model="language">Python<br>
<input type="checkbox" value="Swift" v-model="language">Swift<br>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
//数组中的值,就是被选中的元素的value属性值
language:["Java","Python"]
}
});
</script>
</html>
5.事件绑定(v-on)
5.1事件绑定(v-on)
<!--完整写法-->
<button v-on:事件名="函数名/vue表达式">点我</button>
<!--简化写法-->
<button @事件名="函数名/vue表达式">点我</button>
5.2事件修饰符
<button @事件名.事件修饰符="函数名/vue表达式">点我</button>
<!--分类-->
.stop :阻止事件冒泡, 也就是当前元素发生事件,但当前元素的父元素不发生该事件
.prevent :阻止默认事件发生
.capture :使用事件捕获模式, 主动获取子元素发生事件, 把获取到的事件当自己的事件执行
.self :只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
.once :只执行一次
6.循环遍历(v-for)
6.1遍历数组
v-for="item in items"
v-for="(item,index) in items"
<!--注释:-->
items:要迭代的数组
item:存储数组元素的变量名
index:迭代到的当前元素索引,从0开始。
6.2遍历对象
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
<!--注释:-->
value,对象的值
key, 对象的键
index, 索引,从0开始
6.3key
概述:
:key 一般配合v-for一起使用. 用来在特定情况下, 保证被遍历的数组中的元素的顺序.
7.判断语法(v-if和v-show)
概述:
v-if与v-show可以根据条件的结果,来决定是否显示指定内容.
v-if: 条件不满足时, 元素不会存在.
v-show: 条件不满足时, 元素不会显示(但仍然存在).
8.显示数据(v-bind)
概述:
v-bind的作用和插值表达式差不多, 只不过, v-bind主要用于动态设置标签的属性值
<!--语法-->
<!--完整写法-->
<标签名 v-bind:标签属性名="vue实例中的数据属性名"/>
<!--简化写法-->
<标签名 :标签属性名="vue实例中的数据属性名"/>
9.Vue页面跳转
方法:标签实现跳转和this.$root.push()实现
<router-link :to="{name: 'bookshelf', params: { entityId: this.entityId } }" href="javascript:">
<span>测试</span>
</router-link>
<!--当this.$router.push()只有一个参数时 默认为跳转地址 最多可传两个参数 第二个参数为地址参数-->
<a @click="toIndex" :class="{'flex-item-1':'flex-item-1',cur:tabs[2].isShow}" href="javascript:">
<span>首 页</span>
</a>
toIndex: function(){
this.$router.push("/?entityId="+ localStorage.getItem("entityId"));
}
四、Vue其他语法
4.1计算属性
概述:
计算属性就是一个提前定义好的方法, 该方法可以看作是一个特殊的值, 可以在插值表达式中使用.
语法:
var app = new Vue({
el:"#app",
//计算属性必须放在Vue的computed中
computed:{
//定义计算属性
属性名(){
return "返回值";
}
}
});
4.2watch属性
概述:
watch可以监听简单属性值及其对象中属性值的变化.
watch类似于onchange事件,可以在属性值修改的时候,执行某些操作.
语法:
var app = new Vue({
el:"#app",
data:{
message:"信息",
person:{"name":"名称", "age":0}
},
//watch监听
watch:{
//监听message属性值,newValue代表新值,oldValue代表旧值
message(newValue, oldValue){
console.log("新值:" + newValue + ";旧值:" + oldValue);
},
//监控person对象的值,对象的监控只能获取新值
person: {
//开启深度监控;监控对象中的属性值变化
deep: true,
//获取到对象的最新属性数据(obj代表新对象)
handler(obj){
console.log("name = " + obj.name + "; age=" + obj.age);
}
}
}
});
五、实例生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6A9Gm0t-1693293621612)(E:\vue\笔记\img\image-20230724102239085.png)]
-
vue 生命周期分析
初始化显示 beforeCreate() created() beforeMount() mounted() 更新状态: this.xxx = value beforeUpdate() updated() 销毁 vue 实例: vm.$destory() beforeDestory() destoryed()
-
常用的生命周期方法
mounted(): 发送 ajax 请求, 启动定时器等异步任务 beforeDestory(): 做收尾工作, 如: 清除定时器
总结:
又名:生命周期回调函数、生命周期函数、生命周期钩子 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的 生命周期函数中的this指向是vm 或 组件实例对象
六、Vue组件化编程
模块
理解:向外提供特定功能的 js 程序,一般就是一个 js 文件
为什么:js 文件很多很复杂
作用:复用 js,简化 js 的编写,提高 js 运行效率
组件
定义:用来实现局部功能的代码和资源的集合(html/css/js/image…)
为什么:一个界面的功能很复杂
作用:复用编码,简化项目编码,提高运行效率
模块化
当应用中的 js 都以模块来编写的,那这个应用就是一个模块化的应用
组件化
当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用
案例:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>组件</title>
</head>
<body>
<div id="app">
<counter></counter>
<counter></counter>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
const counterTemp = {
template: '<button @click="num ++">您点击{{num}}次</button>',
data() {
return {
num: 0
}
}
};
var app = new Vue({
el: "#app",
components: {
counter: counterTemp
}
});
</script>
</html>
注意:
1. 组件的模版中, 只能书写一个跟标签
2. 组件的定义必须放在Vue创建对象之前, 否则报错
父组件向子组件通信
概述:
子组件无法直接使用父组件中的数据, 如果需要使用, 则必须由父组件把数据传递给子组件才可以.
本质: 让子组件中的属性与父组件中的属性进行关联绑定, 然后子组件使用该属性, 这样才能做到数据传递
可以把父组件中的数据, 更新传递到子组件
案例:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>父组件向子组件通信</title>
</head>
<body>
<div id="app">
<aaa :number="count" :ids="arr" :person="p"></aaa>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var aaa = {
template: '<h2>{{num}}----{{number}}-----{{ids}}------{{person}}</h2>',
data() {
return {
num: 0
}
},
props: {
number: {
type: Number,
default: ""
},
ids: {
type: Array,
default: []
},
person: {}
}
};
Vue.component("aaa", aaa);
var app = new Vue({
el: "#app",
data: {
count: 5,
arr: [1, 2],
p: {username: "用户名", age: "年龄"}
}
});
</script>
</html>
子组件向父组件通信
概述:
子组件无法直接给父组件传递数据. 也无法操作父组件中的数据, 更无法调用父组件中的方法.
所以, 所谓的子组件向父组件通讯, 其实就是想办法让子组件调用父组件的方法. 进而响应到父组件中的数据.
子组件可以调用父组件中的方法
案例:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>子组件向父组件通信</title>
</head>
<body>
<div id="app">
<h1>父组件中:app_num={{app_num}}</h1>
<counter @aaa="add" @bbb="rem" :counter_num="app_num"></counter>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
let counter = {
template: ' <div> <h1>子组件中:counter_num={{counter_num}}</h1><input type="button" @click="fun1" value="+"/> <input type="button" @click="fun2" value="-"/> </div>',
props:{
//定义属性counter_num,用来接收父组件传递的数据
counter_num:null,
//定义aaa属性,用来绑定父组件的方法,当然,该定义也可以省略
aaa:function(){},
//定义bbb属性,用来绑定父组件的方法,当然,该定义也可以省略
bbb:function(){},
},
methods:{
fun1(){
//找到aaa属性所绑定的那个方法,执行那个方法
return this.$emit("aaa");
},
fun2(){
//找到bbb属性所绑定的那个方法,执行那个方法
return this.$emit("bbb");
}
}
}
var app = new Vue({
el: '#app',
data: {
app_num: 0
},
components: {
counter
},
methods:{
add(){
this.app_num++;
},
rem(){
this.app_num--;
}
}
});
</script>
</html>
七、axios异步请求
axios概述
概述:
axios是一个基于 promise 的 HTTP 库, 主要用于:发送异步请求获取数据。
常见的方法:
axios(config)
axios.get(url, [config])
axios.post(url, [data])
发送数据config常用参数:
{
url: '请求的服务器',
method: '请求方式', // 默认是 get
// GET请求参数
params: {
参数名: 参数值
},
// POST请求参数, 如果使用axios.post,则参数在url之后直接书写,不需要该位置传递参数
data: {
参数名: 参数值
},
// 响应数据格式,默认json
responseType: 'json'
}
响应数据常用参数:
{
data: {}, //真正的响应数据(响应体)
status: 200, //响应状态码
statusText: 'OK', //响应状态描述
headers: {}, //响应头
config: {} //其他配置信息
}
Get请求
var app = new Vue({
el: "#app",
data: {
user: {}
},
//当页面加载完毕后
created() {
//发送GET请求axios.get("请求路径",{ config });
axios.get("请求路径",{
//get请求参数
params: {
name:"zhangsan",
age:23
},
//响应数据格式为"json"
responseType: 'json'
}).then(res => {
//打印响应数据
console.log(res);
//把响应数据赋值给Vue中的user属性
app.user = res.data;
}).catch(err => {
//打印响应数据(错误信息)
console.log(err);
});
}
});
Post请求
var app = new Vue({
el: "#app",
data: {
user: {}
},
//当页面加载完毕后
created() {
//发送POST请求axios.post("请求路径",{ 参数 });
axios.post("请求路径",{
name:"zhangsan",
age:23
}).then(res => {
console.log(res);
app.user = res.data;
}).catch(err => {
console.log(err);
});
}
});
VueJs Ajax
引入axios
首先就是引入axios,如果你使用es6,只需要安装axios模块之后
import axios from ‘axios’;
//安装方法
npm install axios //或 bower install axios
或者
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
八、使用Vue Cli 脚手架
初始化脚手架
说明
Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)
最新的版本是 4.x
文档:https://cli.vuejs.org/zh/
具体步骤
如果下载缓慢请配置 npm 淘宝镜像:npm config set registry http://registry.npm.taobao.org
全局安装@vue/cli:npm install -g @vue/cli
切换到你要创建项目的目录,然后使用命令创建项目:vue create xxxx
选择使用vue的版本
启动项目:npm run serve
暂停项目:Ctrl+C
Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置,请执行:
vue inspect > output.js
ref属性
ref属性:
被用来给元素或子组件注册引用信息(id的替代者)
应用在html标签上获取的是真实DOM元素,应用在组件标签上获取的是组件实例对象(vc)
使用方式:
打标识:<h1 ref="xxx"></h1> 或 <School ref="xxx"></School>
获取:this.$refs.xxx
props配置项
props配置项:
功能:让组件接收外部传过来的数据
传递数据:<Demo name="xxx"/>
接收数据:
第一种方式(只接收):props:['name']
第二种方式(限制数据类型):props:{name:String}
第三种方式(限制类型、限制必要性、指定默认值):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'JOJO' //默认值
}
}
props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据
mixin混入
功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
定义混入:
const mixin = {
data(){....},
methods:{....}
....
}
使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
备注:
<!--组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”,在发生冲突时以组件优先。-->
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data () {
return {
message: 'goodbye',
bar: 'def'
}
},
created () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
<!--同名生命周期钩子将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。-->
var mixin = {
created () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created () {
console.log('组件钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"
methods:{....}
....
}
使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
**备注:**
```javascript
<!--组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”,在发生冲突时以组件优先。-->
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data () {
return {
message: 'goodbye',
bar: 'def'
}
},
created () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
<!--同名生命周期钩子将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。-->
var mixin = {
created () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created () {
console.log('组件钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"