万字复盘Vue2相关知识(适合学过但忘了然而需要上手的朋友)

前言

这是一篇帮助读者快速复盘Vue2有关实践知识点的博客。

先说说笔者的情况吧,写这篇文章的一个月前,我刚帮老师做完他的公司的官方网站,这是一个展示形的网站,写了两天,内容基本写完。

这一个月时间里,我没有碰Vue2的相关内容,而是复习了跟前端请求的相关内容。所以一个月后要我改这个网站,我看着代码内心是懵的。因此想花一个下午时间去复盘一下和Vue2实践相关的内容。

注意事项:本文针对的是和我情况类似,之前系统学过Vue2但是因为很久没碰忘记了的朋友,目的不是重新学习,而是复盘。所以很多内容我都是一笔带过的,重点内容我会有详细的步骤讲解。希望读者体谅。

最后我来说一下本文的大致内容,分为以下几块:脚手架创建vue项目及其基本配置,vue的基础部分,重要的生命周期函数,组件化编程,组件之间的信息传递,以及vue路由

当然,这也不是一个简单的回顾文章,内部还会包含很多我做项目的经验。希望能对您有帮助!!

一,Vue2项目的创建及基本配置

1.1 用脚手架创建项目

选择合适的文件夹,打开终端,输入命令行语句:

Vue create 文件名

选择合适的配置即可。

1.2 项目结构

在这里插入图片描述
上面的图片是用脚手架创建的一个最初的vue2项目的结构。需要了解,src内部放置的是自己写的代码,assets存放图片,components存放组件,main.js是入口文件,App.vue可以理解为项目最初渲染的组件。

1.3 入口文件main.js

main.js一开始的配置是固定的。

首先,引入Vue文件

import Vue from 'vue'

接着,引入App.vue

import App from './App.vue'

然后,创建Vue的实例对象。Vue本质上是一个构造函数,所以我们创建Vue构造函数的实例对象

new Vue({
	el: '#app',
	render: h => h(App)
})

还有一种写法,这种写法也是脚手架给我们的写法:

new Vue({
	render: h => h(App)
}).$mount('#app')

这里简单说一下为什么需要render。render的作用在于:弥补非完整版Vue的模板解析作用,render是一个函数,参数就是一个h函数。==作用是把App的内容放入一开始的页面中。==有了这一步,我们打开项目后,看到的就是App组件中的内容。

1.4 组件配置

这里要说一下App组件的基本配置。

<template>
  <div></div>
</template>

<script>
export default {
  name: 'App',
  data() {
  	return {}
  }
}
</script>

<style scoped>

</style>

一般情况下,Vue2项目中的组件,会以以上格式呈现。其中,template内部需要有一个div,这个div又叫作根结点,在Vue2的组件中,一定要有一个根结点(Vue3不用)。

接着是name,每个组件可以有一个组件名,这一点在路由规则中会用到。

最后是data,data中的数据在vue2中一定要以这种形式来写。data分为函数形与对象形,如果在vue中写成对象形式,则多个组件都使用data,会对data进行改动,一个组件对data的改动会影响所有组件中的data,所以必须使用函数形式来写data

最后再提一句style中的scoped。scoped的存在在于,如果组件A与组件B的内容中,都有一个叫box的类,如果没有scoped,则在一个项目中类名相同,元素样式会互相影响。scoped存在,则不会有这类问题,每个组件的样式都是独立的,不受其他组件影响。

1.4 运行项目

打开终端

npm run serve

如果要打包项目

npm run build

当然,这些知识脚手架下的命令语句,可以改的但是需要配置。有些vue2模板的语句也是有不一样的,通常下面这个也比较常用:

npm run dev

二,Vue的基础知识

这一节涵盖的内容有:数据显示、数据绑定、事件处理、循环遍历、判断语法、计算属性、监控属性。

再次提醒,由于内容较多,所以很多地方一笔带过!

2.1 数据显示

数据显示,这里介绍三个,分别是v-text、v-html与插值语法。

指令格式:

<div v-text='123'></div>
<div v-html="<h1>123</h1>"></div>

注意,v-html要少用,尤其忌讳放置a链接。容易引起XSS攻击

比较重要的就是插值语法了,请看下面代码:

<template>
  <div>
    <h1>个人信息</h1>
    name: {{ person.name }}
    age: {{ person.age }}
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      person: {
        name: '巧克力小猫猿',
        age: 20
      }
    }
  }
}
</script>

这段代码中,下面是data,上面用插值语法把下面的内容给引出来了。

这里我要说的是,在vue2中,如果需要对数据进行操作,需要获取数据,请看下面代码:

<template>
  <div>
    <h1>个人信息</h1>
    name: {{ person.name }}
    age: {{ person.age }}
    <button @click="add">+1</button>
  </div>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      person: {
        name: '巧克力小猫猿',
        age: 20
      }
    }
  },
  methods: {
    add() {
      this.person.age ++;
    }
  },
}
</script>

在上面这段代码中,实现的是对年龄加1,首先要获取age,插值语法中,直接写的是person.age,但是在函数中,获取age则需要用到this。

2.2 数据绑定

数据绑定分为两种,一种是数据的单向绑定,一种是数据的双向绑定。

单向绑定:v-bind
双向绑定:v-model

从表单开始介绍,请看以下代码:

    <br>
    班级1: <input type="text" v-bind:value="person.class">
    班级2: <input type="text" v-model="person.class2">

在这里插入图片描述
最后结果:
在这里插入图片描述

最后结果描述:由于表单被单向绑定和双向绑定,所以value都是提前设置好的值。不同的是,对于单向绑定,在页面上修改值数据无法同步,但是在下面的控制台中修改数据,正确是数据能够被渲染;

双向绑定的话,在页面修改值,data中的数据会改变;改变data中的数据,页面的值也会改变。

双向绑定用于表单,但是单向绑定,也就是v-bind,除了表单之外,还有很多用处,比如组件之间传递数据(后面会写),比如在标签中想要读取js代码:
在这里插入图片描述
单向绑定需要注意的问题是:用了单向绑定,引号内部的是js代码。

最后要说的是,单向绑定的简写,在前面加冒号,就是上一张图片那样。

2.3 事件处理

事件处理相当于原生中点击,鼠标经过,鼠标离开等事件。在触发事件后会有一个回调函数,在vue中叫作事件处理。

还是刚刚那个例子,设置一个按钮,点击按钮年龄往上加,这里了解简写就好:

    age: {{ person.age }}
    <button @click="add">+1</button>

这里其实是为button绑定了add事件;add事件在methods中写:

  methods: {
    add() {
      this.person.age ++;
    }

上面这个也是用的最多的。

2.4 循环遍历

这是一个很重要的点。并且有很多关键的地方。

首先,在data中给出一个数组:

      arr: [1, 2, 3, 4, 5]

接着开始遍历。

这里需要注意的是,在vue中,遍历一般用的都是ul和li:

    <ul>
      <li v-for="a in arr" :key="a.id">{{ a }}</li>
    </ul>

ul是固定的,有多少条数据,就会自动生成多少个li。在li中有一个v-for,v-for有两个内容,a是我们自定义的一个变量,它来存放我们的数据,arr是需要遍历的数组。a in arr的意思就是,遍历数组arr,每条数据由对应的a来存放。

每个数据都会自动生成一个id,id可以理解为数据的身份证。这个:key必须要有,不然会报错。

由于是复盘文章所以原理略过,感兴趣可以去查看跟响应式有关的博客了解原理。后面会出一个专题专门记录Vue中的原理部分,可以关注一波。

在li的内容中用插值语法来写出我们需要的数据。

最后的效果:
在这里插入图片描述

2.5 判断语法

判断语法分为v-if和v-show。

它们能够根据一定的判断条件来设置页面中的元素是否能看见。其中,v-if的原理是,如果满足条件显示,不满足条件则删掉页面结构;v-show是根据display:none来设置的,只是隐藏页面内容而已,页面结构依旧存在。

2.6 计算属性

计算属性的本质是个函数。

这里我们来看一个姓名案例,我会结合代码进行分析:

<template>
  <div class="box">
    姓氏: {{ firstName }}
    <br>
    名字: {{ lastName }}
    <br>
    合计: {{ fullName }}
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      firstName: '巧',
      lastName: '克力小猫猿',
    }
  },
  computed: {
    fullName() {
      return this.firstName + this.lastName
    }
  }
}
</script>

上面是计算属性的简写部分。用到最多的其实也是简写。computed是计算属性的标志,后面的fullName函数,是对fullName进行了加工。在页面结构中可以直接使用插值语法:
在这里插入图片描述
复杂版本的计算属性中还会有get和set,这里就略了可自行了解。

2.7 监视属性

这里同样也是介绍简洁版本的监视属性,监视属性与计算属性非常类似,在刚刚的基础上加上了这段代码:

  watch: {
    fullName(newvalue, oldvalue) {
      console.log(newvalue)
      console.log(oldvalue)
    }
  }

监视属性有两个参数,一个是newvalue一个是oldvalue,分别是fullName的最新值,和旧的值。
在这里插入图片描述

三,重要的生命周期函数

如果不了解生命周期,可以去了解下。本节只讲一些重要的生命周期函数。

3.1 整体复习

如果需要了解vue2的全部生命周期函数,可以把这段代码复制下来,打断点运行体验。(不用在脚手架上跑,直接跑就可以)

<!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">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>
<body>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
    <div id="root">
         <h2>当前的n值是: {{ n }}</h2>
        <button @click="add">点我n+1</button>
        <button @click="bye">点我销毁</button>
    </div>

    <script>
        new Vue({
            el: '#root',
            data: {
                n: 1
            },
            methods: {
                add() {
                    this.n++    
                },
                bye() {
                    console.log('bye')
                    this.$destroy()
                }
            },
            beforeCreate() {
                console.log('beforeCreate')  
            },
            created() {
                console.log('created')
            },
            beforeMount() {
                console.log('beforeMount')
            },
            mounted() {
                console.log('mounted')
            },
            beforeupdate() {
                console.log('beforeupdate')
            },
            updated() {
                console.log('updated')
            },
            beforeDestroy() {
                console.log('beforeDestroy')
            },
            destroyed() {
                console.log('destroyed')
            }
        })
    </script>
</body>
</html>

3.2 重要的生命周期钩子

一个是mounted:发送ajax,axios请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。

一个是beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

四,组件化编程

4.1 概述

组件化编程这一节,涉及到组件的相关配置。

这里就要了解父组件,子组件了。

这两张图片可以说明一定的问题:
在这里插入图片描述

在这里插入图片描述
总结一下组件的标准定义:实现应用中局部功能代码和资源的集合。

4.2 组件的局部注册

需求:在App组件中导入Son组件。

先来说说部分导入吧。在一个组件中引用另一个组件。

请看以下代码:

<template>
  <div class="box">
    子组件:<Son></Son>

  </div>
</template>

<script>
import Son from '@/components/Son.vue'
export default {
  name: 'App',
  components: {
    Son
  }
}
</script>

一共三个点,首先,引入组件。这里我想提醒下,引用地址的时候能用@尽量用@,因为如果是用./或者…/的话,后面很容易因为一个文件位置变了报很多错;

接着就是,注册组件,注册组件的时候如果组件名和组件本身的名字是一样的话,那就可以简写;

最后就是用组件的使用了,使用组件的时候,把它写成类似标签的样式即可。

4.3 组件的全局注册

全局注册,顾名思义,就是所有的组件都可以用这个全局注册过的组件,所以现在我们来看一下如何全局注册一个组件,还是以Son为例吧。

一般注册一些全局的东西,都在入口文件,也就是main.js上。

这就要使用Vue中的一个api,Vue.component(),但是api的参数一定是一个键值对,左边是组件名称,右边是组件(不然会报错)。组件要先经过引入才可以使用。

代码如下:

import Vue from 'vue'
import App from './App.vue'

// 全局组件
import Son from '@/components/Son.vue'
Vue.component('Son', Son)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

注册完毕后直接使用即可。

4.4 插槽

关于插槽我之前写过一篇很详细的文章:vue插槽之插槽的用法及作用域插槽详解

这里就简单概括以下几点吧,概括的前提是,接着刚刚的案例,父组件是App,子组件是Son。

接着我们再来回顾下插槽的理解,其实就是,在子组件中空出一个位置,在父组件中填这个位置。我们做的其实就是这样的事情。

4.4.1 默认插槽

首先,在子组件中放一个位置:
在这里插入图片描述
接着,在父组件中放置内容:
在这里插入图片描述
最后的效果:
在这里插入图片描述
刚刚上面这个插槽,我们称之为默认插槽。

4.4.2 具名插槽

具名插槽意为,取名字的插槽。

这里给个需求:需要两个插槽,一个名字叫one,一个名字叫two。两个插槽内容不同。

所以我们先在子组件中放置插槽,并且给插槽取名字。
在这里插入图片描述
接着在父组件中书写插槽内容,并对应上插槽:
在这里插入图片描述
最后效果:
在这里插入图片描述

五,组件之间的信息传递

组件之间的通讯有多种,本节复习的内容有:父传给子利用props(最基本)、子传给父(自定义事件)、ref传递数据、事件车、以及Vuex。算是一个比较综合的概括。

详情可以看这两篇文章,下面的只是复盘不会特别详细:
Vue组件之间的数据共享详解
vue事件车的原理与标准写法实现兄弟组件的传值
vue中利用ref实现更灵活的子向父传值

5.1 父向子传值

父向子传值的方式非常简单:利用props。

父组件利用单向绑定,把数据传给子元素,子元素利用props接收,以下是代码部分。

父组件:

<template>
  <div class="box">
    <Son :students="students"></Son>
  </div>
</template>

<script>
import Son from '@/components/Son.vue'
export default {
    name: 'App',
    data() {
        return {
            students: [
                {name: 'zxd', age: 20},
                {name: 'wxy', age: 20}
            ]
        }
    },
    components: {
        Son
    }
}
</script>

子组件:

<template>
  <div class="box">
    <ul>
        <li v-for="s in students" :key="s.id">
        {{ s.name }}--{{ s.age }}</li>
    </ul>
  </div>
</template>

<script>
export default {
    name: 'Son',
    props: ['students']
}
</script>

5.2 子向父传值

子向父传值用的是自定义事件。

在子组件中定义事件,在父组件中触发。

这里要了解下$emit这个方法,这里可以理解为触发,触发自定义事件。当然,触发自定义事件是有前提的自定义事件被定义了。

我们在父组件中写一个自定义事件:
这里要注意,这个自定义事件是绑在子组件上面的:给谁绑定的自定义事件,就去找谁触发。
在这里插入图片描述

接着再看看看看子组件代码:点击按钮,add函数被调用,触发了父组件中定义的自定义事件fun。于是在子组件中,自定义事件被调用。

        <button @click="add">发送信息</button>
    </ul>
  </div>
</template>

<script>
export default {
    name: 'Son',
    props: ['students'],
    data() {
      return {
        baby: {
          age: 20,
          name: 'wxy'
        }
      }
    },
    methods: {
      add() {
        this.$emit('fun', this.baby);
      }
    }

子组件中的自定义事件被触发,或者被调用后,父组件会执行一个回调函数:在这个回调函数中可接收到子组件传过来的参数:

    methods: {
        get(value) {
            this.message = value;
            console.log(value)
        }
    }

步骤就算完成了:
在这里插入图片描述
可能有些读者没办法理解步骤为什么是这样的,这里来个解释:我们在父组件中,利用事件绑定,给子组件绑定了一个自定义事件fun。由于给谁绑定自定义事件就找谁触发。所以在子组件中用$emit触发自定义事件。自定义事件触发需要两个参数,一个是自定义事件名称,一个是自定义事件需要用到的参数。事件被触发后,会有一个回调函数。回调函数在父组件中,于是父组件得以接收到子组件传递过来的参数。

如果还没有明白,那我来说一下触发和回调。这就要聊到原生的js,看一下下面的代码,在下面代码中,实际上是触发了click事件,然后有一个触发后的回调。在上面的例子中也是,在子组件中触发,在父组件中回调:

<button class="btn"></button>
<script>
	var btn = document.querySelector('btn')
	btn.addEventlistner('click', () => {
		alert('123')
})
</script>

如果再看不懂的话就去复习自定义函数这一块内容。

5.3 事件车

关于事件车,上文链接的博客其实写的很清楚。但是这里也会尽量讲清楚滴。

还是来复习一下原理吧:
在这里插入图片描述
我们把x称之为事件车,把x看成一个联络方,D可以把数据给x,A可以从x中拿取数据。这一节需要利用上一节的思路——自定义事件。我们可以通过x触发自定义事件,把参数传递给x,还可以通过x执行回调,拿到参数。这对x的要求就很高:x需要能够被所有组件看见(所有组件都能访问到x),x还需要能够使用on和emit。

什么样的x符合上面的条件呢?在原型上。原型中的方法是可以被所有组件看到的。这里写一下标准写法,如果要剖析原理,请移步上面链接的博客。

首先配置以下入口文件main.js:

import Vue from 'vue'
import App from '@/App.vue'
Vue.use(App)

new Vue({
    render: h => h(App),
    beforeCreate() {
        Vue.prototypes.$bus = this
    }
}).$mount('#app')

这里,$bus就是刚刚的x,可以称之为数据总线,也可称之为事件车。

接着就可以用到它传递数据了。这里设置两个组件,组件A,组件B。我们在这两个平级组件中传递数据。A传向B。

先来看一下A的代码,在A中,利用emit触发自定义事件:

<template>
    <div class="box"></div>
</template>

<script>
export default {
    name: 'A',
    data() {
        return {
            me: {
                name: 'qklxmy',
                age: 20,
                job: 'zhongruan'
            }
        }
    },
    created() {
        this.$bus.$emit('toB', this.me)
    }
}
</script>

<style scoped></style>

再看看B的,B中用到on,on的作用实际上就是,接收自定义事件中的参数并回调:

<template>
</template>

<script>
export default {
    name: 'B',
    mounted() {
        this.$bus.$on('toB', (value) => {
            console.log(value)
        })
    }

}
</script>

<style scoped></style>

以上,就是事件车的用法。

六,路由

本节会复盘路由的配置、路由的基本用法、嵌套路由。本节内容需要对路由有一定理解:在单页面应用中,起到与链接相同作用的就是路由。路由可以理解为key-value的对应关系,就像链接,点击后就会到某个新的页面。路由也起到这样的作用,只不过,规则写在了路由规则里面。

6.1 路由的配置

6.1.1 入口文件配置

先配置入口文件main.js

import Vue from 'vue'
import App from '@/App.vue'
//引入路由器
import VueRouter from 'vue-router'
//引入路由规则
import router from '@/router/index'

Vue.use(VueRouter)

new Vue({
    render: h => h(App),
    router: router
}).$mount('#app');

我们来分析下入口文件:

排去之前最基本的配置,导入了路由器和路由规则。并且路由器需要注册引入以下;在Vue中也要配置router文件。

6.1.2 路由规则配置

路由规则在router文件夹里面:
在这里插入图片描述
接着我们对路由规则进行配置:

import VueRouter from 'vue-router'

export default new VueRouter({
    
})

在这段代码中,首先引入路由器,接着创建一个VueRouter对象,内部放置的是路由规则,路由规则我们后面说。但是写的路由规则需要能被路由器访问到,所以要export default 出去。

6.2 路由的基本使用

我们先看一下效果吧,效果出来了之后再一步步分析。

运行后,首先看到的是:
在这里插入图片描述
点击Home后:
在这里插入图片描述
点击About后:
在这里插入图片描述
请看下上面的链接变化:当我们点击Home,链接对应到/home,下面展示Home;当我们点击About,链接对应到/about,下面展示About。

上面说的就是链接,链接规则(路由,路由规则)。所以我们先从路由规则入手,在上面引入组件,下面写路由规则:

import VueRouter from 'vue-router'
//组件引入
import About from '@/Pages/About.vue'
import Home from '@/Pages/Home.vue'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home
        }
    ]
})

并且在app中写出链接和展示链接的地方(路由和展示路由的地方),router-link和router-view。其中,router-link需要加上一个to,to后面是地址。

<template>
  <div class="box">
    <router-link to="/home"><button>Home</button></router-link>
    <router-link to="/about"><button>About</button></router-link>

    <router-view></router-view>
  </div>
</template>

<script>
export default {
    name: 'App'
}
</script>

<style scoped>

</style>

6.3 嵌套路由

还是先看效果。

初始页面:
在这里插入图片描述
点击About:
在这里插入图片描述
点击about中任意一个按钮:
在这里插入图片描述
可以看到,是about中嵌套了路由。

看路由规则,内部有一个children。并且需要记住,路由规则中,子组件的规则无需写完整。

import VueRouter from 'vue-router'
//组件引入
import About from '@/Pages/About.vue'
import Home from '@/Pages/Home.vue'
//嵌套组件
import Messages from '@/Pages/Messages'
import News from '@/Pages/News'

export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: About, 
            children: [
                {
                    path: 'messages',
                    component: Messages
                }, 
                {
                    path: 'news',
                    component: News
                }
            ]
        },
        {
            path: '/home',
            component: Home
        }
    ]
})

再看一下about组件:router-link的地址中,地址需要写完整。

<template>
  <div class="box">
    <router-link to="/about/news"><button>News</button></router-link>
    <router-link to="/about/messages"><button>Messages</button></router-link>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
    name: 'About'
}
</script>

<style scoped>

</style>

后记

本篇文章阐述了Vue2的一些基本知识,与其说基本,不如说基础——必须要掌握的东西。

还有很多东西需要在做项目中用到的。如果想了解更多可以关注我,关注我的一些博客。

就这么多啦,爆肝不易,每天都在摸鱼时间写博客。希望能收获一波点赞关注。虽然不会给我带来很多收益,但是每每点开看到点赞与收藏的地方有小红点,会很开心。

谢谢大家,祝大家都找到好工作!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值