vue
第一个vue小程序#
1、idea安装插件vue.js
2、下载vue.
代码实现#
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
</head>
<body>
<div id="id1">
{{ message }}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#id1",
data:{
message:"hello vue "
}
})
</script>
</body>
</html>
显示 hello vue
在控制台改变
或者通过:
<div id="app-2"> <span v-bind:title="message"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span> </div>
你看到的 v-bind
attribute 被称为指令。指令带有前缀 v-
,以表示它们是 Vue 提供的特殊 attribute。可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的 title
attribute 和 Vue 实例的 message
property 保持一致”。
如果你再次打开浏览器的 JavaScript 控制台,输入 app2.message = '新消息'
,就会再一次看到这个绑定了 title
attribute 的 HTML 已经进行了更新。
MVVM#
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。
前端页面中,把Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。
把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。
我们惊讶地发现,改变JavaScript对象的状态,会导致DOM结构作出对应的变化!这让我们的关注点从如何操作DOM变成了如何更新JavaScript对象的状态,而操作JavaScript对象比DOM简单多了!
设计思想#
- 这就是MVVM的设计思想:关注Model的变化,让MVVM框架去自动更新DOM的状态,从而把开发者从操作DOM的繁琐步骤中解脱出来!
基础语法:#
v-text:显示文本#
v-text
:用来获取 data 中数据将数据以文本的形式渲染到指定标签内部,类似于 javascript 中 innerText
。
使用 v-text
:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>v-text</title>
</head>
<body>
<div id="app">
<h3 v-text="msg"></h3>
</div>
<!--引入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
msg: "Hello Vue.js !",
}
});
</script>
</body>
</html>
使用 {{}}
:
<body>
<div id="app">
<h3>{{ msg }}</h3>
</div>
<!--引入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
msg: "Hello Vue.js !",
}
});
</script>
</body>
{{ xx }}
(插值表达式)和 v-text
获取数据的区别在于:
- 使用
v-text
取值会将标签中原有的数据覆盖,
插值表达式的形式不会覆盖标签原有的数据。 - 使用
v-text
可以避免在网络环境较差的情况下出现插值闪烁。(已修复)
v-html:显示解析html标签的文本#
v-html
:用来获取 data 中数据将数据中含有的 html 标签先解析在渲染到指定标签的内部,类似于 javascript 中 innerHTML
。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>v-text</title>
</head>
<body>
<div id="app">
<span> {{ message }} xxxxxxxxxx</span> <!--不会解析-->
<br>
<span v-text="message">xxxxxxxxxx</span> <!--不会解析-->
<br>
<span v-html="message">xxxxxxxxxx</span> <!--会解析html-->
</div>
<!--引入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : "#app",
data : {
message: "<a href=''>hello Vue.js</a>"
}
})
</script>
</body>
</html>
v-on:事件绑定#
v-on
:事件绑定
v-on:click
可以简化成@click
- 事件函数可以简写,
dowork: function() {}
可以简写成dowork() {}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>v-on</title>
</head>
<body>
<div id="app">
<h2>鼠标点击次数: {{count}}</h2>
<h2>年龄: {{age}}</h2>
<input type="button" value="通过v-on事件修改年龄每次+1" v-on:click="changeage">
<input type="button" value="通过@绑定事件修改年龄每次-1" @click="editage">
<input type="button" value="统计点击次数" @click="clickcount">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : "#app",
data : {
age: 23,
count: 0,
},
methods : {
changeage : function() {
this.age++;
},
editage() {
this.age--;
},
clickcount() {
this.count++;
}
}
});
</script>
</body>
</html>
v-show#
v-show是用来控制该标签是否显示的。底层操作的是标签的display=none/block
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-show</title>
</head>
<body>
<div id="app">
<h1 v-show="false">我被隐藏了,因为v-show的值是false</h1>
<!--自定义的isShow的值-->
<h1 v-show="isShow">我的显示决定于isShow的值</h1>
<input type="button" value="显示/隐藏" @click="isShow=!isShow">
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const vue = new Vue({
el: "#app",
data:{
isShow: false
},methods: {
},
});
</script>
</html>
解释:
我们可以f12中查看标签的style属性。
v-if#
v-if也是用来控制标签是否显示的,但是和v-show不同的是,v-show是操作的元素的display,而v-if是直接操作dom。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-if</title>
</head>
<body>
<div id="app">
<h1 v-if="false">我直接当场自闭,我没了</h1>
<h1 v-if="isShow">我的显示与否取决于isShow</h1>
<input type="button" value="切换显示/隐藏" @click="isShow=!isShow">
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const vue = new Vue({
el: "#app",
data: {
isShow: false
},methods: {
},
});
</script>
</html>
解释:
Copy# 我们f12后就会发现,当没显示的时候,直接dom元素直接没了,然后再去对比v-show就能很清晰的知道他们二者的区别了。
v-bind#
用来绑定标签的属性,达到快捷的更改属性的操作,例如绑定元素的class,src等。
Copy<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-bind</title>
<style type="text/css">
.s1{
color:red;
font-size: 25px;
}
.s2{
color: aqua;
font-size: 25px;
}
</style>
</head>
<body>
<div id="app">
<span v-bind:class="spanClass">我是文字,我会被动态的改变样式,因为我使用v-bind绑定了class属性</span>
<span v-bind:class="spanClass">我是文字,我也会被动态的改变样式,我使用了另一种绑定的语法,:class</span>
<br>
<input type="button" value="切换span的样式" @click="changeSpanStyle">
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const vue = new Vue({
el: "#app",
data: {
spanClass: "s1"
},methods: {
changeSpanStyle(){
this.spanClass = this.spanClass=='s1'?'s2':'s1'
},
}
});
</script>
</html>
解释:
# v-bind的作用就是绑定标签的属性,可以很便捷的更改其属性的值。
两种写法:
1> v-bind:属性名="变量名"
2> :属性名="变量名"
v-for循环#
可以遍历对象、数组等玩意的。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-for</title>
</head>
<body>
<div id="app">
<h2>测试遍历对象</h2>
<ul>
<li v-for="(value,key,index) in user">
第:{{index+1}}个,key:{{key}},value:{{value}}
</li>
</ul>
<hr>
<h2>测试遍历数组</h2>
<ul>
<li v-for="item,index in arrays">
第:{{index+1}}个,值为:{{item}}
</li>
</ul>
<hr>
<h2>测试遍历数组(内容为对象)</h2>
<ul>
<li v-for="user,index in users">
第:{{index+1}}个,用户名为:{{user.username}},名称为:{{user.name}},密码为:{{user.password}}
</li>
</ul>
<hr>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
user: {username:"user1",name:"用户1",password:"密码1"},
arrays: ["张三","李四","王麻子"],
users: [
{username:"user1",name:"用户1",password:"密码1"},
{username:"user2",name:"用户2",password:"密码2"},
{username:"user3",name:"用户3",password:"密码3"},
{username:"user4",name:"用户4",password:"密码4"}
]
},methods: {
},
});
</script>
</html>
解释:
# 遍历对象的时候:
v-for="每一项的key,每一项的value,当前下标 in 变量名"
# 遍历其他的时候:
v-for="每一项的内容,当前下标 in 变量名"
# 建议绑定一个 key ,用来排序和重用
:key="user,id"
v-model 双向绑定#
v-model
:用来绑定 标签元素的值 与 vue实例对象中data数据 保持一致,从而实现 双向的数据绑定机制。
- 所谓双向绑定,就是表单中数据变化导致 vue 实例 data 数据变化,vue 实例中 data 数据的变化导致表单中数据变化。
MVVM 架构 双向绑定机制
Model:数据 Vue实例中绑定数据
View:页面 页面展示的数据
VM:ViewModel 监听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
</head>
<body>
<div id="id1">
请输入:<input type="text" value="123" v-model="message"/> {{message}}
<br>
<input type="radio" name="sex" value="male" v-model="sex1" checked>Male
<br>
<input type="radio" name="sex" value="female" v-model="sex1" >Female
<br>
{{sex1}}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#id1",
data: {
message: "space1",
sex1:""
},
})
</script>
</body>
</html>
事件修饰符#
例子@click.self="divClick"
官方解释:
在事件处理程序中调用 `event.preventDefault()` 或 `event.stopPropagation()` 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 `v-on` 提供了**事件修饰符**。之前提过,修饰符是由点开头的指令后缀来表示的。
大概的意思就是,例如冒泡这种,元素内的元素事件可以会冒泡到外层元素的事件中,或者我们a标签点击事件的时候,并不想触发它默认的跳转的行为,这些在没有vue之前,都需要自己手动的去设置,有了vue以后,vue提倡的是只关心代码的数据、逻辑实现,而不需要去关心dom事件的繁杂细节,所以vue提供了事件修饰符来进行解决这些事情。
语法:@事件名.修饰符,注意,修饰符可以多个。
修饰符作用:用来和事件连用,决定事件触发条件或者是阻止事件的触发机制。
常用的事件修饰符:
.stop
:用来阻止事件冒泡。.prevent
:用来阻止标签的默认行为。.capture
.self
:只触发自己标签的上特定动作的事件,不监听事件冒泡。.once
:让指定事件只触发一次。.passive
stop修饰符#
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue中事件修饰符使用</title>
<style>
.aa {
background: red;
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<div id="app">
<!--self事件修饰符, 只出发标签自身的事件-->
<div class="aa" @click.self="divClick">
<!--stop事件修饰符, 用来阻止事件冒泡-->
<input type="button" value="按钮" @click.stop="btnClick">
<input type="button" value="按钮1" @click="btnClick1">
</div>
<hr>
<!--prevent事件修饰符, 用来阻止标签的默认行为-->
<!--a标签的默认行为就是跳转, prevent阻止了跳转-->
<!--.once: 用来只执行一次特定的事件-->
<a href="http://hlzy.xyz/" @click.prevent.once="aClick">所愿皆所得, 所行化坦途</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {},
methods: {
// 事件冒泡, 点击了按钮, 然后会触发父元素(div)的事件
// 用stop事件修饰符, 可以阻止事件冒泡
btnClick() {
alert("按钮被点击了。");
},
divClick() {
alert("div被点击了。");
},
aClick() {
alert("a标签被点击了。");
},
btnClick1() {
alert("btn1被点击了。");
}
}
});
</script>
</body>
</html>
按键修饰符#
作用:用来与键盘中按键事件绑定在一起,用来修饰特定的按键事件的修饰符。
@keyup.enter="input1Click"
# 常用
.enter
.tab (捕捉通过tab跳转到当前按标签)
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
<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="app">
<!-- 回车按键 -->
<input type="text" placeholder="测试回车按键" @keyup.enter="input1Click">
<!-- 退格按键 -->
<input type="text" placeholder="测试退格按键" @keyup.delete="input2Click">
<!-- ESC按键 -->
<input type="text" placeholder="ESC退格按键" @keyup.esc="input3Click">
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const vue = new Vue({
el: "#app",
data: {
},methods: {
input1Click(){
console.log("你按下了回车!");
},input2Click(){
console.log("你按下了退格!");
},input3Click(){
console.log("你按下了ESC!");
}
},
})
</script>
</html>
vue7个属性#
学习vue我们必须之到它的7个属性,8个 方法,以及7个指令。787原则
-
el属性
-
- 用来指示vue编译器从什么地方开始解析 vue的语法,可以说是一个占位符。
-
data属性
-
- 用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中。
-
template属性
-
- 用来设置模板,会替换页面元素,包括占位符。
-
methods属性
-
- 放置页面中的业务逻辑,js方法一般都放置在methods中
-
render属性
-
- 创建真正的Virtual Dom,路由对象
-
computed属性
-
- 用来计算
-
watch属性
-
- watch:function(new,old){}
- 监听data中数据的变化
- 两个参数,一个返回新值,一个返回旧值,
data的三种写法#
在vue中,定义data可以有三种写法。
1.第一种写法,对象。
var app = new Vue({
el: '#yanggb',
data: {
yanggb: 'yanggb'
}
})
2.第二种写法,函数。
var app = new Vue({
el: '#yanggb',
data: function() {
return {
yanggb: 'yanggb'
}
}
})
3.第三种写法,函数,是第二种写法的ES6写法。
var app = new Vue({
el: '#yanggb',
data() {
return {
yanggb: 'yanggb'
}
}
})
三种写法的区别
在简单的vue实例应用中,三种写法几乎是没有什么区别的,因为你定义的#yanggb对象不会被复用。
但是如果是在组件应用的环境中,就可能会存在多个地方调用同一个组件的情况,为了不让多个地方的组件共享同一个data对象,只能返回函数。这个与JavaScript的作用域特性有关,函数自己拥有私有的作用域,函数之间的作用域相互独立,也就不会出现组件对数据的绑定出现交错的情况。
组件#
- 自定义标签
- 可重复使用的vue实例,模板
作用#
组件作用:用来减少 Vue 实例对象中代码量,日后在使用 Vue 开发过程中,可以根据不同业务功能将页面中划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于日后使用 Vue 进行开发时页面管理,方便开发人员维护。
使用#
全局组件#
全局组件注册给 Vue 实例,可以在任意 Vue 实例的范围内使用该组件。
# 1:Vue.component用来开发全局组件
参数1:组件的名称。
参数2:组件的配置--template:''用来书写组件的代码
注意:组件中的代码只能有一个根元素,且必须有一个根元素
# 2:使用时需要在Vue实例的范围内使用,其他地方使用是无效的
# 3:如果组件注册过程中,使用驼峰命名,例如你的组件名是这样的:userAdd,那么你使用的时候,就要变成这样:user-add
全局组件的开发:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>全局组件的开发</title>
</head>
<body>
<div id="app">
<!-- 使用全局组件 -->
<login></login>
<!-- 使用局部组件 -->
<user-login></user-login>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 开发全局组件
// 参数1: 组件名称
// 参数2: 组件配置对象 template:用来书写组件的html代码(注意:在template中必须存在一个容器(如div))
Vue.component('login', {
template : '<div><h1>用户登录</h1></div>'
});
// 驼峰命名法的组件会被特殊处理, userLogin 使用时必须写成 user-login
Vue.component('userLogin', {
template : '<div><input type="button" value="登录"></div>'
});
const app = new Vue({
el: "#app",
data: {},
methods: {},
});
</script>
</body>
</html>
局部组件#
通过将组件注册给Vue实例的一个components属性来完成注册,这样不会对Vue造成累加
第一种开发方式:
</head>
<body>
<div id="app">
<login></login>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
// 声明组件为一个变量
let login = {
template: '<div><h1>登录组件</h1></div>'
};
const vue = new Vue({
el: "#app",
data:{},
methods: {},
components:{
// 注册组件到Vue实例的components中
login:login // 前面的是组件名称,后面的是组件的内容,我们这里使用变量login
// login,如果组件名和变量名一致,那么只需要写一个login就可以了。
},
created() {},
});
</script>
</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">
<login></login>
</div>
<!-- 1.写模板 -->
<!-- 使用template,可以定义组件的内容 -->
<template id="loginCom">
<div>
<h1>用户登录</h1>
</div>
</template>
</body>
<script src="./js/vue.js"></script>
<script>
// 声明变量来保存组件
<!-- 2.保存组件 -->
let login = {
template: '#loginCom' // 我们在这里不仅可以直接书写html,还可以使用选择器,例如id选择器,类选择器等
}
const vue = new Vue({
el: "#app",
data:{},methods:{},
components:{
<!-- 3.声明组件 -->
login:login
}
});
</script>
</html>
Prop的使用#
作用:prop用来给组件传递静态数据或动态数据
通过在组件上声明静态数据传递给组件内部#
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>在局部组件中使用props接收静态数据</title>
</head>
<body>
<div id="app">
<!--使用组件, 通过组件进行静态数据传递-->
<login user-name="zhenyu" age="20"></login>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 声明一个组件模板配置对象
let login = {
template: '<div><h2>欢迎: {{ userName }} 年龄: {{ age }}</h2></div>',
props: ['userName', 'age'] // props: 用来接收使用组件时通过组件标签传递的数据
}
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login // 组件注册
}
});
</script>
</body>
</html>
解释:
# 1:可以在标签属性上书写属性名=值,然后在组件参数使用props声明这两个传递来的值,然后我们就可以在组件内使用这两个使用这两个值
# 2:标签内的命名不能使用驼峰命名,只能使用单词-单词这种,但是当我们在组件内使用的使用又不能使用-的这种变量名,所以我们在标签上使用-形式,在组件内就转为驼峰命名法即可
通过在组件上声明动态数据传递给组件内部#
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>在局部组件中使用prop接收动态数据</title>
</head>
<body>
<div id="app">
<!--使用组件接收 Vue 实例中的动态数据-->
<!--使用 v-bind 形式将数据绑定到 Vue 实例中 data 属性, data 属性发生变化, 组件内部数据跟着变化-->
<login v-bind:name="username" :age="userage"></login>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const login = {
template: '<div><h2>欢迎: {{ name }} 年龄: {{ age }}</h2></div>',
props: ['name', 'age']
}
const app = new Vue({
el: "#app",
data: {
username: "zhenyu",
userage: 25
},
methods: {},
components: {
login // 注册组件
}
});
</script>
</body>
</html>
解释:
# 注意:
我们前面的静态数据是写死的,但是我们要知道我们的login这个标签是在vue实例中的,那么我们就可以使用vue实例的data数据,那么我们将原来将原来的死数据绑定为我们vue实例中的data数据,那么就达到了动态的效果。
props 的单向数据流#
# 所有的 props 都使得其父子 props 之间形成了一个**单向下行绑定**:父级 props 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
# 额外的,每次父级组件发生更新时,子组件中所有的 props 都将会刷新为最新的值。这意味着你**不应该**在一个子组件内部改变 props。如果你这样做了,Vue 会在浏览器的控制台中发出警告。—摘自官网
# 是什么意思呢?
就比如前面的例子,
我们vue实例中data数据发生改变后,那么组件内应用了此数据的地方则会进行更新,这就是向下流动到子组件中。
但是如果我们在组件中修改data数据,那么这就会改变vue实例的状态,那么这种情况是不被认可的,vue认为这是难以理解的。
代码实例:
<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="app">
<login :name="username"></login>
<button type="button" @click="changeName">更改username的值</button>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
let login = {
template:'<div><h1>你好,{{name}}</h1><button type=\'button\' @click=\'changeValue\'>改变值</button></div>',
props:["name"],
data:function(){
return {};
}
methods: {
changeValue(){
this.name='你好'
}
},
};
const vue = new Vue({
el: "#app",
data: {
username:"张三"
},methods:{
changeName(){
this.username='李四';
}
},
components:{
login
}
});
</script>
</html>
组件中定义数据#
data是一个函数,返回{}对象
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>组件中定义自己的data数据</title>
</head>
<body>
<div id="app">
<!--组件的使用-->
<login></login>
</div>
<!-- 引入Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const login = {
template: '<div><h2>{{ msg }}</h2><ul><li v-for="item,index in lists"> {{index+1}} : {{ item }} </li></ul></div>',
data() {
return {
msg: "hello Vue.js !",
lists: ['java', 'C++', 'python'],
}; // 组件内部的数据
}
};
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login // 注册组件
}
});
</script>
</body>
</html>
组件定义事件和使用#
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>组件中事件的定义</title>
</head>
<body>
<div id="app">
<!--使用组件-->
<login></login>
</div>
<!-- 引入Vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const login = {
// 组件中定义了属于组件的事件 @click="change"
template: '<div><h2>{{ hello }}</h2><input type="button" value="点我触发组件的事件" @click="change"></div>',
data() {
return {
hello: 'Hello Vue.js!',
};
},
// 组件中定义的 @click="change" 事件
methods: {
change() {
alert(this.hello);
}
}
}
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login // 注册组件
}
});
</script>
</body>
</html>
解释:
# 1:组件中定义方法和vue实例一致
# 2:定义data和vue实例不同,定义data需要写成一个函数,并且返回数据是对象。
向子数组中传递事件并在子组件中调用改变事件#
也就是说在子组件内去调用父组件的方法
<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">
<!--
@find:这个find是在组件内调用时候的名字
findAll:需要调用的实例中的方法名
-->
<login @find="findAll"></login>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
let login = {
template:"<div><h1>你好,请登录</h1><button type='button' @click='testClick'>试试点我</button></div>",
methods: {
// 组件内的方法
testClick(){
this.$emit("find"); // 此方法名在标签中定义的
}
},
}
var vue = new Vue({
el: "#app",
data:{},
methods:{
findAll(){ // vue实例的方法
alert("vue实例的findAll方法");
}
},
components:{
login
}
});
</script>
</html>
解释:
# 1、<login @find="findAll"></login>--->find则是在组内见调用方法的时候的名字
# 2、this.$emit("find"); // 此方法名在标签中定义的,
组件的组织#
通常一个应用会以一棵嵌套的组件树的形式来组织:
例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。
为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。至此,我们的组件都只是通过 Vue.component
全局注册的:
Vue.component('my-component-name', {
// ... options ...
})
全局注册的组件可以用在其被注册之后的任何 (通过 new Vue
) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
到目前为止,关于组件注册你需要了解的就这些了,如果你阅读完本页内容并掌握了它的内容,我们会推荐你再回来把组件注册读完。
网络通信axios#
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特性#
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
Vue基于 关注度分离 专注于视图层,少用jquery,频繁操作DOM树。
使用vue-axios#
安装:#
cnpm install --save axios vue-axios
将下面代码加入入口文件:
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
//使用方法
Vue.axios.get(api).then((response) => {
console.log(response.data)
})
this.axios.get(api).then((response) => {
console.log(response.data)
})
this.$http.get(api).then((response) => {
console.log(response.data)
})
代码实现:#
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="id1">
<div>{{info.name}}</div>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#id1",
data(){
//请求返回的数据,必须和json字符串一样
return{
info:{
name:"",
url: "",
page: "",
isNonProfit:"",
}
}
},
//进行网络通信,底部实现是ajax
mounted(){
//钩子函数
axios.get("./data.json").then(response=>(this.info=response.data))
}
})
</script>
</body>
</html>
请求#
get请求#
This wrapper bind axios
to Vue
or this
if you’re using single file component.
你可以按照以下方式使用:
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 上面的请求也可以这样做
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);
});
Axios 并发请求#
并发请求:将多个请求在同一时刻发送到后端服务接口,最后在集中处理每个请求的响应结果。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Axios - Get</title>
</head>
<body>
<!--引入Axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// 1.创建一个擦汗寻所有的请求
function findAll() {
return axios.get("http://localhost:8989/user/findAll?name=zhangsan");
}
// 2.创建一个保存的请求
function save() {
return axios.post("http://localhost:8989/user/save", {
id: "996",
username: "zhenyu",
age: 20,
email: "zhenyu@123.com",
phone: "123456789"
});
}
// 3.并发执行
axios.all([findAll(), save()]).then(
axios.spread(function (res1, res2) { // 用来将一组函数的响应结果汇总处理
console.log(res1.data);
console.log(res2.data);
})); // 发送一组并发请求
const app = new Vue({
el: "#app",
data: {},
methods: {},
});
</script>
</body>
</html>
Vue生命周期#
八大钩子函数#
1,beforeCreate():此钩子函数发生在实例创建之前,此时data,el,methods未初始化,观测数据和事件初始化完成,
2,created():此钩子函数data,methods数据初始化;el未初始化
3,beforemount():此钩子函数内就运用了dom虚拟技术 即是先占位置 数据不更新 (操作dom时拿不到数据),el未初始化完成
4:mounted():实例挂载完成,
5:beforeupdate():此函数发生在视图dom数据更新之前,dom虚拟和下载补丁之前,即data更新 当操作dom时拿不到数据,
6:updated():视图更新完成,
7:beforedestory():此时实例仍未销毁,this可以使用
8:destoryed():实例销毁完成,
生命周期图示#
下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
讲解图示
# 我们可以将这个生命周期拆分为三个阶段:
1- 初始化阶段
2- 运行阶段
3- 销毁阶段
# 那么就按照这三个阶段来说明这三个阶段中的回调方法:
1- 初始化阶段:
# beforeCreate:Vue实例仅仅是初始化、绑定了事件、还没有初始化el、data等数据的时候
# created:完成了el、data等数据库初始化,但是还没有将数据渲染到dom中的时候
# beforeMount:准备将数据渲染到dom中,但是还没有渲染的时候
# mounted:已经将数据渲染到dom中的时候
2- 运行阶段:
# beforeUpdate:data中数据发生改变,重新渲染到dom中之前的时候
# updated:data中改变的数据已经重新渲染到dom中之后的时候
3- 销毁阶段:
# beforeDestroy:实例销毁之前的时候,在这个方法里面使用vue完全可以
# destroyed:实例被销毁之后的时候,在这个方法里面vue基本上不可用了
当然还有很多其他的回调方法:
例如activated(keep-alive缓存组件激活时)、deactivated(keep-alive缓存组件停用时)、errorCaptured(发生错误的时候),详细了解可以查询官网:
https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9FE9%92%A9%E5%AD%90
Vue-router路由#
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
作用#
路由:根据请求的路径按照一定的路由规则进行请求的转发从而实现统一请求的管理;
路由的作用:用来在 Vue 中实现 组件之间的动态切换;
使用路由#
# 组件定义一定在创建路由对象前面
1、引入路由
<script src=“https://unpkg.com/vue-router@3.3.4/dist/vue-router.js"></script>
2、创建组件
// 登录组件
const login = {
template: '<div><h1>登录组件</h1></div>'
}
// 注册组件
const register = {
template: '<div><h1>注册组件</h1></div>'
}
3、创建路由对象并定义路由规则
// 定义路由对象
const router = new VueRouter({
routes:[
{path:'/login',component:login}, // path就是对应路径,component就是对应的组件
{path:'/register',component:register}
]
});
4、将路由对象注册到vue实例中
Copyconst vue = new Vue({
el: "#app",
data:{},
methods: {
},
router:router // 将路由注册到vue实例中去
})
5、在页面中定义路由组件显示的区域
Copy <!-- 显示路由组件 -->
<router-view></router-view>
6、定义a标签来切换路由
Copy<a href="#/login">点我到登录</a>
<a href="#/register">点我到注册</a>
注意:要加上#符号
原网站:
http://localhost:63342/%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86/src/main/webapp/demo2.html#/
// 登录组件
http://localhost:63342/%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86/src/main/webapp/demo2.html#/login
// 注册组件
http://localhost:63342/%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86/src/main/webapp/demo2.html#/register
代码实现#
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路由的基本使用</title>
</head>
<body>
<div id="app">
<!--4、在页面中显示路由的组件-->
<router-view></router-view>
<!--5、根据链接切换路由组件-->
<a href="#/login">点我登录</a>
<a href="#/register">点我注册</a>
</div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.3.4/dist/vue-router.js"></script>
<script>
// 1、创建组件对象
const login = {
template: "<h1>登录</h1>"
};
const register = {
template: "<h1>注册</h1>"
};
// 2、创建路由对象
const router = new VueRouter({
routes: [ // 定义路由对象的规则
// path:设置路由的路径, component:路径对应的组件
{path: "/login", component: login},
{path: "/register", component: register}
]
});
const app = new Vue({
el: "#app",
data: {},
methods: {},
router: router // 3、在vue实例中注册路由对象
});
</script>
router-link 使用#
作用:在切换路由时可以自动给路由路径加入#
不需要手动加入。
使用 a标签 切换路由: 需要在路径前面加 #
;
<a href="#/login">点我登录</a>
<a href="#/register">点我注册</a>
使用 router-link 切换路由:
to
属性书写路由路径;tag
属性将 router-link 渲染成指定的标签;
<router-link to="/login" tag="a">我要登录</router-link>
<router-link to="/register" tag="button">点我注册</router-link>
默认路由#
作用:用来在第一次进入界面是显示一个默认的组件;
const router = new VueRouter({
routes: [
// {path: "/", component: login},
{path: "/", redirect:"/login"}, // redirect:当访问的是默认路由"/"时, 跳转到指定的路由展示[推荐]
{path: "/login", component: login},
{path: "/register", component: register}
]
});
传递参数#
传统方式#
- URL 中通过
?
拼接参数:
<router-link to="/login?username=zhenyu&password=12345" tag="a">我要登陆</router-link>
2 . 在组件中获取参数:通过 this.$route.query.xxx
来获取参数;
const login = {
template: "<h1>用户登录</h1>",
data() {return{}},
methods: {},
//生命周期函数
created() {
console.log("name=" + this.$route.query.name + ", pwd=" + this.$route.query.pwd)
}
};
restful 方式传递参数#
- 通过使用路径方式传递参数:
const router = new VueRouter({
routes: [
{path: "/register/:name/:pwd", component: register}
]
});
12345
<router-link to="/register/zhenyu/12345" tag="a">我要注册</router-link>
1
- 在组件中获取参数:通过
this.$route.params.xxx
来获取参数;
const register = {
template: "<h1>用户注册</h1>",
data() {return{}},
methods: {},
created() {
console.log("name=" + this.$route.params.name + ", pwd=" + this.$route.params.pwd);
}
};
嵌套路由#
- 声明最外层和内层组件对象;
- 创建含有路由对象的路由对象(嵌套路由),通过
chidren
嵌套; - 注册与使用路由;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路由中传递参数</title>
</head>
<body>
<div id="app">
<router-link to="/product">商品管理</router-link>
<router-view></router-view>
</div>
<template id="product">
<div>
<h1>商品管理</h1>
<router-link to="/product/add">商品添加</router-link>
<router-link to="/product/edit">商品编辑</router-link>
<router-view></router-view>
</div>
</template>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.3.4/dist/vue-router.js"></script>
<script>
// 声明最外层和内层组件对象
const product = {
template: '#product'
};
const add = {
template: "<h4>商品添加</h4>"
};
const edit = {
template: "<h4>商品编辑</h4>"
};
// 创建含有路由对象的路由对象(嵌套路由), 通过children嵌套
const router = new VueRouter({
routes: [
{
path: "/product",
component: product,
//子路由不需要/ ,表示同级
children: [
{path: "add", component: add},
{path: "edit", component: edit},
]
},
]
});
const app = new Vue({
el: "#app",
data: {},
methods: {},
router // 注册路由
});
</script>
解释:
解视组件内还需要展示其他的组件,那么就需要下一层。
例如:
用户管理--组件
新增用户--组件
查询用户--组件
那么这个时候,我们需要在用户管理内展示新增用户,那么就需要这种嵌套路由。
路由转发#
# 路由转发
this.$router.push("/xx")
# 获取路由路径
this.$route.path
计算属性#
计算属性=把计算出来的值,保存在属性里面,在内存中运行,虚拟DOM,想象成缓存。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="id1">
fun1:{{data1()}}
<br>
fun2:{{data2}}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#id1",
data: {
message:"aaaa"
},
methods: {
data1:function () {
return Date()
}
},
computed:{
data2:function () {
this.message;
return Date()
}
}
})
</script>
</body>
</html>
插槽slot#
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 [Web Components 规范草案,将 <slot>
元素作为承载分发内容的出口。
就是在页面里面预留 位置 ,提前规划好位置。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="id1">
<slot1>
<title2 slot="title" v-bind:title1="messgae"></title2>
<lis slot="lis" v-for=" i in items " v-bind:item="i"></lis>
</slot1>
</div>
<script type="text/javascript">
//插槽
Vue.component('slot1',{
template:" <div>\
<slot name='title'></slot>\
<ul> \
<slot name='lis'></slot>\
</ul>\
</div>"
})
Vue.component('title2',{
props: ['title1'],
template: '<div>{{title1}}</div>'
});
Vue.component('lis',{
props: ['item'],
template:"<li>{{item}}</li>"
});
var app = new Vue({
el: "#id1",
data:{
messgae:"书籍列表",
items:["java","c++","python"]
}
});
</script>
</body>
</html>
自定义事件#
<!-- v-on:remove="removelist(index)" 自定义事件remove-->
this.$emit("remove",index) 通过这个把组件的函数 映射到自定义事件上,调用自定义事件的函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="id1">
<slot1>
<title2 slot="title" v-bind:title1="messgae"></title2>
<lis slot="lis" v-for=" (i, index) in items" v-bind:item="i" v-bind:index1="index"
v-on:remove="removelist(index)" v-bind:key="index" >
</lis>
</slot1>
</div>
<script type="text/javascript">
//插槽
Vue.component('slot1',{
template:" <div>\
<slot name='title'></slot>\
<ul> \
<slot name='lis'></slot>\
</ul>\
</div>"
})
Vue.component('title2',{
props: ['title1'],
template: '<div>{{title1}}</div>'
});
Vue.component('lis',{
props: ['item',"index"],
template:"<li>-- {{index}} ----{{item}} <button v-on:click='remove'>删除</button></li>",
methods:{
// this.$emit("remove",index1)
remove:function (index) {
this.$emit("remove",index)
}
}
});
var app = new Vue({
el: "#id1",
data:{
messgae:"书籍列表",
items:["java","c++","python"]
},
methods: {
//index表示下标
removelist:function (index1) {
console.log("删除了"+this.items[index1]+"---------")
this.items.splice(index1,1)
}
}
});
</script>
</body>
</html>
1实际开发#
Vue的开发都是基于NodeJS,实际开发采用vue-cli,vue-route路由,vuex做状态管理,VueUI ,界面一般使用ElementUI(饿了吗),或者ICE(阿里巴巴)
Vue-cli#
vue脚手架指的是vue-cli,它是一个专门为单页面应用快速搭建繁杂的脚手架,它可以轻松的创建新的应用程序而且可用于自动生成vue和webpack的项目模板。
vue-cli是有Vue提供的一个官方cli,专门为单页面应用快速搭建繁杂的脚手架。它是用于自动生成vue.js+webpack的项目模板,是为现代前端工作流提供了 batteries-included的构建设置。只需要几分钟的时间就可以运行起来并带有热重载,保存时 lint 校验,以及生产环境可用的构建版本。
主要的功能#
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
index 会自动加载 main.js 给他的 模板,main.js的模板来自App.vue
项目结构#
需要的环境:#
nodejs(官网下载)
git
确定 nodejs安装成功#
node -v
npm -v
//淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
使用npm(node package mangager) 安装 cnpm
1. 需要更改一个安装路径
再使用npm config get registry查看镜像地址。
npm config set registry "http://registry.npmjs.org/"
2. 再次使用npm进行全局安装cnpm
npm install -g cnpm
3.输入cnpm -v 即可出现版本号
使用cnpm安装vue-cli
cnpm install -g vue-cli
cnpm uninstall -g vue-cli
vue list
//查看可以基于那些模板进行创建,通常我们使用webpack
配置下载位置#
验证环境配置
npm config ls
配置npm依赖下载的位置
npm config set cache "E:\NodeJS\node-v14.7.0-win-x64\npm-cache"
npm config set prefix "E:\NodeJS\node-v14.7.0-win-x64\npm_global"
创建第一个Vue项目#
创建Vue项目#
vue init webpack myVue
? Project name myvue
? Project description A Vue.js project
? Author helloWorld
? Vue build standalone 回车
? Install vue-router? No
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) yes
初始化并运行#
//进入项目,安装依赖
npm start 就行了
npm install
//启动项目
npm run dev
Your application is running here: http://localhost:8080
文件目录#
- hello ------------->项目名
- build ------------->用来使用webpack打包使用build依赖
- config ------------->用来做整个项目配置目录
- node_modules ------>用来管理项目中使用依赖
- src ------>用来书写vue的源代码[重点]
- assets ------>用来存放静态资源 [重点]
- components ------>用来书写Vue组件 [重点]
- router ------>用来配置项目中路由[重点]
- App.vue ------>项目中根组件[重点]
- main.js ------>项目中主入口[重点]
- static ------>其它静态
- -.babelrc ------> 将es6语法转为es5运行
- -.editorconfig ------> 项目编辑配置
- -.gitignore ------> git版本控制忽略文件
- -.postcssrc.js ------> 源码相关js
- -index.html ------> 项目主页
- -package.json ------> 类似与pom.xml 依赖管理 jquery 不建议手动修改
- -package-lock.json ----> 对package.json加锁
- -README.md ----> 项目说明文件
开发使用#
# 1.Vue Cli中项目开发方式
注意: 一切皆组件 一个组件中 js代码 html代码 css样式
1. VueCli开发方式是在项目中开发一个一个组件对应一个业务功能模块,日后可以将多个组件组合到一起形成一个前端系统
2. 日后在使用vue Cli进行开发时不再书写html,编写的是一个个组件(组件后缀.vue结尾的文件),日后打包时vue cli会将组件编译成运行的html文件
使用Axios#
# 1、安装axios
npm install axios --save-dev
# 2、在main.js中引入axios并配置
import axios from 'axios';
Vue.prototype.$http=axios;
# 3、使用axios
this.$http.get(xxxxx),这种用法,我们配置的原因就是将vue中的http请求工具换成axios
打包#
# 1.在项目根目录中执行如下命令:
npm run build
注意:vue脚手架打包的项目必须在服务器上运行不能直接双击运行
# 2.打包之后当前项目中变化
在打包之后项目中出现dist目录,dist目录就是vue脚手架项目生产目录或者说是直接部署目录
常用知识点#
//转换路由 页面转换路由
this.$router.push("/user")
//监听页面路由变化
watch:{
$route:{
//val指路由对象
handler:function (val,oldVal) {
console.log(val);
if(val.path=="/user"){
this.findAll()
}
}
}
}
webpack#
本质上,webpack是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack它是代码编译工具,有入口,出口、loader和插件
模块的进化#
最原始的js加载方式,
<script src="" ></script>
每一个文件看做一个模块,那么他们的接口暴露在全局作用域下。
弊端
- 全局作用域变量冲突
- 按照
<script>
书写的顺序进行加载 - 开发人员必须主管解决模块和代码库的依赖关系
- 大型项目各种资源难以管理,长期积累的问题导致代码库混乱不堪
CommonJS#
CommonJS是一种被广泛使用的js模块化规范,核心思想是通过require方法来同步加载依赖的其他模块,通过module.exports导出需要暴露的接口。
采用 CommonJS 导入及导出的代码如下:
//导入
const moduleA = require ( ’. / moduleA’);
//导出
module .exports = moduleA.someFunc;
AMD是什么#
Asynchronous Module Definition,即异步模块加载机制
作为一个规范,只需定义其语法API,而不关心其实现。AMD规范简单到只有一个API,即define函数:
CMD#
(Common Module Definition)通用模块定义,它解决的问题和AMD规范是一样的,只不过在模块定义方式和模块加载时机上不同,CMD也需要额外的引入第三方的库文件,SeaJS
ECMAScript 6(简称ES6)#
是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言 [1]
安装webpack#
安装:
cnpm install webpack -g
cnpm install webpack-cli -g
测试:
D:\Code\myvue\myVue>webpack -v
4.44.1
D:\Code\myvue\myVue>webpack-cli -v
3.3.12
配置#
Webpack 最关键的就是 webpack.config.js 配置文件,架构的好坏都体现在这个配置文件中。
- 入口(entry) :入口文件,制定WebPack用哪个文件作为项目的入口
- 输出(output):指定WebPack把处理完成的文件放置到指定路径
- model:模块,用于处理各种类型的文件
- 插件(plugins):如:热更新,代码重用等
- resolve:设置路径指向
- watch:监听,用于设置文件改动后直接打包成文件。
使用webpack#
1.创建一个文件夹
2.创建一个 module 目录,用于放置JS模块等资源文件
3.在module创建hello.js文件,编写js模块代码
"user strict"
//暴露一个方法
exports.sayHi=function () {
document.write("<div>我在学前端</div>")
}
4.在module创建main.js文件,作为入口文件,
"user strict"
//require 映入模块
var hello = require("./hello");
hello.sayHi()
5.创建配置文件webpack..conf.js,使用webpack打包
设置入口,出口
"use strict"
var path = require('path');
module.exports = { //注意这里是exports不是export
entry: "./module/index.js", //入口文件
output: { //输出文件
path: path.resolve(__dirname,'dist'), //输出文件的目录
filename: 'bundle.js' //输出文件的名称
}
}
6.创建HTML文件,引入打包后的js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html>
结果:
脚手架vue-router#
安装和使用#
基于vue-cli创建的项目,进入项目后进行安装vue-router插件
cnpm install vue-router --save-dev //安装到开发环境
在模块进行使用 ,必须通过Vue.use()进行加载
import VueRouter from "vue-router";
//安装路由
Vue.use(VueRouter)
1.创建组件#
Context.vue
<template>
<h1>内容页</h1>
</template>
<script>
export default {
name: "Context"
}
</script>
<style scoped>
</style>
Main.vue
<template>
<h1>主页</h1>
</template>
<script>
export default {
name: "Index"
}
</script>
<style scoped>
</style>
2.创建自定义路由#
在src下创建route目录,创建index.js
index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Context from "../components/Context";
import Main from "../components/Main";
//安装路由
Vue.use(VueRouter)
//配置路由
export default new VueRouter({
//注册路由
routes:[
{
//路径
path:"/context",
//名称
name:"context",
//组件
component:Context
},
{
//路径
path:"/main",
//名称
name:"main",
//组件
component:Main
}
]
})
3.注册路由#
在main.js入口文件注册
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import Router from './route/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>',
//注册全部路由
router:Router
})
在App.vue使用模板#
<template>
<div id="app">
<!-- <img src="./assets/logo.png">-->
<!-- <HelloWorld/>-->
<router-view></router-view>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
结果:#
路由嵌套#
{
//路径,转到哪个组件
path:"/main",
component : Main,
children:[{
path:"/xxx",
component : Main,
}]
}
参数传递和重定向#
前端传参数
<router-link :to="{ name: 'main/user', params: { id: 123 }}">跳转到main</router-link>
路由接受参数:
{
//路径,转到哪个组件,获取参数
path:"/main/:id",
name:"main",
component : Main,
//声明有参数
props: true
}
使用参数
<template>
<h1>id:{{id}}</h1>
</template>
<script>
export default {
name: "Main",
props:["id"]
}
</script>
路由模式#
路由模式有两种:
- hash:路径带# http://localhost:8080/#/login
- history 路径不带# http://localhost:8080/login
export default new VueRouter({
//定义路由模式
mode:"history",
//定义路由转发
routes:[]
404页面#
-
先在view目录下写NotFound.vue
-
<template> <h1>你的页面走丢了</h1> </template> <script> export default { name: "NotFound" } </script> <style scoped> </style>
-
定义路由
{ path: "*", component: NotFound }
路由钩子和异步请求#
参考:
路由钩子函数有三种:#
1:全局钩子: beforeEach、 afterEach
2:单个路由里面的钩子: beforeEnter、 beforeLeave
3: 组件路由:beforeRouteEnter(进入)、 beforeRouteUpdate、 beforeRouteLeave(离开)
方法#
每个守卫方法接收三个参数:
①to: Route: 即将要进入的目标路由对象(to是一个对象,是将要进入的路由对象,可以用to.path调用路由对象中的属性)
②from: Route: 当前导航正要离开的路由
③next: Function: 这是一个必须需要调用的方法,执行效果依赖 next 方法的调用参数。
next参数:
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按 钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在router-link 的 to prop或router.push中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给router.onError()注册过的回调。
next(vm=>{})仅在beforeRouteEnter可用,vm是组件实例
ps~ : 确保要调用 next 方法,否则钩子就不会被 resolved。
代码使用#
导入依赖:
//导入axios,必要的两个东西
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
<template>
<div>main</div>
</template>
<script>
import axios from "axios";
export default {
name: "Main",
//钩子函数
beforeRouteEnter:function (to,from,next) {
console.log("路由进入前");
next(vm => {
console.log("开始执行axios")
vm.getData()
});
},
beforeRouteLeave:function(to,from,next){
console.log("路由进入后")
next()
},
methods:{
getData:function () {
this.axios({
method:"get",
url:"http://localhost:8080/static/mock/data.json"
}).then(function (response) {
console.log(response)
console.log("11111")
})
}
}
}
</script>
<style scoped>
</style>
作者:Esofar
出处:https://www.cnblogs.com/firsthelloworld/p/13462976.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本