Vue :前端整合框架

什么是Vue?

Vue.js是一套构建用户界面的框架 ,它不仅易于上手,还可以与其他的第三方库整合(Swiper)

Vue两大核心

  • 数据驱动界面改变

  • 组件化

Vue过渡动画

添加动画操作步骤

  • 将需要执行的动画元素放到transition组件中

    • 当transition组件中的元素显示时会自动查找 .v-enter / .v-enter-active / v-enter-to 类名
    • 当transit ion组件中的元素隐藏时会自动查找.v-leave / .v-leave-active / v-leave-to 类名
  • 我们只需要在.v-enterv-leave-to中指定动画开始的状态

    .v-enter-active .v-leave-active中指定动画执行的状态

    即可完成过渡动画

d

Vue组件&组件化

  • 什么是组件

在前端开发中,组件就是把一个很大的界面拆分成为多个小界面,每一个小界面就是一个组件

  • 什么是组件化

将大界面拆分成小界面就是组件化

  • 组件化的好处
    • 可以简化Vue实例代码
    • 可以提高复用性

Vue 全局组件

在任意一个Vue实例控制的区域中都可以使用

创建组件构造器

1
2
3
4
5
let Profile = Vue.extend({
template:'
<!--html代码-->
'
});

注册已经创建好的组件

1
Vue.componect(id,[defintion])

id : 给注册的组件起一个名字

defintion : 传入已经创建好的组件构造器

注意点:在创建组件指定组件的模版的时候,模版只能有一个根玉元素

使用注册好的组件

1
<id></id>

组件的简写方法

内部直接调用

1
2
3
4
5
6
<script>
// 直接将模版写到component内部
Vue.component(id,{
<!--html代码-->
})
</script>

自动调用 Vue.extend() 方法

外部调用

1
2
3
4
5
6
7
8
9
10
<script>
// 将模版包含到变量中
let obj = {
template:'
<!--html代码-->
'
}
// 将包含模版的变量绑定到组件
Vue.component(id,obj)
</script>

type方法

1
2
3
4
5
6
7
8
9
<script id="msg" type="text/html">
<!-- html代码 -->
</script>
<script>
// 将模版绑定到组件
Vue.componment(id,{
template:"#msg"
});
</script>

template封装方法(常用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 创建组件模版 -->
<template id="msg">
<!-- 同时因为template只能传递一个标签,
所以应该用一个div将所有指令包裹一下-->
<div>
<!-- html代码 -->
</div>
</template>
<script>
// 将模版绑定到组件
Vue.componment(id,{
template:"#msg"
});
</script>

在单文件Vue开发中,template应该定义在实例的外面

在Vue-cli中,有template应该在对应的.vue的文件中

Vue 局部组件

只能在自定义的那个Vue实例控制的区域中才可以使用

如何自定义一个局部组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
let app = new Vue({
el:"#app",
data:{},
methods:{},
// 在Vue实例中新增components:{}
components:{
"msg":{
// 将以创建的模版与"msg"进行绑定
template:"#msg"
}
}
})
</script>

创建组件模版的方式在定义Vue全局变量中有所讲解跳转

组件中的data与methods

data的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template id="add">
<div>
{{msg}}
</div>
</template>
<script>
// 在注册自定义组件时
// 在其中书写自定义组件中出现的data内容
Vue.component("addFn",{
template:"#add",
data:function(){
return {
msg:"data in template!"
}
}
})
</script>

在Vue的官方文档 - 组件基础中提到 data 必须是一个函数,所以定义不能使用原先实例中的定义方法

在自定义函数中使用data必须赋值一个函数,然后通过函数的返回值来定义有哪些数据

为什么data需要函数来返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<div id="app">
<!-- 3.创建三个组件 -->
<showAdd></showAdd>
<showAdd></showAdd>
<showAdd></showAdd>
</div>
<!-- 1.创建组件模版 -->
<template id="add">
<div>
<button @click="addFn">加一</button>
<p>{{num}}</p>
</div>
</template>
<script>
// 2.注册组件
Vue.component("showAdd",{
template:"#add",
data:function(){
return {
num:0
}
},
methods:{
addFn(){
this.num++;
}
}
})
</script>

为什么data需要函数来返回的运行结果

在上面的的结果中可以看出,同时创建的3个组件的data是相对独立的,并没有因为一个组件的数值发上改变而影响到其他组件中的数值结果

因为每创建一个组件,就会调用一次data方法。所以每个组件都拿到了自己的data方法,然后在通过data方法的返回值拿到自己的数值

当然,不使用方法返回的方式的话,就是注册的多个组件公用一个data,会造成数据的混乱

methods的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template id="add">
<div>
<button @click="addFn">按钮</button>
</div>
</template>
<script>
// 在注册自定义组件时
// 在其中书写自定义组件中出现的methods内容
Vue.component("addFn",{
template:"#add",
methods:{
addFn(){
// 方法
}
}
})
</script>

Vue组件切换 v-if

1
2
3
4
<div id="app">
<add v-if="showAdd"></add>
<sub v-else></sub>
</div>

在创建组件时添加v-if-else方法可以显示或隐藏组件

组件注册与绑定请参考全局组件的创建 跳转

动态组件 component

1
<component v-bind:is="'add'"></component>

直接写死为add

当然也可以定义成动态的

动态写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<button @click="toggle">切换</button>
<component v-bind:is="toggleName"></component>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
toggleName:"add"
},
methods:{
toggle(){
this.toggleName = this.toggleName === "add"?"sub":"add";
}
}
})
</script>

保留状态 keep-live

当你在其中一个组件模版中添加inputcheckbox再进行切换时,你会发现在切换后,原先组件的属性并不会被保留。因为当组件被切换就会把组件进行销毁

这时我们可以在建立组件的时候使用<keep-alive>组件包围起来,状态就可以被保留

1
2
3
<keep-live>
<component v-bind:is="toggleName">
</keep-live>

动画效果

1
2
3
<transition mode="in-out">
<component v-bind:is="toggleName">
</transition>

同时可以使用in-outout-in指定过渡样式

父子组件

  • 什么是父子组件

    在一个组件中又定义了其他组件就是父子组件

    其实局部定义组件就是最简单的父子组件,因为我们说过可以把Vue实例看作把Vue实例看作是一个大组件

    我们在Vue实例中定义了局部组件,就相当于在大组件里面定义了小组件,所以局部组件就是最简单的父子组件

  • 如何定义其他的父子组件

    自定义组件中可以使用data,可以使用methods,当然组定义组件组件中也可以使用components

VueX

VueX是Vue配套的公共数据管理工具,我们可以将共享的数据保存到Vuex中,方便整个程序中的任何组件都可以获取和修改Vuex中保存的公共数据

创建Vuex对象

1
2
3
4
5
6
7
8
<script>
const store = new Vuex.Store({
// state功能与组件中的data,用来存放共享数据
state: {
count: 0
}
})
</script>

在组件中使用Vuex对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
// 父组件
Vue.component('topTemplate',{
template: '#topTemplate',
// 在顶级组件中导入Vuex
store: store,
// 一级子组件
components:{
'secTemplate': {
template: '#secTemplate',
// 二级子组件
components: {
'thiTemplate': {
template: '#thiTemplate'
}
}
}
}
})
</script>

在顶级组件中使用Vuex对象,所以子类都能继承Vuex对象

输出共享数据

1
2
3
<div>
{{this.$store.state.count}}
</div>
  • 效果

    Vuex is easy!

修改共享数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
// 一级子组件
components:{
'secTemplate': {
template: '#secTemplate',
methods: {
add(){
this.$store.state.count = this.$store.state.count + 1;
},
sub(){
this.$store.state.count = this.$store.state.count + 1;
}
}
}
}
</script>

在Vuex中不推荐直接修改共享数据

如果多个组件都修改了共享的数据,那么后期数据发生了错误,调试错误需要把每一个修改了数据的组件都需要检查一遍

使用方法修改共享数据

创建VueX对象的修改方法 mutations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
const store = new Vuex.Store({
// state功能与组件中的data,用来存放共享数据
state: {
count: 0
},
mutations:{
addCount(state){
state.count= state.count + 1
},
subCount(state){
state.count= state.count - 1
}
}
})
</script>

在执行mutations中定义的方法的时候,系统会自动给方法传递一个state属性

state中就保存了共享的数据

调用VueX对象的修改方法 commit

1
2
3
4
5
6
7
8
9
10
<script>
methods:{
add(){
this.$store.commit("addCount")
}
sub(){
this.$store.commit("subCount")
}
}
</script>

VueX的getter属性

getter方法类似于 Vue实例中的computed属性

定义Vuex的Getter方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
const store = new Vuex.Store({
// state功能与组件中的data,用来存放共享数据
state: {
msg: 'Vuex'
},
getter:{
formatMsg(state){
console.log("getter方法被执行了") // ==>只会输出一次
return state.msg + ' is very easy!'
}
}
})
</script>

调用Vuex的Getter方法

1
2
3
<div>
{{this.$store.getters.formatMsg}}
</div>

Vue Router

Vue Router和v-if / v-show 一样,是用来切换组件显示的

与v-if/v-show的不同

v-if / v-show 是用标记来切换(true/false

Vue Router哈希来切换(#/xxx

v-if / v-show 相比,Vue Router不仅能切换组件的显示,还能再切换的时候传递参数

使用步骤

定义组件

1
2
3
4
5
6
7
8
<script>
const one = {
template:"#one"
}
const two = {
template:"#two"
}
</script>

定义切换规则

1
2
3
4
5
6
<script>
const routes = [
{path:'/one', component: one },
{path:'/two', component: two }
]
</script>

创建路由对象

1
2
3
4
5
<script>
const router = new VueRouter({
routes: routes
});
</script>

将实例绑定到Vue中

1
2
3
4
5
6
7
8
<script>
let vue = new Vue({
el:'#app',
router: router,
data:{
}
})
</script>

切换到路由界面

1
2
3
4
<div id="app">
<a href="#/one"></a>
<a href="#/two"></a>
</div>

路由显示的位置

1
2
3
4
5
6
<div id="app">
<a href="#/one">切换到one页面</a>
<a href="#/two">切换到two界面</a>
<!-- 定义所指定的路由所指向的组件的显示位置 -->
<route-view></route-view>
</div>

其他的操作

除了这些路由的相关操作以外,为了让程序能够正常运行,我们还应该定义 one 和 two 两个组件

定义相应的组件

1
2
3
4
5
6
<template id="one">
<div>我是one页面</div>
</template>
<template id="two">
<div>我是one页面</div>
</template>

想了解template的用法 跳转

这时我们点击对应的 <a> 标签,就应该可以看到页面的变化了

router-link标签

1
2
3
4
5
6
<div id="app">
<router-link to="/one">切换到one界面</router-link>
<router-link to="/two">切换到two界面</router-link>
<!-- 定义所指定的路由所指向的组件的显示位置 -->
<route-view></route-view>
</div>

通过 <router-link>设定了urlHash值的话,就不用写#

to : 定义Hash

tag : 定义标签名,默认为<a>,在Vue3中已经被移除,使用了v-slot代替

linkActiveClass属性

1
2
3
4
5
6
7
8
9
10
11
<style>
.activeing{

}
</style>
<script>
const router = new VueRouter({
routes: routes,
linkActiveClass: 'activeing'
});
</script>

当路由为被激活状态时,会写入相应的class标签

定义在创建路由的步骤

重定向路由

当我们不带任何路由指向访问网站时,我们可以通过重定向的方式,强制加载相应的组件

1
2
3
4
5
6
7
<script>
const routes = [
{path:'/', redirect:'/one'}
{path:'/one', component: one },
{path:'/two', component: two }
]
</script>

路由传递参数

只要将Vue Router挂载到了Vue实例对象上,我们就可以通过vue.¥route拿到路由对象

只要能拿到路由对象,就可以通过路由对象拿到传递的参数

如何拿到路由参数

URL方式传递

在指定hash的时候,通过?key=value&key=value的方式传递

1
2
3
<div id="app">
<router-link to="/one?name=Xonline&website=xon.ink" tag="button">带参数的路由切换</router-link>
</div>

在组件的生命周期方法中,通过this.$route.query方式获取

1
2
3
4
5
6
7
8
<script>
const one = {
template: "#one",
created: function (){
console.log(this.$route.query)
}
}
</script>

在控制台中,我们可以看到我们接受到了一个对象,在对象的query中,我们可以看到我们发送的数据

在使用时,我们可以使用

1
2
this.$route.query.name // 输出 Xonline
this.$route.query.website // 输出 xon.ink

路由规则占位符传递

在指定路由规则的时候通过 /:key/:key的方式来指定占位符

1
2
3
4
5
6
7
8
9
<script>
// 在创建路由规则的时候
const routes = [
{
path: '/one/:name/:website',
component: one
}
]
</script>

在指定hash的时候通过/value/value的方式来传递值

1
2
3
<div id="app">
<router-link to="/one/Xonline/xon.ink" tag="button">带参数的路由切换</router-link>
</div>

书写参数时,要与占位符对应

在组件的生命周期方法中,通过this.$route.params方式来获取

1
2
3
4
5
6
7
8
<script>
const one = {
template: "#one",
created: function (){
console.log(this.$route.params)
}
}
</script>

URL传递的接收方式一样,来获取传递的数据

1
2
this.$route.params.name // 输出 Xonline
this.$route.params.website // 输出 xon.ink

嵌套路由(未完)

嵌套路由也称之为子路由,就是在被切换的组件中又切换其他子组件

watch属性

Watch属性是专门用于监听数据变化的,只要数据发生了变化,就会自动调用对应数据的回调方法

Watch属性如何监听路由变化

Watch属性不仅仅能够监听数据的变化,还能监听路由地址的变化

Vue-CLI 手脚架工具

  • Command Line Interface

    Vue-CLI是Vue官方提供的手脚架工具

    默认已经帮我们搭建好了一套利用webpack管理vue的项目结构

安装&使用 Vue-cli

事先需要安装node.js,更新npm

安装手脚架

1
npm install -g @vue/cli

检查是否安装成功

1
vue --version

通过手脚架创建项目

1
vue create project-name

Vue-cli目录

node_modules : 存放当前项目的依赖包

public :

src :

build :

config :

为什么没有webpack配置文件

当使用Vue-cli 3.x以后的版本 webpack的配置文件被隐藏起来的了

手动配置Vue项目

  • 选择手动配置Vue-cli

选择手动配置Vue-cli

  • 选择需要安装的插件&依赖

选择需要安装的插件&依赖

按上下方向键选择,空格选中,回车下一步

Babel :

TypeScript :

Progressive Web App (PWA) Support :

Router : 路由

Vuex : 共享数据

CSS Pre-processors : CSS预处理器

CSS预处理器选择

Linter / Formatter : 代码规范检查 / 格式化代码工具

代码规范检查模式选择

Unit Testing : 单元测试

E2E Testing :

请我喝杯咖啡吧~

支付宝
微信