vue
vue项目创建:
1、初始化npm项目
npm init -y
2、安装vue
npm i vue@2 指定下载版本
npm install vue
3、html <!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="text" v-model="num" > // 双向绑定:v-model 数据发生改变 视图也要随之改变; <button v-on:click="num++">登录</button> <button v-on:click="loginout()">登出</button> <h1>{{name}},欢迎您,当前登录第{{num}}次,当前登录时间:{{nowDate()}}</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> // 1.new vue实例 每个Vue应用都是通过Vue函数创建一个新的Vue实例开始的 let vm=new Vue({ //el: "#app", // 挂载的模板 data: { // 绑定的数据 当数据属性的值发生改变时,视图会进行重新渲染, 响应式的 name: "图灵学院", num:1 }, methods: { // 写方法 nowDate(){ return new Date().toLocaleDateString() }, loginout(){ this.num--; } }, }).$mount("#app"); // 双向绑定:v-model 数据发生改变 视图也要随之改变; // 指令: 来简化对Dom的频繁操作 // 方法: 声明方法可以实现更复杂的操作,声明methods属性中 </script> </body> </html>
指令:
v-text/v-html: 指定标签体
v-text : 当作纯文本 v-text是元素的 InnerText 属性,它的作用和之前我们使用的 {{}} 一样,用于数据绑定: v-html : 将value作为html标签来解析 v-html是元素的 innerHTML,它用于绑定一段 html 标签:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>1、v-text&v-html</title>
</head>
<body>
<div id="app">
<div v-text="message"></div>
<!-- {{}} 在网络延迟情况下会出现暂显的情况 -->
{{message}}
<hr>
<div v-html="message"></div>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 1.实例Vue
var vm = new Vue({
el: '#app',
data: {
message: "<a href='#'>Hello</a>",
hrefx:"http://www.baidu.com"
},
})
// v-text 用于绑定数据, 语法v-text="属性" ,
// 会直接将值作为文本显示
// v-html
// 会将值进行编译再显示
</script>
</html>
v-bind : 属性绑定:
v-bind用于给元素的属性赋值。v-bind后面是 :属性名=[变量名]。例如:v-bind:title="message": 很多属性值是不支持表达式的, 就可以使用v-bind 代码解释: 在 HTML 代码第 17 行,我们使用了 v-bind 指令给 div 标签的 title 属性赋值。 在 HTML 代码第 21 行,我们使用了 v-bind 指令给 a 标签的 href 属性赋值。 在 HTML 代码第 24 行,我们使用了 v-bind 指令给 img 标签的 src 属性赋值。 在 HTML 代码第 27 行,我们使用了 v-bind 指令给 bitton 标签的 disabled 属性赋值。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>2、v-bind</title> <style> .red{ background-color: red; } </style> </head> <body> <div id="app"> <div v-bind:title="title" :class="{red:isred}" :style="{fontSize: bigFont}"> 鼠标悬停查看消息! </div> <div> <a :href="href">图灵学院</a> </div> <div> <img :src="src"/> </div> <div> <button v-bind:disabled="disabled">禁用按钮</button> </div> </div> </body> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { isred:true, bigFont:"50px", title: "您好,我是徐庶老师,欢迎来到图灵学院!希望你可以在图灵学院学到更多的东西!", href: 'https://www.tulingxueyuan.cn/', src: 'https://tuling--mall.oss-cn-chengdu.aliyuncs.com/20210114134341.png', disabled: true } }) // 绑定元素属性 -- v-bind /* 语法: v-bind:元素属性="vue的属性" 简写: v-bind:title 简写成 :title 针对样式的特殊用法 动态控制class是否添加 :class="{red:isred}" 语法 {red:isred} : {需要动态控制的class样式:vue的属性(需要是bool类型)} 动态设置style的样式::style="{fontSize: bigFont}" 语法{fontSize: bigFont} : {css样式的驼峰命名方式:vue的属性}: font-size=fontSize */ </script> </html>
v-model 双向数据绑定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div >
<label>年龄:</label>
<input v-model="age"/>
</div>
<div>当前输入的年龄是: {{age}}</div>
<button v-on:click="add">加一岁</button>
<button v-on:click="alertYear">弹出年龄</button>
<hr>
<label>课程:</label>
<select v-model="course">
<option value="java">java</option>
<option value="html">html</option>
<option value="csss">css</option>
</select>
<div>
<input v-model="course" type="radio" name="course" value="java">java
<input v-model="course" type="radio" name="course" value="html">html
<input v-model="course" type="radio" name="course" value="csss">csss
</div>
<div>当前课程是:{{course}}</div>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
course:'html',
age: 10
},
methods: {
add(){
this.age++;
},
alertYear() {
alert(this.age)
}
}
})
// v-model 用于实现双向绑定 一般用在表单元素
</script>
</html>
v-on : 绑定事件监听:
有时候,我们需要给元素绑定事件,vue 中提供了指令 v-on 来进行事件的绑定。用法:v-on:事件名="方法",例如:v-on:click=“alert”。
v-on:事件名, 可以缩写为: @事件名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="hello('hello')">hello</button>
<button @click="hello('world')">world</button>
<button @click="num++">数据</button>{{num}}
<!-- 不让事件传播 .stop
禁止默认a标签事件.prevent 阻止默认事件
.slef 必须要自身触发, 不会参与传播
.once 事件只会触发一次
-->
<div @click.once="hello('1')" style="background: red;width: 800px;height: 500px;padding: 50px;">
1
<div @click.stop="hello('2')" style="background: blue;width: 400px;height: 200px;padding: 50px;">
2
<a @click.stop.prevent="hello('3')" style="background: yellow;width: 200px;height: 100px;display: block;padding: 50px;" href="http://www.baidu.com">3</a>
</div>
</div>
<input v-on:keyup.ctrl="hello('space')">
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num:0
},
methods: {
hello(str) {
alert(str)
}
}
})
/*
v-on 用于绑定事件
语法 v-on:事件名
简写方式 v-on:click ---> @click
只能调用vue中的函数和数据
*/
</script>
</html>
v-for : 遍历
v-for 用于列表的循环渲染。基本语法:v-for="item in data",data 可以是数组或者对象,接下来我们介绍对两种数据类型的循环。 遍历数组 : v-for="person in persons" $index
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>循环</title> </head> <body> <div id="app"> 循环数组 <ul> <li v-for="(item, index) in music">{{item.name}}---{{index+1}}</li> </ul> 循环对象 <ul> <li v-for="(item, index) in obj">{{item}}</li> </ul> </div> </body> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> var vm = new Vue({ el: '#app', data:{ // 要循环的数组 music: [ { name: '青花瓷' }, { name: '阳光总在风雨后' }, { name: '十年' } ], // 要循环的对象 obj: { name: '句号', age: 18, sex: '男' } } }) /* v-for 循环, 可以循环数组和对象 语法:v-for="(每次循环接收的变量, 当前循环的索引) in 需要循环的变量" */ </script> </html>
v-if v-else v-show
vue提供了v-if和v-show两个指令来控制页面元素的显示和隐藏。我们先通过一段代码来看一下使用两个指令各有什么效果: v-if : 如果vlaue为true, 当前标签会输出在页面中 v-show: 就会在标签中添加display样式, 如果vlaue为true, display=block, 否则是none v-else : 与v-if一起使用, 如果value为false, 将当前标签输出到页面中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<button @click="vif=!vif">切换显示隐藏</button>
<div v-if="vif" style="background-color: red; width: 200px; height: 200px;">
v-if
</div>
<hr>
<button @click="vshow=!vshow">切换显示隐藏</button>
<div v-show="vshow" style="background-color: yellow; width: 200px; height: 200px;">
v-show
</div>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
vif: true,
vshow: true
}
})
/*
v-if 和v-show 用于控制元素显示隐藏 ,
语法 v-if ="指定bool值" v-show一样
v-if 控制元素是否生成
v-show 控制元素是否显示隐藏
*/
</script>
</html>
上面我们已经了解了v-if的使用方法。事实上,v-if的条件渲染和JavaScript条件判断语句中的if、else、else if非常类似。 v-else、v-else-if : 与v-if一起使用, 如果value为false, 将当前标签输出到页面中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-if="number == 1">
A
</div>
<div v-else-if="number == 2">
B
</div>
<div v-else>
C
</div>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data() {
return {
number: 3
}
}
})
</script>
</html>
过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>过滤器</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="user in userList">
姓名:{{user.name}};性别:{{formateGender(user.gender)}}
{{user.gender | filterGender}} // 过滤器
</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'xushu', gender: 1 },
{ id: 2, name: 'zhuge', gender: 0 }
]
},
methods: {
formateGender(gender){
if(gender==1){
return "~男"
}else{
return "~女"
}
}
},
// 专门针对数据过滤
filters:{ // 过滤器
filterGender(gender){
if(gender==1){
return "!男"
}else{
return "!女"
}
}
}
})
</script>
</body>
</html>
计算属性和侦听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>计算属性和侦听器</title>
</head>
<body>
<div id="app">
<!-- 实现一个购物车功能
1. 数据初始化处理
2.计算商品总价
3.选择商品数量:当商品数量超过库存做提示
-->
<ul>
<li v-for="(item, index) in car" >
{{item.pname}} --- 商品价格:{{item.price}} --- 库存:{{item.stock}}
数量:<input type="number" v-model="item.num" style="width: 30px;" />
</li>
<li><strong>总价:</strong>{{calcSum}}</li>
<li v-html="message"></li>
<li v-html="warn()"></li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
car:[
{pname:'Iphone 12',price:7999,stock:10,num:1},
{pname:'小米11',price:3599,stock:3,num:4},
],
message:"",
},
// methods : 当方法中使用的数据发生改变,方法会自动调用
methods: {
// calcSum(){
// let sum=0;
// this.car.forEach(item => {
// sum+=item.price*item.num;
// });
// return sum;
// }
warn(){
let message="";
this.car.forEach(item => {
if(item.num>item.stock){
message+=`${item.pname}的库存超出限制<br/>`
}
});
return message;
}
},
// 计算属性: 当方法中使用的数据发生改变,方法会自动调用
computed:{
calcSum(){
let sum=0;
this.car.forEach(item => {
sum+=item.price*item.num;
});
return sum;
}
},
// 侦听器 专门用于侦听数据的变化,当数据发生变化会自动调用方法
watch:{
// 要侦听的数据: 数组
car:{
handler(newvalue,oldvalue){
this.message="";
this.car.forEach(item => {
if(item.num>item.stock){
this.message+=`${item.pname}的库存超出限制<br/>`
}
});
},
deep:true //深度侦听器,只有监听数组、对象才用deep属性
},
// 基础类型的侦听, 将侦听数据作为函数就可以了
message(newvalue,oldvalue){
console.info(newvalue,oldvalue)
}
}
});
/*
方法和计算属性的区别:
声明发生不一样,调用不一样方法要用(), 计算属性调用不要加()
*/
/*
方法和侦听器的区别:
方法: 方法中任意数据发生了改变就会自动调用方法
可以调用,进行返回值
侦听器:需要指定具体的侦听数据,只有被具体指定的侦听数据发生了改变才会触发
不能像方法那样去调用, 而是靠vue自动触发
*/
</script>
</body>
</html>
组件化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>组件化</title>
</head>
<body>
<div id="app">
<xushu :num="numxx"></xushu>
<app-xushu></app-xushu>
</div>
<hr>
<div id="app2">
<xushu :num="numxx"></xushu>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 1.全局組件: 在所有的Vue实例中使用
/*
1.1 命名:不要使用驼峰命名, 可以使用中划线的方式命名
1.2 模板: 必须的
1.3 数据:一定要函数的方式声明
1.4 xushu 作为标签使用 <xushu :num="numxx"></xushu>
*/
Vue.component("xushu",{ // (子实例)
template: ` <div @click='num++'>{{num}}</div>`,
// data() {
// return {
// num:10
// }
// },
props:["num"] // 声明变量
})
// 2.局部组件 <app-xushu></app-xushu>
const appXushu={
template: ` <div @click='num++'>{{num}}</div>`,
data() {
return {
num:66
}
},
}
new Vue({ // (父实例)
el: "#app",
data: {
numxx: 50
},
components:{ // 局部组件
"app-xushu":appXushu
}
})
new Vue({
el: "#app2",
data: {
numxx: 100
}
})
</script>
</body>
</html>
生命周期和钩子函数

从上面这幅图中,我们可以看到 vue 生命周期可以分为八个阶段,分别是: beforeCreate(创建前) created(创建后) beforeMount (载入前) mounted(载入后) beforeUpdate(更新前) updated(更新后) beforeDestroy(销毁前) destroyed(销毁后) 3.1 创建前(beforeCreate) 在实例初始化之后,此时的数据观察和事件机制都未形成,不能获得 DOM 节点。 3.2 创建后(created) 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始。 3.3 载入前(beforeMount) 在挂载开始之前被调用:这个过程是在模版已经在内存中编译完成, render 函数首次被调用,此时完成了虚拟 DOM 的构建,但并未被渲染。 3.4 载入后(mounted) 这个过程在模版挂载之后被调用,页面完成渲染,所以在这之后,我们可以操作和访问 DOM 元素。 3.5 更新前(beforeUpdate) 当数据更新时调用,在这一阶段 DOM 会和更改过的内容同步。 3.6 更新后(updated) 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。 3.7 销毁前(beforeDestroy) 实例销毁之前调用。在这一步,实例仍然完全可用。 3.8 销毁后(destroyed) Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id = "app">
<span id="name">{{ name }}</span>
<button @click="updateName">更新</button>
<button @click="destroy">销毁</button>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type = "text/javascript">
var vm = new Vue({
el: '#app',
data: {
name:'hello !'
},
methods : {
updateName() {
console.log('准备修改名字啦!')
this.name = 'hello 图灵!'
},
destroy(){
vm.$destroy()
}
},
beforeCreate() {
// 此时页面数据未初始化
console.log('beforeCreate:' + this.name) // beforeCreate: undefined
},
created() {
// 页面数据已经初始化
console.log('created:' + this.name) // beforeCreate: hello !
},
beforeMount() {
console.log('beforeMount:' + this.name) // beforeCreate: hello !
console.log("html模板未渲染:" + document.getElementById("name").innerText);
},
mounted() {
console.log('mounted:' + this.name) // beforeCreate: hello !
console.log("html模板已渲染:" + document.getElementById("name").innerText);
},
// 点击更新按钮后会先触发 beforeUpdate
beforeUpdate() {
console.log('beforeUpdate:' + this.name) // beforeCreate: hello
console.log("html模板未更新:" + document.getElementById("name").innerText);
},
updated() {
console.log('updated:' + this.name) // updated hello 图灵 !
console.log("html模板已更新:" + document.getElementById("name").innerText);
},
// 点击销毁按钮后会先触发 beforeDestroy
beforeDestroy(){
console.log('beforeDestroy: before destroy') // beforeDestroy: before destroy
console.log("销毁前:" + document.getElementById("name").innerText);
},
destroyed(){
console.log('destroyed: success') // destroyed: success
// 在这之后点击页面 更新 按钮将无任何效果
console.log("销毁后:" + document.getElementById("name").innerText);
}
});
</script>
</html>
路由:vue-router
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div>
<!-- <a href="/5、vue路由器.html#/index">首页</a>
<a href="#">商品</a> -->
<router-link to="/index">首页</router-link>
<router-link to="/product">商品</router-link>
<router-view></router-view> // 自动将模板放入到 <router-view></router-view> 中
</div>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<!-- 1.安装vue-router路由
2.引入vue-router文件
3.要根据不同url链接到不同的页面, 需要使用模板实现, 将模板绑定对应的路由地址
-->
<script src="./node_modules/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
let Index = Vue.component("index", {
template: `<div>Hello,欢迎使用来到图灵商城!</div>`
});
let Product = Vue.component("product", {
template: `<ul><li>1. Iphone11</li><li>2. 小米11</li></ul>`
});
// 4.使用路由管理模板, 将url跟模板进行绑定
const router = new VueRouter({
routes: [{
path: "/index",
component: Index
},
{
path: "/product",
component: Product
},
]
})
var vm = new Vue({
el: '#app',
router
})
</script>
</html>
axios:
特性
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF
安装
使用 npm:
$ npm install axios
<!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">
<ul>
<li v-for="(item, index) in users">
{{item}}
</li>
</ul>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script src="./node_modules/axios/dist/axios.js"></script>
<script>
//1. 还没有调用getAllUsers方法
let vm = new Vue({
el: "#app",
data() {
return {
users:[]
}
},
mounted() {
this.getAllUsers();
},
methods: {
getAllUsers() {
axios.get('http://localhost:8811/user/getAllUsers'
//, {
// params: {
// ID: 12345
// }
// }
)
// 当使用箭头函数 this 指向的是外层
.then(response =>{
this.users=response.data.data;
})
.catch(function (error) {
console.log(error);
});
}
},
})
</script>
</html>
执行 GET 请求 // 上面的请求也可以这样做 axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
执行 POST 请求 axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
执行多个并发请求 function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(), getUserPermissions()]) .then(axios.spread(function (acct, perms) { // 两个请求现在都执行完成 }));
使用Vue脚手架进行模块化开发
1、安装vue-cli npm install -g @vue/cli 2. 安装初始化工具 npm i -g @vue/cli-init 3. 创建项目 vue init webpack 项目名

4、运行项目 npm run dev // 执行的是 webpack.dev.conf.js 模块
5、引用axios F:\web\es\vue3> npm install axios F:\web\es\vue3> npm install vue-axios


浙公网安备 33010602011771号