什么是vue
官网
视频
Vue.js是一套用于构建用户界面的JavaScript渐进式框架
开发工具
使用VSCode开发vue
- VSCode安装插件
- 中文插件Chinese (Simplified) Language Pack for Visual Studio Code
- 实时加载Live Server插件
- 浏览器打开Open In Browser
- 自动生成html代码整体结构HTML Boilerplate
- 自动提示vue插件vuehelper
- 浏览器安装插件方便vue调试
vue-devtools插件
vue.js引入项目
独立引入
我们可以在 Vue.js 的官网上直接下载vue.min.js 并用
cdn引入
https://cdn.jsdelivr.net/npm/vue/dist/vue.js
https://cdn.jsdelivr.net/npm/vue
对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:
npm引入
在用 Vue 构建大型应用时推荐使用 NPM 安装;
命令行工具 (CLI)
Vue 提供了一个官方的 CLI,可以快速搭建繁杂的Vue项目脚手架;
VUE对象
引入了vue.js后,在页面就可以创建一个Vue对象,每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
var vm = new Vue({
//选项
})
通过这些选项来创建你想要的行为,选项对象非常多,可以参考api文档:
https://cn.vuejs.org/v2/api/
- Vue构造器:
1、el 选项,表示dom中的element,用el指定 DOM 元素中的 id;
2、data 选项,用于定义属性/数据; - 页面展示数据采用模板语法:
1、{{ }} 用于输出对象属性或函数返回值;
2、整体上代码分为:视图 + 脚本(数据);
3、视图部分实际上是一种简洁的模板语法来声明式地将脚本里的数据渲染到DOM中;
4、通过浏览器控制台vue-devtools插件,更新控制台的数据,页面视图数据也会同步更新;
5、new Vue 创建了一个Vue应用的根对象,Vue根对象提供了一些有用的属性和方法供我们使用,这些属性和方法都有前缀 $
Vue.js模板语法
视图部分实际上Vue.js 使用了基于 HTML 的模版语法,允许开发人员声明式地将 DOM 和底层 Vue 实例数据绑定在一起;
- Vue.js给我们提供了14个指令用于页面的渲染:
(1){{ }}:插值表达式,用来显示data中的数据,在网速慢的时候会显示大括号,不会覆盖表签内的内容
(2)v-text:用来展示data中的数据,在网速慢的时候不会显示插值函数,会覆盖标签内的内容,不会解析html标签
(3)v-html:用来展示data中的数据,在网速慢的时候不会显示插值函数,会覆盖标签内的内容,会对html标签进行解析
(4)v-show:用来控制页面的标签元素是否展示 底层通过控制元素的display属性来进行标签的展示和隐藏
(5)v-if:用来控制页面的标签元素是否展示 底层通过对dom树节点进行添加和删除来控制展示和隐藏
(6)v-else-if:用来进行判断
(7)v-else:用来进行判断
(8)v-for:进行遍历 v-for="(value,key,index) in 遍历对象" :key=“id” :key便于vue内部做重用和排序
(9)v-on:用来给标签绑定事件,v-on:事件 可以省略为 @事件
(10)v-bind:用来给页面中的标签元素绑定相应的属性,v-bind:属性名 可以省略为 :属性名
(11)v-model:用于双向绑定
(12)v-slot
(13)v-pre:使插值表达式失效,直接显示{{key}}
(14)v-cloak
(15)v-once:数据只加载一次
v-on绑定事件
监听DOM事件,并在触发时运行JavaScript代码,可以缩写为:@;
- 为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
**keydown事件发生在键盘的键被按下的时候,接下来触发keypress事件,keyup 事件在按键被释放的时候触发;
**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test08</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<p>
<a href="javascript:void(0)" v-on:click="sayHello">点击我</a> {{message}}
</p>
<p>
<a href="javascript:" @click="sayHello">点击我</a> {{message}}
</p>
<p>
<a href="javascript:" @click="sayHello2('zhangsan')">点击我</a>
</p>
<p>
<a href="javascript:" @click.once="sayHello2('zhangsan')">点击我</a>
</p>
<p>
<input v-on:keyup.tab="onEnter">
</p>
<p>
<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">
</p>
</div>
<script>
var vm = new Vue({
el: '#app',
//数据
data: {
message: "嗨,动力节点"
},
//函数方法
methods: {
sayHello: function () {
this.message = this.message.split('').reverse().join('')
},
sayHello2: function (name) {
alert(111)
this.message = 'hello, ' + name
},
onEnter: function() {
this.message = "按下Enter键了.111"
}
}
})
</script>
</body>
</html>
v-bind绑定属性
v-bind可以省略,只写:
例子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test09</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<div class="classStyle">
1、class 指令
</div>
<div v-bind:style="classStyle">
2、v-bind:class 指令
</div>
<div :class="'classStyle'">
3、:class 指令
</div>
<div v-bind:style="style1">
4、v-bind:style 指令
</div>
<div :style="style1">
:style 指令
</div>
<p>
<img v-bind:src="imageSrc">
</p>
<a v-bind:title="title">v-bind:title指令</a><br/>
<a :title="title">:title指令</a>
<div v-bind:id="'java-' + id">动力节点</div>
<div :id="'list-' + id">动力节点</div>
<p>
<a v-bind:href="url">动力节点</a><br />
<a :href="url">动力节点</a>
</p>
<input id="" name="" value="动力节点">
<input id="" name="" v-bind:value="message">
</div>
<script>
new Vue({
el: '#app',
data: {
style1: "color:green;",
title: "这是链接的提示文字",
message: '动力节点',
classStyle : 'color: red;',
id: 10,
url: "http://www.bjpowernode.com",
imageSrc : "http://www.bjpowernode.com/Public/static/uploads/index/banner/20210413/1618301238@959d4566df1108f31b681f7a0817a67a.jpg"
}
})
</script>
<style>
.classStyle {
color: red;
}
</style>
</body>
</html>
v-model双向绑定
在表单控件或者组件上创建双向绑定,一般用在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值;
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test10</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
-->
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
1、<br/>
<input type="text" v-model="message" placeholder="请输入"> <span>{{ message }}</span>
<br/><br/>
2、<br/>
千米 : <input type="text" v-model="kilometers"> <span>{{ kilometers }}</span> <br/>
米 : <input type="text" v-model="meters"> <span>{{ meters }}</span>
<br/><br/>
3、<br/>
<p>textarea元素:</p>
<textarea v-model="content" placeholder="多行文本输入……"></textarea>
<span>{{ content }}</span>
<br><br>
4、<br/>
<input type="radio" id="taobao" value="taobao" v-model="picked">
<span>taobao</span>
<br>
<input type="radio" id="baidu" value="baidu" v-model="picked">
<span>baidu</span>
<br>
<span>选中值为: {{ picked }}</span>
<br><br>
5、<br/>
<p>单个复选框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<span>{{ checked }}</span>
<br><br>
6、<br/>
<p>多个复选框:</p>
<input type="checkbox" id="baidu" value="baidu" v-model="checkedNames">
<span>baidu</span>
<input type="checkbox" id="weibo" value="weibo" v-model="checkedNames">
<span>weibo</span>
<input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
<span>taobao</span>
<br><br>
<span> 选择的值为: {{ checkedNames }} </span>
<br><br>
7、<br/>
<select v-model="selected" name="fruit">
<option value="">请选择</option>
<option value="www.taobao.com">taobao</option>
<option value="www.baidu.com">baidu</option>
</select>
<div>
选择的网站是: {{selected}}
</div>
</div>
<script>
var vm= new Vue({
el: '#app',
data: {
message: '动力节点',
kilometers: 0,
meters: 0,
name: "动力节点",
content: '口口相传的Java黄埔军校!',
picked: 'taobao',
checked: false,
checkedNames: [],
selected: ''
}
})
</script>
</body>
</html>
Vue.js 是一个典型的 MVVM(Model-View-ViewModel)模型框架,MVVM 由MVC演化而来,View的变动,会自动更新到ViewModel,ViewModel的变动,也会自动更新到View,这种机制叫做双向绑定;
这也是Vue.js相较于传统JavaScript DOM编程的优势,通过这种数据双向绑定,我们可以轻松实现视图与数据的解耦:
v-pre
比如下面的代码:
{{ this will not be compiled }}
将显示的是 {{ this will not be compiled }}
{{ msg }}
即使data里面定义了msg这里仍然是显示的{{ msg }}
v-clock
在使用 {{ }} 展示或更新页面数据时,当网速比较慢时,会出现一个体验不好的过渡现象,会让用户先看到 {{ }} 表达式,即页面中的{{ msg }},然后才看到data中的值,即所谓的闪烁问题
- 解决这个问题的方法:
1、使用v-cloak指令,然后为其设置css样式display:none;
但有时添加完毕后变量仍会显示,即闪烁问题没解决,原因是 v-cloak 的display属性被其他优先级高的样式覆盖所导致,所以最好再添加一个 !important ,将其优先级设置为最高,防止被其他优先级高的dispaly:none样式所覆盖;
2、使用v-text解决,v-text没有闪烁问题,{{ }} 存在闪烁的问题;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test12</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
</head>
<body>
<div id="app">
<p v-cloak>{{ msg }}</p>
<p v-text="msg"></p>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: '欢迎使用Vue!'
}
})
</script>
<style>
[v-cloak] {
display: none !important;
}
</style>
</body>
</html>
v-once
使用了此指令的元素/组件及其所有的子节点,只会渲染元素和组件一次,随后都会跳过渲染,当作静态内容处理,这可以用于优化更新性能;
vue.js常用选项
数据
- data
Vue实例的数据对象; - computed
计算属性,进行一些运算逻辑,对数据进行处理等;
在模板内的直接使用表达式也非常便利,但是这种方式设计的初衷是用于简单运算,在模板中放入太多的逻辑会让模板过重且难以维护,所以此时就提供了computed计算属性的选项;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test03</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
千米 : <input type="text" v-model="kilometers">
米 : <input type="text" v-model="meters">
<p>原始字符串: {{ message }}</p>
<p>计算后反转字符串: {{ message.split('').reverse().join('') }}</p>
<p>计算后反转字符串: {{ reversedMessage }}</p>
<p>现在时间:{{ now }}</p>
<p>现在时间:{{ now2 }}</p>
<p>网站信息:{{ site }} </p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
kilometers: 10,
meters: 10000,
message: '动力节点-口口相传的Java黄埔军校',
url: 'http://www.bjpowernode.com'
},
//计算属性,返回属性运算后的结果
computed: {
reversedMessage: function () {
//`this`指向vue实例
return this.message.split('').reverse().join('')
},
now: function () {
return Date.now()
},
now2() {
return Date.now()
},
site: {
//computed计算属性默认提供getter方法
get: function () {
return this.message + ' -- ' + this.url
}
}
}
});
</script>
</body>
</html>
- methods
methods 选项主要定义了一些执行函数; - computed 与 methods
1、computed是计算属性,比如你要根据data里一个值随时变化做出一些处理,就用computed;(这里是属性调用)
2、methods里面是定义很多函数,比如你点击事件要执行一个函数,这时候就用methods;
(这里是方法调用) - watch
watch选项可以监听值的变化;
DOM
-
el
把页面上已存在的 DOM 元素作为 Vue 实例的挂载目标; -
template
用模板内容 替换 挂载元素的内容,挂载元素的内容都将被模板替换;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test09</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<template id="template">
<span>
<h1 style="color:red">这是一个模板内容</h1>
<h1 style="color:red">这是一个模板内容</h1>
<h1 style="color:red">这是一个模板内容</h1>
<h1 style="color:red">这是一个模板内容</h1>
<h1 style="color:red">这是一个模板内容</h1>
</span>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {
message: "这个是正文内容"
},
template: '#template'
})
</script>
</body>
</html>
写法二:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test10</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script type="x-template" id="template">
<span>
<h1 style="color:red">这是一个script标签模板</h1>
<h1 style="color:red">这是一个script标签模板</h1>
<h1 style="color:red">这是一个script标签模板</h1>
</span>
</script>
<script>
var vm = new Vue({
el: '#app',
data: {
message: "这个是正文内容"
},
template: '#template'
})
</script>
</body>
</html>
生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等,同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会;
- 生命周期钩子有如下这些:
初始化阶段
- beforeCreate:该函数在执行时vue实例仅仅完成了自身事件的绑定和生命周期函数的初始化工作,vue实例中还没有data,el,methods相关属性
- created:该函数在执行时vue实例已经完成了初始化data属性和methods中相关方法
- beforeMount:该函数在执行时vue将el中指定作用范围作为模板进行编译,数据还没有渲染完毕
- mounted:该函数在执行过程中,已经将数据渲染到界面中并且已经更新页面
运行阶段 - beforeUpdate:该函数时data中的数据发生变化时执行,这个事件执行时仅仅是vue中data数据发生变化,页面中的数据还是原始数据
- updated:该函数执行时data中的数据发生变化,页面中的数据也发生了变化
销毁阶段 - beforeDestroy:该函数执行时,vue中的数据data、el、methods都没有销毁
- destroyed:该函数执行时,vue中的数据data、el、methods都销毁了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test11</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: "动力节点"
},
methods: {
showMessage : function() {
console.log("showMessage()方法执行.")
}
},
beforeCreate() {
console.log('------------beforeCreate--------------');
console.log(this.message);
this.showMessage();
},
created() {
console.log('------------created--------------');
console.log(this.message);
this.showMessage();
},
beforeMount() {
console.log('------------beforeMount--------------');
console.log(this.message);
this.showMessage();
},
mounted() {
console.log('------------mounted--------------');
console.log(this.message);
this.showMessage();
},
beforeUpdate() {
console.log('------------beforeUpdate--------------');
console.log(this.message);
this.showMessage();
},
updated() {
console.log('------------updated--------------');
console.log(this.message);
this.showMessage();
},
beforeDestroy() {
console.log('------------beforeDestroy--------------');
console.log(this.message);
this.showMessage();
},
destroyed() {
console.log('------------destroyed--------------');
console.log(this.message);
this.showMessage();
},
errorCaptured() {
console.log('------------errorCaptured--------------');
console.log(this.message);
this.showMessage();
}
})
</script>
</body>
</html>
资源
filters
Vue.js 允许自定义过滤器,常用于一些文本格式化,由 “管道符” 连接;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test12</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
<p>
{{ message | capitalize | capitalize2 }}
</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'www.bjpowernode.com'
},
methods: {
},
filters: {
//把字符变成大写
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.toUpperCase()
},
capitalize2: function (value) {
if (!value) return ''
value = value.toString()
return value.substring(0,5)
}
}
})
</script>
</body>
</html>
事件修饰符
作用:用来和事件连用,用来决定事件触发的条件或者阻止事件触发的机制
常用的事件修饰符
- stop
- prevent
- capture
- self
- once
- passive
stop
用来阻止事件冒泡
案例
<div id="app">
<div id="aa" @click="divClick">
<!-- 会产生事件冒泡,点击按钮后div也被点击了-->
<input type="button" value="按钮" @click="butClick">
<br>
<!-- 不会产生事件冒泡,只有按钮被点击-->
<input type="button" value="按钮" @click.stop="butClick">
</div>
</div>
<script>
const vm = new Vue({
el:"#app",
data:{},
methods: {
butClick(){
alert("按钮被点击了")
},
divClick(){
alert("div被点击了")
}
}
})
</script>
prevent
用来阻止标签的默认行为
<!-- 不会跳转到百度-->
<a href="https://www.baidu.com" @click.stop.prevent="aClick">百度</a>
self
用来针对当前标签的事件触发,只出发自己标签上特定的动作
<div id="app">
<div id="aa" @click.self="divClick">
</div>
</div>
once
指定事件只触发一次
<input type="button" value="按钮" @click.once="butClick">
按键修饰符
用来与键盘中的按键事件绑定在一起,用来修饰特定的按键修饰符
常用的按键
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
<!--按所有键都会触发-->
<input type="text" @keyup="keyups">
<!--只有按enter键的时候才会触发-->
<input type="text" @keyup.enter="keyups">
promise
Promise是JavaScript异步编程解决方案之一,是为了解决请求回调地狱问题而提出的,是目前解决Javascript异步编程中最优雅的实现方案,在业界非常流行;
Promise是基于Promise / A++规范:https://promisesaplus.com/ ;
Promise有各种开源实现,在ECMAScript 6中被统一规范,由浏览器直接支持,在不支持ECMAScript 6的浏览器中不被支持,先测试一下你的浏览器是否支持Promise:
<script type="text/javascript">
new Promise(()=>{})
</script>
如果不报错,表示支持Promise;
回调地狱问题
调用嵌套太多,不好看和修改,使用promise便于查看和修改代码
$.ajax({
url: 'https://www.baidu.com',//地址随便写的
type: 'GET',
success: function (res) {
$.ajax({
url: 'https://www.taobao.com',//地址随便写的
type: 'GET',
data: {
accountId: 20210512
},
success:function(res){
$.ajax({
url: 'https://www.tencent.com',//地址随便写的
type: 'GET',
data: {
accountId: 20210512
},
success:function(res){
$.ajax({
url: 'https://www.douban.com',//地址随便写的
type: 'GET',
data: {
accountId: 20210512
},
success:function(res){
console.log(res);
}
});
}
});
}
});
}
});
$.ajax()中回调函数嵌套过多,回掉函数中再嵌套回调,导致回调地狱,那么Promise解决了回调地狱问题;
语法
new Promise(( reslove, reject ) =>{})
- 其中括号里面的 ( reslove, reject ) =>{} 是箭头函数;
• Promise构造器接收一个函数作为参数
• 这个函数中又可以接收两个参数,这两个参数又是函数;
• resolve: 是处理成功的函数
• reject: 是处理失败的函数 - 最少传一个参数,也可以传多个参数,但是第二个参数以后的参数都没有用
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test01</title>
</head>
<body>
<div id="app">
Promise test01
</div>
<script type="text/javascript">
//构造方法需要有参数
// var p = new Promise()
// console.log(p)
// var a = new Promise(() => {})
// console.log(a)
var b = new Promise((reslove) => {})
console.log(b)
var c = new Promise((reslove, reject) => {})
console.log(c)
var d = new Promise((reslove, reject, err, aa, bb, cc) => {})
console.log(d)
</script>
</body>
</html>
promise实例对象
创建出来的promise实例有两个属性
• PromiseState: 状态属性
• PromiseResult: 结果属性
- Promise的状态
第一种状态: pending,未处理,等待处理的一种状态;
第二种状态: fulfilled,已处理,处理成功的一种状态;
第三种状态: rejected,已处理,处理失败的一种状态;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test02</title>
</head>
<body>
<div id="app">
Promise test02
</div>
<script type="text/javascript">
var c = new Promise((reslove, reject) => {
//调用该函数, 使当前Promise对象的状态改成fulfilled
reslove()
//调用该函数, 使当前Promise对象的状态改成rejected
reject()
})
console.log(c)
</script>
</body>
</html>
- Promise状态的改变
Promise状态的改变是一次性的,不能同时fulfilled又rejected; - Promise的结果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test03</title>
</head>
<body>
<div id="app">
Promise test03
</div>
<script type="text/javascript">
var c = new Promise((reslove, reject) => {
//通过调用reslove函数传递参数,改变当前Promise对象的结果
//reslove("成功的结果");
reject("失败的结果")
})
console.log(c)
</script>
</body>
</html>
promise方法
then方法
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test04</title>
</head>
<body>
<div id="app">
Promise test04
</div>
<script type="text/javascript">
var p = new Promise((resolve, reject) => {
//通过调用reslove函数传递参数,改变当前Promise对象的结果
resolve("成功的结果");
//reject("失败的结果")
})
console.log(p)
//then方法函数
//两个参数都是函数
//返回值: 是一个Promise对象
p.then(
()=>{
//当Promise的状态是fulfilled时执行
console.log("成功的回调")
},
()=>{
//当Promise的状态是rejected时执行
console.log("失败时调用")
}
)
</script>
</body>
</html>
1)在then方法的参数函数中,通过形参使用Promise对象的结果
举例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test06</title>
</head>
<body>
<div id="app">
Promise test06
</div>
<script type="text/javascript">
var p = new Promise((resolve, reject) => {
//通过调用reslove函数传递参数,改变当前Promise对象的结果
//resolve("成功的结果");
reject("失败的结果")
})
console.log(p)
//then方法函数
//两个参数都是函数
//返回值: 是一个Promise对象
p.then((msg)=>{
//当Promise的状态是fulfilled时执行
console.log("成功的回调", msg)
},(msg)=>{
//当Promise的状态是rejected时执行
console.log("失败时调用", msg)
})
</script>
</body>
</html>
2)Promise的状态不改变,不会执行then里的方法
3)在then方法中,通过return将返回的Promise实例改为fulfilled或rejected状态
举例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test08</title>
</head>
<body>
<div id="app">
Promise test08
</div>
<script type="text/javascript">
//如果Promise的状态改变,then里的方法不会执行
var p = new Promise((resolve, reject) => {
resolve("执行成功")
})
var t = p.then((msg) => {
console.log("成功", msg)
//使用return可以将t实例的状态改为fulfilled
return "OK"
}, (reason) => {
console.log("失败")
})
var r = t.then((msg) => {
console.log("成功2", msg)
}, (reason) => {
console.log("失败2")
})
</script>
</body>
</html>
4)在then方法中,出现代码错误,将返回的Promise实例改为rejected状态
举例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test09</title>
</head>
<body>
<div id="app">
Promise test09
</div>
<script type="text/javascript">
//如果Promise的状态改变,then里的方法不会执行
var p = new Promise((resolve, reject) => {
resolve("执行成功")
})
var t = p.then((msg) => {
//msg1变量不存在,发生错误,则t实例的状态变成reject
console.log("成功", msg1)
//使用return可以将t实例的状态改为fulfilled
return "OK"
}, (reason) => {
console.log("失败")
})
t.then((msg) => {
console.log("成功2", msg)
}, (reason) => {
console.log("失败2", reason)
})
</script>
</body>
</html>
catch方法
可以捕获异常,统一处理失败
举例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test10</title>
</head>
<body>
<div id="app">
Promise test10
</div>
<script type="text/javascript">
//catch中的参数函数在什么时候被执行
//1.当Promise的状态改为rejcted被执行
//2.当Promise执行体重出现代码错误时被执行
var p = new Promise((resolve, reject) => {
//reject("失败")
//console.log(a)
throw new Error("出错了");
})
var t = p.then((msg) => {
console.log(msg)
})
t.catch((err) => {
console.log("catch", err)
})
</script>
</body>
</html>
Promise链式调用
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test11</title>
</head>
<body>
<div id="app">
Promise test11
</div>
<script type="text/javascript">
new Promise((resolve, reject) => {
resolve("执行成功")
}).then((msg) => {
console.log(msg)
return "OK"
}).then((msg) => {
console.log(msg)
return "SUCCESS"
}).then((msg) => {
console.log(msg)
console.log(msg2)
}).catch((err) => {
console.log(err)
})
</script>
</body>
</html>
使用promise封装传统ajax
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/jquery-3.6.0.min.js"></script>
<title>test12</title>
</head>
<body>
<div id="app">
Promise test12
</div>
<script type="text/javascript">
//封装ajax请求
function getData(url, data = {}) {
return new Promise((resolve, reject) => {
$.ajax({
//发送请求类型
type: "GET",
url: url,
data: data,
success: function (res) {
// 修改Promise状态为成功, 修改Promise的结果res
resolve(res)
},
error: function (res) {
// 修改Promise的状态为失败,修改Promise的结果res
reject(res)
}
})
})
};
//调用函数
getData("http://localhost:8080/info")
.then((res) => {
console.log(res)
const { id } = res //对象解构赋值,ECMAScript 6里面的特性
return getData("http://localhost:8080/info2", { id })
}).then((res) => {
console.log(res)
const { name } = res
return getData("http://localhost:8080/info3", { name })
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
</script>
</body>
</html>
Vue.js之Ajax(axios)
Vue.js,包括React.js都推荐使用 axios 来完成 ajax 请求;
axios 是一个基于 Promise的HTTP库,可以用在浏览器和node.js中;
Github开源地址:https://github.com/axios/axios
官方网站:https://axios-http.com/ (还有中文文档)
中文文档:https://axios-http.com/zh/docs/intro
安装方法
方法1、直接下载js文件导入到页面中
方法2、使用 cdn:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
方法3、使用npm:
$ npm install axios
get方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test14</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
{{ info }}
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data() {
return {
info: null
}
},
mounted() {
// axios.get('http://localhost:8080/user?id=12345')
// .then(response => {
// this.info = response
// console.log(response);
// }).catch(error => {
// console.log(error);
// })
// axios.get('http://localhost:8080/user', {
// params: {
// id: 12345,
// name: "cat"
// }
// }).then(response => {
// this.info = response
// console.log(response);
// console.log(a)
// }).catch(error => {
// this.info = error
// console.log(error);
// })
//async/await是ECMAScript 2017的一部分,在Internet Explorer和旧浏览器中不受支持,因此请谨慎使用;
async function getUser() {
try {
console.log("000");
const response = await axios.get('http://localhost:8080/user?id=12345');
console.log(response);
this.info = response
console.log("111");
} catch (error) {
console.error(error);
}
console.log("333");
}
//调用
getUser()
}
})
</script>
</body>
</html>
post方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test15</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
{{ info }}
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data() {
return {
info: null
}
},
mounted() {
axios.post('http://localhost:8080/user2', {
id: 123,
name: 'cat'
}).then((response) => {
this.info = response
console.log(response);
})
.catch((error) => {
console.log(error);
});
}
})
</script>
</body>
</html>
AXIOS并发请求
将多个请求在同一时刻发送到后台服务器接口,最后集中处理每个请求的响应结果
axios.all([请求function()])
<script>
function f1 (){
return axios.get("http://xxxxxxxxxxx");
}
function f2 (){
return axios.post("http://xxxxxxxx",{
id:xx,
name:xxx,
age:xx
})
}
//并发执行
axios.all([f1(),f2()]).then(
axios.spread({
function(res1,res2){
//res1是f1()的返回结果
//res2是f2()的返回结果
}
})
);
</script>
组件
组件可以使相同的内容进行复用。
用来减少vue实例对象中代码量,日后在使用vue开发过程中,可以根据不同业务功能将页面中划分不同的多个组件。然后由多个组件去完成整个页面的不仅,便于日后使用vue进行开发时页面管理,方便开发人员维护。
第一步:注册组件
- 通过component方法注册组件
- 第一个参数表示组件名
- 第二个参数表示组件的组成,组成本质上也是一个Vue实例,也就可以定义:data/methods等等
- 组件在定义市,不会和任何页面元素绑定,因此没有el属性,但多个template属性抽取html片段
- data必须是一个函数
<script>
Vue.component("button-counter",{
template:"<button @click='increment'>你点了我{{count}}次,我记住了</button>",
data:function(){
return {
count:0
}
},
methods:{
increament(){
this.count++;
}
}
})
</script>
第二步:使用组件
- 把组件名当作标签直接使用就可以
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
</div>
第三步:创建vue实例
- 因为组件会被多次使用,所以定义组件时,语法上要求data必须是一个函数,每次使用时返回一个新的对象
- 组件要在Vue实例中使用,所以最后一定要创建Vue实例。
- 组件名如果由多个单词组成,按照规范多个单词全小写,并使用-连接,比如button-counter.如果使用驼峰命名法,比如buttonCounter,那么在使用组件时,也需要在单词间添加-
- 组件中template只能有一个根标签,比如实例中只有一个div根标签,如果又有一个同级的div就会报错
<script>
Vue.component("button-counter",{
template:"<button @click='increment'>你点了我{{count}}次,我记住了</button>",
data:function(){
return {
count:0
}
},
methods:{
increament(){
this.count++;
}
}
})
const vm = new Vue({
el:"#app"
})
</script>
组件的注册方式
全局注册
全局组件注册给vue实例,日后可以在任意vue实例的范围内使用该组件
语法如上述案例
<div id="app">
<!-- 使用全局组件-->
<login></login>
</div>
<script>
//全局组件注册 参数1:组件名称 参数2:组件配置对象
// template:用来书写组件的html代码(template必须在一个容器中)
Vue.component('login',{
template:'<div><h1>用户登录</h1></div>'
});
const vm = new Vue({
el: "#app",
data: {},
methods: {}
})
</script>
局部注册
一旦全局注册,就意味着即便以后你不在使用这个组件,它依然会随着vue的加载二加载。因此,对于一下并于频繁使用的组件,我们会采用局部注册。在vue实例中添加选项components语法如下:
<script>
const vm - new VUE({
el:"选择器",
data:{
//属性
},
components:{
//注册局部组件
"组件名":{
template:"复用的html片段",
data:function(){
return {...}//return的对象,类似于创建vue实例的data
},
methods:{
//和定义vue实例对象时一样,用于定义函数
}
}
}
});
注册优化
1.将组件参数单独抽取成变量
当vue实例中注册的组件比较多时,vue实例的代码就会变得非常臃肿,不利于代码管理,此时可以将vue实例参数抽取成变量
<script>
const buttonCounter = {
template:"<button @click='increament'>你点了我{{count}}次,我记住了</button>",
data:function(){
return {
count:0
}
},
methods:{
increment(){
this.count++;
}
}
};
const vm = new Vue({
el:"#app",
components:{
//"button-counter":buttonCounter
//组件名和组件变量类似的时候可以省略组件名
buttonCounter
}
})
</script>
2.将代码片段定义在外部
<template id = "button-template">
<button @click='increament'>你点了我{{count}}次,我记住了</button>
</template>
<script>
const buttonCounter = {
template:"#button-template",
data:function(){
return {
count:0
}
},
methods:{
increment(){
this.count++;
}
}
};
const vm = new Vue({
el:"#app",
components:{
//"button-counter":buttonCounter
//组件名和组件变量类似的时候可以省略组件名
buttonCounter
}
})
</script>
3.组件和is属性
在html表签中使用组件时,收到html本身的一些显示。比如table.ul.select内部只能出现特定的子标签,如果在这些标签中使用组件,组件无法正确显示。解决方案:使用is属性
<div id = "app">
<h4>直接在table中使用table-body组件</h4>
<table border="1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<th>gender</th>
</tr>
</thead>
<!--直接使用组件,这样是不对的,效果不对-->
<table-body></table-body>
</table>
<h4>在table中通过is属性使用table-body组件</h4>
<table border = "1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<th>gender</th>
</tr>
</thead>
<!--通过is属性使用组件-->
<tbody is = "table-body"></tbody>
</table>
</div>
porp的使用
作用:props是来给组件传递相应的静态数据或动态数据
1.通过组件上声明静态数据传递给组件内部
案例:
<div id="app">
//通过组件完成数据传递
<login user-name="小陈" age=></login>
</div>
<script>
//1.声明组件模板配置对象
let login={
template: "<div><h1>欢迎:{{userName}}</h1></div>",
//声明proop,用来接收使用组件时通组件标签传递的数据
props:['userName']
}
//2.注册组件
const vm = new Vue({
el: "#app",
data: {},
methods: {},
components:{
login
}
})
</script>
总结
- 1.使用组件时可以在组件上定义多个属性以及对应数据
- 2.在组件内部可以使用prop数组声明多个定义在组件上的属性名 日后可以在组件中通过{{属性名}}方式获取组件中的属性值
2.通过组件上声明动态数据传递给组件内部
<div id="app">
<!--3.使用组件 使用v-bind形式绑定vue实例中data属性,日后data属性发生变化,组件内部数据跟着变化-->
<login :name="userName"></login>
</div>
<script>
//1.声明组件模板对象
const login={
template: "<div><h1>欢迎:{{name}}</h1></div>",
props:['name']
}
//2.注册局部组件
const vm = new Vue({
el: "#app",
data: {
userName:'小晨晨'
},
methods: {},
components:{
login
}
})
</script>
prop单向数据流问题
父级 的prop更新会影响到子组件,但反过来不行。
组件中自己的数据需要使用函数形式。
组件中定义数据和事件使用
1.组件中定义属于组件的数据
<div id="app">
<login></login>
</div>
<template id="login">
<div>
<h1>欢迎:{{msg}}</h1>
<ul>
<li v-for="item in lists">{{item}}</li>
</ul>
</div>
</template>
<script>
//1.声明组件的配置对象
let login = {
template: "#login",
props: [],
data() {
//使用data函数方式定义组件的数据 在template代码中通过插值表达式获取
return {
msg: "hello",
lists: ['java', 'c', 'c++', 'python']
}//组件自己内部数据
}
}
const vm = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login
}
})
</script>
2.组件中事件的定义
- 组件中定义事件和直接在vue中帝国一事件基本一致,直接在组件内部对应的html代码上加入@时间名=函数名的方式即可
- 在组件内部使用metnods属性用来定义对应的事件函数即可,时间函数中this指向的是当前组件的实例
<div id="app">
<login ></login>
</div>
<template id="login">
<div>
<input type="button" value="点我触发事件" @click="change">
</div>
</template>
<script>
let login={
template: "#login",
props:[],
data(){
return{
name:'小陈',
}
},
methods: {
change(){
alert("触发事件");
alert(this.name);
}
}
}
const vm = new Vue({
el: "#app",
data: {},
methods: {},
components:{
login
}
})
</script>
3 向子组件中传递事件并在子组件中调用该事件
- 在子组件中调用vue实例中声明的相关事件必须使用**this.$emit(‘函数名’)**方式调用
<div id="app">
<login :name="username" @aaa="findAll"></login>
</div>
<template id="login">
<div>
<h1>helle:{{uname}}</h1>
<input type="button" value="点我触发事件" @click="change">
</div>
</template>
<script>
//1.声明组件
const login = {
template: "#login",
props: ['name'],
data() {
return {
uname: this.name,
}
},
methods: {
change() {
//调用vue实例中的函数
this.$emit('aaa');//调用组件传递过来的其他函数时需要使用this.$emit('函数名')调用
}
}
}
//2. 注册组件
const vm = new Vue({
el: "#app",
data: {
username: '小陈'
},
methods: {
//一个事件函数 将这个函数传递给子组件
findAll() {
alert("vue实例中函数触发")
}
},
components: {
login//组将的注册
}
})
</script>
组件的嵌套
局部注册时注意:在哪个组件内使用组件就在哪个组件内注册component。如果是全局注册时就可以全部注册到全局组件中
<!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">
<script type="text/javascript" src="./vue.js"></script>
<title>Document</title>
</head>
<body>
<div id = "app">
<my-table></my-table>
</div>
<template id = "my-table">
<table border = "1">
<thead is="table-head">
<!--通过is属性使用组件-->
<tbody is = "table-body"></tbody>
</table>
</template>
<template id = "table-head">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<th>gender</th>
</tr>
</thead>
</template>
<template id ="table-body">
<tbody>
<tr>
<td>1</td>
<td>zhangsan</td>
<td>18</td>
<td>male</td>
</tr>
<tr>
<td>2</td>
<td>lisi</td>
<td>20</td>
<td>male</td>
</tr>
</tbody>
</template>
<script>
const tableHead= {
template:"#table-head"
};
const tableBody= {
template:"#table-body"
};
const myTable= {
template:"#my-table",
components:{
tableHead,tableBody
}
};
const vm = new Vue({
el:"#app",
components:{
myTable
}
})
</script>
</body>
</html>
组件通信
通常一个较为复杂的页面,一定会出现组件的嵌套。哥哥组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
父传子:props
通常父组件的模板中包含子组件,父组件要正向地向子组件传递数据或参数。子组件接收到后根据参数的不同来渲染不同的内容或执行操作。这个正向传递数据的过程就是通过props来实现的。
比如在之前的表格案例中,table-body子组件展示的数据时定义在子组件自己身上的,这么做虽然有效果,但降低了该组件的复用价值,更好的做法:子组件中不定义数据,而是由使用它的父组件传递。此时,需要使用props完成父组件向子组件的数据传递。
//语法
//1.定义子组件中添加props属性
const 组件= {
template:"html片段",
props:["自定义参数名",....]
}
//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">
<script type="text/javascript" src="./vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<my-table v-bind:us="users"></my-table>
</div>
<br>
<div id="app2">
<my-table v-bind:us="users"></my-table>
</div>
<template id="my-table">
<table border="1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr v-for="u in us" :key="u.id">
<td>{{u.id}}</td>
<td>{{u.name}}</td>
<td>{{u.age}}</td>
</tr>
</tbody>
</table>
</template>
<script>
const myTable = {
template: "#my-table",
props: ["us"]
};
const vm = new Vue({
el: "#app",
components: {
myTable
},
data() {
return {
users: [
{ id: 1, name: "zhangsan", age: 19 },
{ id: 2, name: "lisis", age: 18 },
{ id: 3, name: "wangwu", age: 20 }
]
}
}
});
const vm2 = new Vue({
el: "#app2",
components: {
myTable
},
data() {
return {
users: [
{ id: 4, name: "zhangsan", age: 19 },
{ id: 5, name: "lisis", age: 18 },
{ id: 6, name: "wangwu", age: 20 }
]
}
}
})
</script>
</body>
</html>
子传父:$emit
父组件的模板中包含子组件,那么经常会出现子组件的转台发生变化时,要通知到父组件,所有的prop都使得父子prop之间形成了一个单向下行绑定,父级prop的更新会向下流动到子组件中,但是反过来则不行。
<div id="app">
<h2>{{num}}</h2>
<!-- 父组件向子组件传递数据count=num
子组件中修改count值,不能修改父组件的num-->
<counter :count="num" @change-count="handleChange"></counter>
</div>
<template id="counter">
<div>
<button @click="increment">点我自增</button>
<span>{{count}}</span>
<button @click="decrement">点我自减</button>
</div>
</template>
<script>
let counter = {
template: "#counter",
props: ["count"],
data() {
return {
name: '小陈',
}
},
methods: {
increment() {
this.count++;
//子组件向父组件传递数据通过this.$emit
// this.$emit("子组件的自定义事件名",子组件要传递给父组件的数据)
this.$emit("change-count", this.count)
},
decrement() {
this.count--;
//子组件向父组件传递数据通过this.$emit
// this.$emit("子组件的自定义事件名",子组件要传递给父组件的数据)
this.$emit("change-count", this.count)
}
}
}
const vm = new Vue({
el: "#app",
data: {
num: 0,
},
methods: {
//c:就是子组件传来的数据this.count
handleChange(c) {
console.log(c);
this.num = c;
}
},
components: {
counter
}
})
</script>
路由(VueRouter)
路由
官网
路由:根据请求的路径按照一定的路由规则进行ing求的转发从而帮助我们实现统一请求的管理
作用:用来在vue中实现组件之间的切换
路由使用
- 引入路由
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
- 创建组件对象
<!--登录模板-->
<template id="login">
<h1>登录</h1>
</template>
<!--注册模板-->
<template id="register">
<h1>注册</h1>
</template>
<script>
//登录组件
const login = {
template: "#login"
}
//注册组件
const register = {
template: "#register"
}
</script>
- 定义路由对象的规则
//创建路由对象
const router = new VueRouter({
routes: [
//path:路由路径 component:路由对应的组件
{path: '/login', component: login},
{path: '/register', component: register}
]
})
- 将路由对象注册到vue实例
const vm = new Vue({
el: "#app",
data: {},
methods: {},
//设置路由对象
router: router
})
- 在页面中显示路由组件
<div id="app">
<a href="#/login">点我登录</a>
<a href="#/register">点我注册</a>
<!--显示路由的组件-->
<router-view></router-view>
</div>
- 根据链接切换路由,#/路径
<a href="#/login">点我登录</a>
<a href="#/register">点我注册</a>
router-link使用
作用:用来替换我们在切换路由时使用a标签切换路由,
好处:就是可以自动给路由路径加入#不需要手动加入
注意:router-link to 属性用来书写路由路径 ;
tag 属性用来将router-link渲染成指定的标签
<!--router-link好处:书写路由路径不需要#-->
<router-link to="/login" tag="button">我要登录</router-link>
<router-link to="/register" tag="button">我要注册</router-link>
默认路由
作用:用来第一次进入界面时显示一个默认的组件
//创建路由对象
const router = new VueRouter({
routes: [
//设置默认路由方式1,不推荐
// {path: '/', component: login},
//设置默认路由方式2,重定向,推荐
{path: '/', redirect: "/login"},
{path: '/login', component: login},
{path: '/register', component: register}
]
})
路由中的参数传递
方式1:使用?形式传递参数
<!--直接拼接参数-->
<router-link to="/login?id=21&name=zhangsan" tag="button">我要登录</router-link>
<script>
//在组件中获取
const login={
template:'<h1>用户登录{{this.$route,id}{{this.$route.name}}}</h1>',
data(){return{}},
methods:{},
created(){
console.log("=======>"+this.$route.query.id+"============>"+this.$route.query.name);
}
}
//创建路由对象
const router = new VueRouter({
routes: [
//设置默认路由方式1,不推荐
// {path: '/', component: login},
//设置默认路由方式2,重定向,推荐
{path: '/', redirect: "/login"},
{path: '/login', component: login},
]
})
</script>
方式2:使用restful传递
<!--直接拼接参数-->
<router-link to="/login/21/zhangsan" tag="button">我要登录</router-link>
<script>
//在组件中获取
const login={
template:'<h1>用户登录{{this.$route,id}{{this.$route.name}}}</h1>',
data(){return{}},
methods:{},
created(){
console.log("=======>"+this.$route.params.id+"============>"+this.$route.params.name);
}
}
//创建路由对象
const router = new VueRouter({
routes: [
//设置默认路由方式1,不推荐
// {path: '/', component: login},
//设置默认路由方式2,重定向,推荐
{path: '/', redirect: "/login"},
{path: '/login/:id/:name', component: login},
]
})
</script>
嵌套路由
需要在路由对象中添加children属性
- 声明最外层和内层路由
//注册组件
const product = {
template: "#product",
}
const productadd = {
template: "<h1>商品添加</h1>"
}
const productmodify = {
template: "<h1>商品修改</h1>"
}
- 创建路由对象含有嵌套路由
//创建路由对象
const router = new VueRouter({
routes: [
{
path: '/product',
component: product,
children: [
{path: 'add', component: productadd},
{path: 'modify', component: productmodify}]
},
{path: '/product/add', component: productadd},
{path: '/product/modify', component: productmodify},
]
})
- 注册路由对象
//声明组件模板
const vm = new Vue({
el: "#app",
data: {},
methods: {},
//设置路由对象
router
})
- 测试路由
<div id="app">
<router-link to="/product" tag="button">商品管理</router-link>
<router-view></router-view>
</div>
vueCLI脚手架
什么是CLI
CLI:命令行界面也叫字符用户界面
什么是vueCLI
官网 Vue CLI是一个基于vue.js进行快速开发的完整系统。使用vue脚手架之后我们开发的页面将是一个完整系统。
vue CLI优势
- 通过vue-cli搭建交互式的脚手架。通过执行命令方式下载相关依赖(bootstrap css js jquery js等)
- 通过@vue/cli+@vue/cli-service-global快速开始零配置原型开发
- 一个运行时依赖 (@vue/cli-service),该依赖:
可升级;
基于 webpack 构建,并带有合理的默认配置; webpack:项目打包方式
可以通过项目内的配置文件进行配置;通过修改默认配置文件达到自己想要的项目环境
可以通过插件进行扩展。vue v-chars elementui - 一个丰富的官方插件集合,即成了前端生态中最好的工具。Nodejs(tomcat) Vue VueRouter webpack yarn
- 一套完全的图形化的出啊关键和管理Vue.js项目的用户界面
Vue CLI安装
- 环境准备
- 安装nodejs,下载nodejs并配置环境变量
- 验证nodejs是否安装成功 node -v npm -version
- 配置淘宝npm镜像(npm 是包管理工具,相当于maven)
- 配置npm默认下载依赖位置
- 验证nodejs环境配置 npm config ls
- 卸载脚手架
npm uninstall -g @vue/cli //卸载3版本脚手架
npm uninstall -g vue/cli //卸载2版本脚手架 - 安装脚手架
npm install -g vue-cli
使用vue脚手架第一个项目
- 创建项目
vue init webpack 项目名
如果出现异常参考 https://blog.csdn.net/feinifi/article/details/104578546
- 运行项目,在项目根目录下
npm start
- 访问页面http://localhost:8081
- vuecli项目开发方式
一切皆组件 一个组件中 js代码 html代码 css样式
vuecli开发方式实在项目中开发一个一个组件对应一个业务功能模块,日后可以将多个组件组合到一起形成前端系统
日后在使用vuecli进行开发时不要再写html文件,写的都是组件,日后打包时vuecli会将组件编译成html文件
- 如何开发vue脚手架
注意:在vuecli中一切皆组件
- ‘/’访问 路径
main.js–>App.vue–>根据router-view标签–>index.js路由文件–>路由对应的组件
- export default时暴露本组件,里面可以有data,methods,created()等,相当于一个组件
- 组件中也可以用其他的组件
main.js文件
在脚手架中使用axios
- 安装axios
npm install axios --save-dev
- 配置axios,在main.js引入axios
import axios from 'axios';
Vue.prototype.$http=axios;//修改内部的$http为axios
- 使用axios
在需要发送异步请求的位置 :this.$http.get(“url”).then((res)=>{})
- 在方法中跳转路由
this.$router.push('/user')
vue打包部署
- 在项目根目录中执行
vue run build
vue脚手架打包的项目必须在服务器上运行,不能直接双击运行
- 打包后生成的dist目录,dist目录就是部署目录
- 把dist目录放在springboot项目statis目录下,注意修改index.html引用的路径