Vue-cli(vue脚手架)上万字总结,超详细教程-程序员宅基地

技术标签: vue  前端  后端  

1、创建Vue脚手架

1.1、首先系统需要全局安装Vue脚手架

npm install -g @vue/cli

1.2、创建Vue脚手架工程

进入你想创建vue脚手架的目录,然后输入命令

vue create xxx项目名

需要注意的是工程名字不能大写,这里我们选择选择Vue2,敲下回车,那么vue将会为我们创建vue脚手架
在这里插入图片描述
显示如图所示说明创建成功
在这里插入图片描述
如图命令所示 我们进入myvue工程,执行命令
npm run serve
然后浏览器访问http://localhost:8080/
在这里插入图片描述
到这里 我们的vue脚手架工程就跑起来了,关闭为Ctrl+C

2、Vue脚手架的文件结构说明

├── node_modules 
├── public
│   ├── favicon.ico: 页签图标
│   └── index.html: 主页面
├── src
│   ├── assets: 存放静态资源
│   │   └── logo.png
│   │── component: 存放组件
│   │   └── HelloWorld.vue
│   │── App.vue: 汇总所有组件
│   │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

3、修改默认配置

Vue-cli官网配置参考:https://cli.vuejs.org/zh/config/#publicpath

在工程根目录下创建文件vue.config.js

在这里插入图片描述
这里我们演示配置一下语法检查

3.1、配置前

在这里插入图片描述
会发现,默认语法检查是开启的,然后我们写了一个function没有被使用的话就会导致整个项目启动不了,所以在实际开发中,会带来很多障碍,所以我们将它关闭。

3.2、配置后

在vue.config.js中,加入以下代码
在这里插入图片描述
这时发现,默认配置已被修改,项目正常启动。
后序我们修改默认都可以结合官网的文档在该文件夹中配置

4、标签的 ref属性

因为在Vue里使用原生js拿去Dom元素不太好,所以就有了ref属性

4.1、ref属性的作用

1、被用来给元素或子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真是Dmo元素,应用在组件标签上的是组件实例对象(vc)
3.使用方法:

 <h1 ref="xxx">......</h1> 或<组件ref="xxx"></组件>
 获取:this.$refs.xxx

作用就相当于给一个表情加了个id=“xxx” 然后通过document.getElementById(“xxx”)的效果一样。

4.2、示范

编写一个School.vue组件,然后在App.vue中引入
在这里插入图片描述
我们访问网页 会发现,拿得到Dom元素,测试成功!
在这里插入图片描述

5、props配置

5.1、功能

让组件接收外部传递过来的数据,从而达到组件复用的目的
(1).传递数据

<Demo name="xxx"/>

(2).接收数据

第一种方式(只接收):

props:['name']

在这里插入图片描述
会发现以上会出现一个问题,如果我们需要传递18而显示19的话,那就需要做一下调整,因为默认传递过去的是一个字符串类型的数据,所以会造成字符串的拼接,所以我们得在传递的属性上面加 : 或者 v-bind ,他就会将表达式中的值正真的传递过去而不是以字符串的形式。

在这里插入图片描述
第二种方式(限制类型):

props{
    
	name:String
}

在这里插入图片描述
会发现传递字符串的话就会报错,一样通过:或者v-bind解决
在这里插入图片描述

第三种方式(限制类型、限制必要性、指定默认值)
在这里插入图片描述

props:{
    
	name:{
    
    	   type:String, //类型
    	   required:true, //是否必传
    	   default:'老王'//默认值
    }
}

备注:props是只读的,不能修改,Vue底层会检测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
如图所示:
在这里插入图片描述

6、mixin混入

6.1、功能

(1)示范准备

可以看到School和Student组件中有相同的方法
在这里插入图片描述
我们可以将其抽取出来达到复用的效果。

(2)创建一个js文件将相同的代码抽取出来,然后在Student和School组件中分别导入。
在这里插入图片描述
(3) 测试

在这里插入图片描述
会发现 抽取出来的方法生效了!!!

6.2、补充

不光上面演示的代码能在写在混合中,Vue中的声明的东西也都可以写在混合中,比如mounted、create,也包括自己定义的一些属性等方法等…混合中的数据最终都会和组件中的数据作一个整合

(1)、示范

一、我们在混合中加入mounted代码块
在这里插入图片描述

在这里插入图片描述
二、我们在混合文件中加入一些属性。
这里我们重新暴露一个代码块,然后代码块中声明name数据,然后School和Student中导入
在这里插入图片描述
测试
在这里插入图片描述
会发现使用name值成功了。注意:从示例中我们可以看到,如果混合和组件中有相同的组件和方法,会以组件中的为准。但是如果是mounted钩子函数,那么都要。并且混合中的钩子函数中的内容会先被执行。

mounted钩子函数测试
在这里插入图片描述
两个组件都引入,会发现混合中的钩子函数内容会先被执行
在这里插入图片描述

6.3、全局混入

上面那些都属于局部混入,导入某个组件内仅供该组件使用。这里介绍全局混入,导入一次可在所有组件中使用混入文件。
在这里插入图片描述

6.4、总结

功能:可以吧多个组件的共同配置提取成一个混入对象
使用方式:

第一步定义混合,例如:
	{
    
	  data(){
    ....},
	  methods:{
    ....}
	}
第二部使用混入,例如:
    (1).全局混入:Vue.minxin(xxx)
    (2).局部混入:mixins:[xxx]

7、插件

7.1、功能

功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数就是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:

	对象.install=function(Vue,options){
    
		
		//1.添加全局过滤器
		Vue.filter(...)
		
		//2.添加全局指令
		Vue.directive(...)
		
		//3.配置全局混入
		Vue.minxin(...)

		//4.添加实例方法
		Vue.prototype.xxx=function(){
    
		  .....
		}
		Vue.prototype.xxx=(...)=>{
    
		 ......
		}

    }

1、示范

先创建一个plugins.js文件,然后在文件中install方法中声明一些全局混入 或者方法等…
在这里插入图片描述
2、导入并且使用插件
在main.js 中导入并且在School组件中使用插件中定义的各种混入,方法,过滤器等…
在这里插入图片描述
3、测试
在这里插入图片描述
4、补充

在使用插件的时候 还可以传递参数
在这里插入图片描述

8、scoped样式

8.1、功能
作用:让样式在局部生效
写法:在style标签上加上scoped即可

<style scoped></style>

示范
在两个组件中都使用相同的样式
在这里插入图片描述
会发现样式会有冲突,所以我们在标签上加上 scoped
在这里插入图片描述
会发现,成功啦!!!

9、组件的自定义事件

9.1、props传递 方法

通过前面的知识我们可以知道,父组件在向子组件传递数据的时候可以在使用子组件时传递参数然后子组件中通过props属性接收参数,其实不光可以接受传递过来的属性,然后也可以接收传递过来的方法。然后子组件中调用方法,通过参数列表像父组件的方法中传递数据。

示范

需求:子组件中的数据传递到父组件中然后显示

(1)、准备一个student组件,然后父组件传递方法,子组件接收传递过来的方法
在这里插入图片描述
在子组件中调用父组件中的方法,则会回调父组件中传递的那个方法,参数则为子组件中传递的参数,那么父组件中就拿到子组件中传递过来的数据了。
(2)、测试
在这里插入图片描述
测试成功!!!

9.2、自定义事件(写法一)

上面的例子是通过props属性的方式实现的,我们还可以通过自定义事件的方式实现子组件 像父组件传递数据

示范

(1)、同样准备一个Student组件,然后在父组件中为子组件绑定事件和回调函数,然后在子组件触发父组件绑定的事件

触发事件用this.$emit('xxx',参数1,参数2...)

在这里插入图片描述
当然,参数想传递多少都是可以的。

(2)、测试
在这里插入图片描述
哈哈,成功啦!!!

9.3、自定义事件(写法二)

(1)、我们还可以通过ref的方式给指定的组件绑定事件
在这里插入图片描述
(2)、测试
在这里插入图片描述
成功啦!!!咋样,是不是很简单呢。

(3)、补充
既然能给组件绑定自定义事件,那么我们也可以解绑自定义事件,记住,给哪个组件绑定的事件就找那个组件触发去,同样,给哪个组件绑定的事件,就找哪个组件解绑

解绑指定的事件:this.$off('xxxxxx');
解绑多个事件:this.$off(['xxx','xxx']);
如果解绑所有事件,直接用: this.$off( );

在这里插入图片描述
解绑之后,那么这个事件就无法被触发了。

9.4、总结

组件的自定义事件

1、是一种组件间的通信方式,适用于子组件===>父组件
2、使用场景: A是父组件,B是子组件,B想给A传递数据,那么就要在A中给B绑定自定义事件和回调函数(回调函数在A中,参数则为B传递过来的)
3、绑定自定义事件:

  1. 第一种,在父组件中
<Demo @zidingyi="test"/><Demo v-on:zidingyi="test"/>
  1. 第二种,在父组件中
<Demo ref="demo"/>
......
mounted(){
    
	this.$refs.demo.$on('zidingyi',this.test)
}
         3.若想让事件只出发一次,可以使用**once**修饰符,或**$once**方法。
  1. 触发自定义事件:
在子组件中
this.$emit('zidingyi',参数1,参数二...)
  1. 解绑自定义事件
this.$off('zidingyi')
  1. 组件也可以绑定原生DOM事件,需要使用native修饰符。
    比如:
<Demo @click.native="xxxx"/>

10、全局事件总线

10.1、功能

从上面props和自定义事件例子中可以看到,他们适用于父组件与子组件或者子组件与父组件中的数据传递进行通信,那么如何实现任意两个组件中的通讯呢?

我们可以使用全局事件总线,全局事件总线并不是一个新的技术或者API,只是编码的经验而已。

(1)、首先得先有一个存放数据的地方,并且这个存放的地方必须是所有组件都能看到的。
在这里插入图片描述
通过图中我们可以看到,若所有的vc要拿数据 x (this.xxx),如果x在vc中找不到,那么就会去找VueComponent的原型对象中找,但是每一个组件都会有一个新的VueComponent,所以数据是不共享的,所以不能存在这里,那么就继续往上找到Vue,Vue的原型对象是所有的组件vm或vc都能看到的,所以存在Vue的原型对象中再合适不过了。

(2)、在Vue的原型对象中存入一个组件,那么这个组件就能被其他所有的组件绑定事件或者触发事件,从而达到通讯的目的

在main.js文件中,构建一个组件并且存入Vue的原型对象中
在这里插入图片描述
(3)、准备两个组件Student和School组件,然后在Student给Vue原型对象中的组件绑定事件,然后School中触发事件

在这里插入图片描述
(4)、测试
在这里插入图片描述
会发现,Student组件中触发了School中给公用组件绑定的方法并且拿到了数据。到这里就实现了兄弟组件中的通讯了,不再局限于父穿子,子传父了。

(5)补充
除了上面那种在main.js 中先构建一个组件然后再存入Vue的原型对象中的写法外还有一种比较标准的写法
在这里插入图片描述
将之前原型对象的k为x都改为$bus (起这名是因为bus也总线的意思,哈哈),测试
在这里插入图片描述

10.2、总结

全局事件总进线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间的通信。

  2. 在main.js中开启全局事件总线:

new Vue({
    
	......
	beforeCreate(){
    
	    Vue.prototype.$bus=this //开启全局配置总线
	}
})
  1. 使用事件总线:
    3.1. 接收数据:A组件想要接收数据,则在A组件中给$bug绑定自定义事件,事件的回调留在A组件自身.
methods(){
    
	demo(date){
    
	}
}
......
mounted(){
    
	this.$bus.$on('xxx',this.demo)
}

3.2. 提供数据

this.$bus.$emit('xxx',数据) 
  1. 最好是在beforeDestory构子中,用$off去解绑当前组件所用到的事件。

11、消息的订阅与发布(pubsub.js)

11.1、介绍和使用步骤

除了上面全局事件总线的方式实现任意组件中的通讯,我们还可以借助 消息的订阅与发布(pubsub.js)实现任意的组件中的通讯。

使用步骤

  1. 安装pubsub: npm i pubsub-js
  2. 在组件中引入: import pubsub from 'pubsub-js'
  3. 接收数据:A组件中想要接收数据,则先在A组件中订阅消息,订阅的回调函数留在A组件自身
methods(){
    
	demo(msgName,参数1,参数2){
    ......}
},
......
mounted(){
    
	this.pid=pubsub.subscribe('xxx',this.demo)//订阅消息
},
beforeDestroy(){
    
 pubsub.unsubscribe(this.pid);
}

  1. 提供数据:pubsub.publish('xxx',数据)
  2. 最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)取消订阅

11.2、示范

将之前给公用组件绑定自定义事件的方式替换成消息的订阅与发布
在这里插入图片描述

测试
在这里插入图片描述
测试成功啦!!!

12、$nextTick

12.1、功能

1、需求
如图所示,点击按钮,显示输入框并且输入框获取焦点
在这里插入图片描述
2、代码如图所示
在这里插入图片描述
3、测试
在这里插入图片描述
会发现根本就没有获取焦点

4、分析原因
在这里插入图片描述
在模版都没成功渲染的时候显然连Dom元素都没有获取到

5、解决
这里我们需要借助$nextTick解决
在这里插入图片描述
6、再次测试
在这里插入图片描述
会发现,成功显示输入框并且输入框也获取了焦点

12.2、总结

  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次DOM更新结束后执行指定的回调。
  3. 什么时候用:当改变数据后,要基于更新后的DOM进行某些操作时,要在nextTick所指定的回调函数中执行

13、animate.css

13.1、功能

animate.css包含了很多动画效果,这里我们试一下 显示/隐藏 的动画效果。有了它,我们不再需要自己手写C3动画样式了。非常nice

官网:点击进入首页

示范:

我们准备一个Test组件

1、安装animate.css :npm install animate.css

2、在组件中引入import 'animate.css'

在这里插入图片描述
3、设置显示和隐藏时的动画效果
我们在官网找到想要的样式
在这里插入图片描述
编写代码,appear为true时表示进入网页时组件第一次渲染就开始显示配置的效果
在这里插入图片描述
4、测试
在这里插入图片描述
很方便对不对,nice

14、反向代理

在解决ajax跨域问题时,后端人员经常会配置CORS解决跨域,但是作为前端,我们也可以通过自己的反向代理的方式解决跨域,这样就不用麻烦后端开发人员。

我们先准备两个接口,这里有使用node-js写的两个服务器。先下载运行起来

链接:https://pan.baidu.com/s/1Tbezmmg7vj_NpqxysYgCjg
提取码:1024

解压之后我们通过node运行
在这里插入图片描述
测试一下接口是否正常返回数据:
在这里插入图片描述
接下来我们写一个组件通过ajax的方式去请求接口,这里我们使用axios发起请求,当然得先安装axios:npm i axios

在这里插入图片描述
会发现,产生了跨域问题,接下来我们用以下两种方式解决跨域

14.1、方式一

官网配置说明:点击直达
在这里插入图片描述
在vue.config.js中加入配置

 module.exports = {
    
	devServer: {
    
   	proxy: 'http://localhost:4000'
  }
}

在这里插入图片描述
重启脚手架项目,这样vue-cli就为你开启了一个8080的代理服务器去代理5000的服务器

重新发起请求
在这里插入图片描述
注意,如果我们8080的服务器上本身就有和5000相同的资源,代理服务器就不会把我们的请求转发给5000
在这里插入图片描述

14.2、方式二

会发现方式一存在两个问题,一是不能配置多个代理,二是不能灵活的控制请求是否转发。
在这里插入图片描述
编写vue.config.js具体规则

module.exports = {
    
	devServer: {
    
      proxy: {
    
      '/api1': {
    // 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {
    '^/api1': ''}
      },
      '/api2': {
    // 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {
    '^/api2': ''}
      }
    }
  }
}
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
   changeOrigin默认值为true
*/

在这里插入图片描述
配置完我们需要重启服务器,我们将请求前缀加上/api1 或/api2,测试。
在这里插入图片描述
说明:
1.优点:可以配置多个代理,且可以灵活控制请求是否走代理
2.缺点:配置略微繁琐,请求资源时必须加前缀。

15、插槽

15.1、插槽的介绍和使用方式

1、作用:让父组件可以向子组件指定的位置插入html结构,也是一种组件间通信的方式,适用于父组件===>子组件。

2、分类:默认插槽、具名插槽、作用域插槽

3、使用方式

  1. 默认插槽:
父组件中:
		<xxx组件>
			<div>html结构1</div>
		</xxx组件>
子组件中:
		<template>
			<div>
				<slot>插槽默认内容...</slot>
			</div>
		</template>
  1. 具名插槽
父组件中:
	<xxx组件>
		<template slot="center">
			<div>html结构1</div>
		</templat>
		<template v-slot:footer>
			<div>html结构2</div>
		</templat>	
	<xxx组件>		
子组件中:
	<template>
		<div>
			<!--定义插槽-->	
			<slot name="center">插槽默认内容...</slot>
			<slot name="footer">插槽默认内容</slot>
		</div>
	</template>
  1. 作用于插槽
    1、理解:数据在组件自身,但数据生成的结构需要组件的使用者来决定,意思就是说,组件的使用者可以拿到组件中提前定义好的数据 然后在使用时根据自己的需求进行渲染。
    2、具体编码
父组件中:
	<xxx组件>
		<!--或者scope换成slot-scope也行-->
		<template scope="scopeData">
		<!--生成的是ul列表>
			<ul>
				<li v-for="g in scopeData.games" :key="g" >{
    {
    g}}</li>
			</ul>
		</template>	
	</xxx组件>

子组件中:
	<template>
		<div>
			<slot :games="games"></slot>
		</div>
	</template>
	<script>
		export default{
    
			name:'Category',
			//数据在组件自身
			data(){
    
				return{
    
					games:['红色警戒','穿越火线','劲舞团'] 
				}
			}
		}
	</script>	

15.2、默认插槽

首先我们准备一Category1组件,在组件中定义一个插槽,然后使用这个组件时动态是插入html结构内容
在这里插入图片描述
测试成功、
在这里插入图片描述

15.3、具名插槽

默认插槽只能定义一个插槽,我们可以使用具名插槽定义多个插槽。我们准备一个Category2组件,在其中声明两个插槽
在这里插入图片描述
测试成功
在这里插入图片描述

15.4、作用域插槽

准备一个组件Category3,并定义插槽携带数据
在这里插入图片描述
测试成功
在这里插入图片描述

16、Vuex

16.1、vuex是什么?

  1. 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,在Vue应用中多个组件共享状态进行集中式管理(读/写),也是一种组件间通信方式,且适用于任意组件中的通信。(说白了就像后端中的redis可以用来多个应用中做数据共享)

  2. Github地址:https://github.com/vuejs/vuex

16.2、什么时候使用Vuex

  1. 多个组件依赖于同一状态
  2. 多个组件的行为需要变更同一状态

16.3、Vuex原理图

在这里插入图片描述
现在看不懂没关系,我们逐个分析…

16.4、搭建Vuex环境

注意:在2022年的2月7日,vue3成为了默认版本,如果我们现在去执行npm i vue ,安装的直接就是vue3了,并且在vue3成为默认版本后。vuex更新到了4版本,所以我们如果执行npm i vuex,安装的是vuex4,而vue3版本只能在vue3版本中使用。
所以简单来说:
vue2中,要用vuex的3版本
vue3中,要用vuex的4版本

1、安装vuex并使用vuex插件

npm i vuex@3

在这里插入图片描述
2、为了让所有的vm和vc都拥有$store,所以我们需要配置store
在src文件夹下创建store文件夹和index.js文件
在这里插入图片描述
测试:
在这里插入图片描述

调整写法
在这里插入图片描述
index.js文件内容

//该文件用于创建VUex中最为核心的store
import Vue from 'vue'

//引入VUex
import Vuex from 'vuex'

Vue.use(Vuex)

//准备actions-用于响应组件中的动作
const actions={
    
}
//准备mutations-用于操作数据(state)
const mutations={
    
}
//准备state-用于存储数据
const state={
    
}
//创建并暴露store
export default new Vuex.Store({
    
    actions,
    mutations,
    state,
})

这回,就没有报错了!!!
测试vm和vc中是否包含$store,我们直接在mounted钩子中打印this
在这里插入图片描述

成功啦,之后$store中那些强大的API我们就都可以在任意vm和vc中使用了。

16.5、求和案例

现在的需求:
在这里插入图片描述

16.5.1、纯Vue版本

在这里插入图片描述

16.5.2、Vuex版本

在这里插入图片描述
测试
在这里插入图片描述

16.6、Store中的getters配置项

1、概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。他就和vue中的计算属性是一样的。
2、在./store/index.js中追加getters配置

......

const getters={
    
	bigSum(state){
    
		return state.sum*10
	}
}
//创建并暴露store
export default new Vuex.Store({
    
	......
	getters
})

3、组件中读取数据:$store.getters.bigSum

4、示范
在这里插入图片描述5、测试
在这里插入图片描述
完美。

16.7、mapState与mapGetters

16.7.1、mapState

1、会发现如过store中的state中有多个属性数据需要读取,就比较繁琐
在这里插入图片描述
2、我们可以通过计算属性来进行简化
在这里插入图片描述

16.7.2、mapGetters

mapGetters和mapState的用法一样,只不过它拿的是store中的getters中的数据
在这里插入图片描述

16.7.3、总结

1.mapState方法:用于帮助我们映射state中的数据为计算属性

computed:{
    
	//借助mapState生产计算属性:sum、address、subject
	...mapState({
    sum:'sum',address:'address',subject:'subject'})

	//借助mapState生成计算属性:sum、address、subject
    ...mapState(['sum','address','subject'])
}

2.mapGetters方法:用于帮助我们映射getters中的数据为计算属性

computed:{
    
	//借助mapGetters生成计算属性:bigSum(对象写法)
	...mapGetters({
    bigSum:'bigSum'}),
	//借助mapGetters生成计算属性:bigsum (数组写法)
	...mapGetters(['bigSum'])
}

16.8、mapActions和mapMutations

16.8.1、mapActions

在这里插入图片描述

16.8.2、mapMutations

在这里插入图片描述

16.8.3、总结
  1. mapActions方法:帮助我们生成与actions对话的方法,即:包含$store.dispath(xxx)的函数
methods:{
    
	//借助mapActions生成与actins的对话的方式(对象写法)
	...mapActions({
    increment:'increment',incrementWait:'incrementWait'})

 	//数组形式的写法
    ...mapActions(['increment','incrementWait'])	

}
  1. mapMutations方法:用于帮助我们生成与mutations对话的方法,即: 包含$store.commit(xxx)的函数
methods:{
    
	//借助mapMutation生成与**mutations**对话的方法(对象形式)
	...mapMutations({
    INCREMENT:"INCREMENT"})
	
	//数组写法
	...mapMutations(['INCREMENT'])

}

16.9、Vuex的模块化编码

会发现,结合上面的技术,我们已经能完成数据的共享以及我们想要的功能。但随之也带来了一些问题,那就是如果业务量很大,模块很多,那么Store中的actions或者mutations以及state就会写得很长,不利于
所以我们可以使用模块化+命名空间将Vuex的模块进行分类,
就是说
订单模块调用订单模块的store
支付模块调用支付模块的store

16.9.1、模块化+命名空间

1.目的:让代码更好维护,让多种数据分类更加明确
2.修改store.js

const module1={
    
	namespaced:true,
	actions:{
     ... },
	mutations:{
     ... },
	state:{
     ... },
	getters:{
     ... }
}

const module2={
    
	namespaced:true,
	actions:{
     ... },
	mutations:{
     ... },
	state:{
     ... },
	getters:{
     ... }
}

const store = new Vuex.Store({
    
	modules:{
    
		//module:module
		// es6 简写
		module1,
		module2
	}
})

3、开启命名空间后,组件中读取state数据:

//方式一:直接读取
this.$store.state.xxxxx模块.sum
//方式二:借助mapState读取
...mapState('xxxxx模块',['sum','subject'])

4、开启命名空间后,组件中读取getters数据:

//方式一:自己直接读取  不能直接写 getters.xxx模块.BigSum 
this.$store.getters['xxx模块/bigSum']
//方式二:借助mapGetters读取:
...mapGetters('xxx模块',['bigSum'])

5、开启命名空间后,组件中调用dispath

//方式一:自己直接dispath
this.$store.dispath('xxx模块/increment',this.xxx)
//方式二:借助mapActions 或者对象写法('xxx模块',{increment:'increment'})
...mapActions('xxx模块',['increment'])

6、开启命名空间后,组件中调用commit

//方式一:自己直接commit
this.$store.commit('xxx模块/INCREMENT',this.xxx)
//方式二:通过mapMutations
...mapMutations('xxx模块',['INCREMENT'])
16.9.2、测试

通过$store的方式,我们准备一个Count组件和Count模块
在这里插入图片描述
测试完美!!!
在这里插入图片描述

通过map映射的方式,准备另外一个Studentr组件和studentOptions模块
在这里插入图片描述
测试完美!!!
在这里插入图片描述
补充、
当然也可以将各个模块抽取出来,然后在index文件中导入,这样模块的划分就更加清晰
在这里插入图片描述

17、路由

17.1、路由的简介

说白了,路由就是一组组Key–Value的对应关系。

(1)、理解:一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理

(2)、前端路由:key是路径,value是组件

17.2、路由的基本使用

17.2.1、安装vue-router

注意,在2022年2月7日以后,vue-router的默认版本为4版本,并且:Vue-router3才能再Vue2中使用

所以我们得安装Vue-router3

npm i vue-router@3
17.2.1、使用vue-router

1、首先创建一个叫router的文件夹,并创建index.js,我们创建并暴露一个路由器VueRouter
在这里插入图片描述
2、在main.js中引入VueRouter并use,然后配置router

在这里插入图片描述
3、准备两个组件,随便写点内容
在这里插入图片描述
4、在路由器中配置路由数组routes 它里面包含很多路由。
在这里插入图片描述

5、然后我们在App.vue中可以开始使用路由了
在这里插入图片描述
6、测试
在这里插入图片描述

17.3、几个注意点

1、用单独的文件夹保存路由跳转的组件
在这里插入图片描述
2、通过切换后,"隐藏"了的路由组件默认是被自动销毁掉的,需要的时候会自动从新挂载。

3、每个组件都有自己的$route属性,里面存储着关于自己的路由信息。

4、整个应用只有一个路由器router,可以通过组件的$router属性获取到。
在这里插入图片描述

17.4、嵌套路由

就是路由组件里继续路由跳转到路由组件
1、首先,我们添加一些样式,并说明一下需求
在这里插入图片描述
我们点击“学生管理”,然后会出现旁边父路由的信息,然后点击父路由组件中的 “学生信息” 或者 “学生地址”

2、我们再准备两个组件News和Address,随便加点内容,这两个是子组件中要显示的内容
在这里插入图片描述
3、我们编写路由规则
在这里插入图片描述
4、测试,完美!!!

在这里插入图片描述
总结:
多级路由:
1.配置路由规则,使用children配置项:

routes:[
	{
    
		path:'/class',
		component:Class
	},
	{
    
		path:'/student',
		component:Student,
		children:[
			{
    
				path:'news',
				component:News
			},
			{
    
				path:'address', //此处千万不要写 /address 
				component:Message
			}


		]
	}
]

17.5、路由的query参数(路由跳转时传递参数)

1.、现在新的需求,要求点击某条消息,然后显示消息的id和消息的详情信息
在这里插入图片描述
2、可以看到 学生消息路由里面还包含路由,三级路由
并且点击的时候还还需要将参数动态的传递给第三级的路由组件。

首先我们创建一个Details组件并配置好路由规则
在这里插入图片描述
3、路由跳转时携带参数
在这里插入图片描述
4、测试成功啦!!!
在这里插入图片描述

17.6、命名路由(简化跳转)

我们会发现,从上述的例子中可以看到,如果路由嵌套过多,那么跳转的时候 路径就会写得很长,那么我们可以给该路由定义一个名字来简化跳转
在这里插入图片描述
在这里插入图片描述

17.7、路由的params参数

打印this 我们可以看到不光query可以携带参数,我们也可以通过params携带参数
在这里插入图片描述
在路由的path中添加占位符,通过params携带参数,然后路由组件中就可以从params中携带拿到参数
在这里插入图片描述

测试 接收参数
在这里插入图片描述

17.8、路由的props配置

在这里插入图片描述
路由的props配置的三种写法

{
    
 name:'ces',
 path:'detail/:id/:detail'
 component:Detail,
 //第一种写法:props值为对象,该对象所有的的key-value最终通过通过props传给Detail组件
 // props:{a:900}
 
//第二种写法:props值为布尔值,布尔值为true,则把路由收到所有params参数通过props传递给Detail
//props:true

//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传递给Detail组件
   props($route){
    
	return {
    
	 	id:$route.query.id,
	 	detail:$route.query.detail
	}
 }
}

第一种写法只能传递固定的数据,不灵活,所以就不演示了。
第二种写法:注意这种写法只能传递params中的key-value…
在这里插入图片描述
第三种写法
在这里插入图片描述

17.9、router-link的replace属性

1、作用:控制路由跳转时操作浏览器历史记录的模式
2、浏览器的历史记录有两种写入方式:分别是pushreplacepush是追加历史记录,replace是替换当前记录。路由跳转时候默认为push
3.如何开启replace模式:<router-link replace .......>News</router-link>

首先,我们点击
在这里插入图片描述
会发现 会从消息二回到消息一
在这里插入图片描述

测试 我们在Student的组件和他的子路由 News的路由跳转中加入replace属性
在这里插入图片描述
再按照刚刚的点击顺序
在这里插入图片描述
说白了 replace 加入之后 该路由 跳转的记录不会在浏览器留下痕迹

17.10、编程式路由导航 (通过$router跳转)

通过上面的例子,我们不仅可以通过<router-link>标签进行跳转,我们还可以通过$router进行跳转,我们之前就说过,每个组件都有自己的$route而所有的组件共用一个$router

我们看一下现在的需求:
在这里插入图片描述
我们通过点击按钮然后调用$router.push跳转到指定组件
在这里插入图片描述
通过$replace进行跳转
在这里插入图片描述
测试成功
在这里插入图片描述
接下来编写前进和后退的代码以及go的代码
在这里插入图片描述
就和点击浏览器前进和后退的箭头一样。之后我们就可以通过$router的这些API实现各种组件 类似于页面条页面的路由跳转啦!!!

17.11、缓存路由组件

1.作用:让不展示的路由组件保持挂载,不被销毁。
2.具体编码:

//指定一个组件不被销毁
<keep-alive include="具体不被销毁的组件名">
	<router-view></router-view>
</keep-alive>

//指定多个缓存不被销毁
<keep-alive :include="['xxx','xxx']">
	<router-view></router-view>
</keep-alive>

示范:
我们希望从新回到该路由组件的时候,输入的内容还在
在这里插入图片描述
所以我们可以使用缓存路由组件keep-alive,我们在显示的视图使用router-view时顺便使用keep-alive即可在这里插入图片描述测试
在这里插入图片描述

17.12、两个新的生命周期钩子

  1. 作用:路由组件所独有的两个钩子
  2. 具体名字:
    1. activated路由组件被激活时触发
    2. deactivated路由组件失活时触发

示范:
我们在Address组件中添加上这两个钩子函数
在这里插入图片描述

17.13、 路由守卫(权限控制)

17.13.1、全局前置守卫

需求:
在这里插入图片描述
所以 我们可以在可以使用路由的前置守卫控制某个路由是否放行

1、首先在LocalStorage中存入key
在这里插入图片描述
2、在路由器中配置前置守卫
在这里插入图片描述
3、当role为vip时
在这里插入图片描述
4、我们改一下role的值、测试成功
在这里插入图片描述
补充
从上面的例子中我们可以看到,如果每次都拿到path或者name去判断的话太长了,也不方便,。我们可以通过在meta属性中加上数据,表面这个路由是否需要被判断。
在这里插入图片描述

17.13.2、全局后置守卫

很少使用,一般用来修改网页的title
在这里插入图片描述

17.13.3、独享守卫

上面的都是对所有路由都有效的,独享守卫就是对某一个路由有效,
并且 独享守卫只有前置,没有后置。
在这里插入图片描述

17.13.4、组件内守卫

说白了就是写在组件内的路由守卫,我们直接写在Class组件中。
在这里插入图片描述
测试
在这里插入图片描述

17.14、路由器的两种工作模式

  1. 对于一个url来说,什么是hash值?—#以及后面的内容就是hash值,
  2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器。
  3. hash模式:
    1. 地址中永远带着#号,不美观。
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
    3. 兼容性较好。
  4. history模式:
    1. 地址干净,美观。
    2. 兼容性和hash模式相比略差。
    3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。

设置:

默认是hash,如果想换成history则可设置
在这里插入图片描述
hash模式下的地址栏
在这里插入图片描述
history模式下的地址栏
在这里插入图片描述
记住:history模式部署上线前记得对服务器进行相关配置解决history刷新地址栏报404的问题。

18、Element-UI 组件库

18.1、Element-UI基本使用

官网:https://element.eleme.cn/#/zh-CN/component/installation

根据官网进行安装

npm i element-ui

安装完之后在main.js 中添加以下代码,则可在所有的组件中使用element ui了

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

我们在App.vue中直接使用一下Element-UI提供的组件库
在这里插入图片描述

18.2、Element-UI按需引入

在这里插入图片描述
1、安装babel插件

npm install babel-plugin-component -D  

2、配置.babelrc文件,注意:vue-cli中已经不存在.babelrc文件了,babel的配置在 babel.config.js文件中

module.exports = {
    
  presets: [
    '@vue/cli-plugin-babel/preset',
    ["@babel/preset-env", {
     "modules": false }]
  ],
  plugins: [
    [
      "component",
      {
    
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

注意,如果按照官网的话可能会出现,这个错误(因为官网的文档可能不是最新的)
在这里插入图片描述
我们改个地方就可以了。
在这里插入图片描述
3、我们根据官网,按需引入即可
比如我只使用button和row组件

import {
     Button, Row } from 'element-ui';
Vue.component(Button.name, Button);
Vue.component(Row .name, Row);

在这里插入图片描述
测试
在这里插入图片描述

19、后记

生活朗朗,万物可爱,人间值得,未来可期。恭喜你,完结撒花!!!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45647685/article/details/123557666

智能推荐

C#连接OPC C#上位机链接PLC程序源码 1.该程序是通讯方式是CSharp通过OPC方式连接PLC_c#opc通信-程序员宅基地

文章浏览阅读565次。本文主要介绍如何使用C#通过OPC方式连接PLC,并提供了相应的程序和学习资料,以便读者学习和使用。OPC服务器是一种软件,可以将PLC的数据转换为标准的OPC格式,允许其他软件通过标准接口读取或控制PLC的数据。此外,本文还提供了一些学习资料,包括OPC和PLC的基础知识,C#编程语言的教程和实例代码。这些资料可以帮助读者更好地理解和应用本文介绍的程序。1.该程序是通讯方式是CSharp通过OPC方式连接PLC,用这种方式连PLC不用考虑什么种类PLC,只要OPC服务器里有的PLC都可以连。_c#opc通信

Hyper-V内的虚拟机复制粘贴_win10 hyper-v ubuntu18.04 文件拷贝-程序员宅基地

文章浏览阅读1.6w次,点赞3次,收藏10次。实践环境物理机:Windows10教育版,操作系统版本 17763.914虚拟机:Ubuntu18.04.3桌面版在Hyper-V中的刚安装好Ubuntu虚拟机之后,会发现鼠标滑动很不顺畅,也不能向虚拟机中拖拽文件或者复制内容。在VMware中,可以通过安装VMware tools来使物理机和虚拟机之间达到更好的交互。在Hyper-V中,也有这样的工具。这款工具可以完成更好的鼠标交互,我的..._win10 hyper-v ubuntu18.04 文件拷贝

java静态变量初始化多线程,持续更新中_类初始化一个静态属性 为线程池-程序员宅基地

文章浏览阅读156次。前言互联网时代,瞬息万变。一个小小的走错,就有可能落后于别人。我们没办法去预测任何行业、任何职业未来十年会怎么样,因为未来谁都不能确定。只能说只要有互联网存在,程序员依然是个高薪热门行业。只要跟随着时代的脚步,学习新的知识。程序员是不可能会消失的,或者说不可能会没钱赚的。我们经常可以听到很多人说,程序员是一个吃青春饭的行当。因为大多数人认为这是一个需要高强度脑力劳动的工种,而30岁、40岁,甚至50岁的程序员身体机能逐渐弱化,家庭琐事缠身,已经不能再进行这样高强度的工作了。那么,这样的说法是对的么?_类初始化一个静态属性 为线程池

idea 配置maven,其实不用单独下载Maven的。以及设置新项目配置,省略每次创建新项目都要配置一次Maven_安装idea后是不是不需要安装maven了?-程序员宅基地

文章浏览阅读1w次,点赞13次,收藏43次。说来也是惭愧,一直以来,在装环境的时候都会从官网下载Maven。然后再在idea里配置Maven。以为从官网下载的Maven是必须的步骤,直到今天才得知,idea有捆绑的 Maven 我们只需要搞一个配置文件就行了无需再官网下载Maven包以后再在新电脑装环境的时候,只需要下载idea ,网上找一个Maven的配置文件 放到 默认的 包下面就可以了!也省得每次创建项目都要重新配一次Maven了。如果不想每次新建项目都要重新配置Maven,一种方法就是使用默认的配置,另一种方法就是配置 .._安装idea后是不是不需要安装maven了?

奶爸奶妈必看给宝宝摄影大全-程序员宅基地

文章浏览阅读45次。家是我们一生中最重要的地方,小时候,我们在这里哭、在这里笑、在这里学习走路,在这里有我们最真实的时光,用相机把它记下吧。  很多家庭在拍摄孩子时有一个看法,认为儿童摄影团购必须是在风景秀丽的户外,即便是室内那也是像大酒店一样...

构建Docker镜像指南,含实战案例_rocker/r-base镜像-程序员宅基地

文章浏览阅读429次。Dockerfile介绍Dockerfile是构建镜像的指令文件,由一组指令组成,文件中每条指令对应linux中一条命令,在执行构建Docker镜像时,将读取Dockerfile中的指令,根据指令来操作生成指定Docker镜像。Dockerfile结构:主要由基础镜像信息、维护者信息、镜像操作指令、容器启动时执行指令。每行支持一条指令,每条指令可以携带多个参数。注释可以使用#开头。指令说明FROM 镜像 : 指定新的镜像所基于的镜像MAINTAINER 名字 : 说明新镜像的维护(制作)人,留下_rocker/r-base镜像

随便推点

毕设基于微信小程序的小区管理系统的设计ssm毕业设计_ssm基于微信小程序的公寓生活管理系统-程序员宅基地

文章浏览阅读223次。该系统将提供便捷的信息发布、物业报修、社区互动等功能,为小区居民提供更加便利、高效的服务。引言: 随着城市化进程的加速,小区管理成为一个日益重要的任务。因此,设计一个基于微信小程序的小区管理系统成为了一项具有挑战性和重要性的毕设课题。本文将介绍该小区管理系统的设计思路和功能,以期为小区提供更便捷、高效的管理手段。四、总结与展望: 通过本次毕设项目,我们实现了一个基于微信小程序的小区管理系统,为小区居民提供了更加便捷、高效的服务。通过该系统的设计与实现,能够提高小区管理水平,提供更好的居住环境和服务。_ssm基于微信小程序的公寓生活管理系统

如何正确的使用Ubuntu以及安装常用的渗透工具集.-程序员宅基地

文章浏览阅读635次。文章来源i春秋入坑Ubuntu半年多了记得一开始学的时候基本一星期重装三四次=-= 尴尬了 觉得自己差不多可以的时候 就吧Windows10干掉了 c盘装Ubuntu 专心学习. 这里主要来说一下使用Ubuntu的正确姿势Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的开源GNU/Linux操作系统,Ubuntu 是基于DebianGNU/Linux,支..._ubuntu安装攻击工具包

JNI参数传递引用_jni引用byte[]-程序员宅基地

文章浏览阅读335次。需求:C++中将BYTE型数组传递给Java中,考虑到内存释放问题,未采用通过返回值进行数据传递。public class demoClass{public native boolean getData(byte[] tempData);}JNIEXPORT jboolean JNICALL Java_com_core_getData(JNIEnv *env, jobject thisObj, jbyteArray tempData){ //resultsize为s..._jni引用byte[]

三维重建工具——pclpy教程之点云分割_pclpy.pcl.pointcloud.pointxyzi转为numpy-程序员宅基地

文章浏览阅读2.1k次,点赞5次,收藏30次。本教程代码开源:GitHub 欢迎star文章目录一、平面模型分割1. 代码2. 说明3. 运行二、圆柱模型分割1. 代码2. 说明3. 运行三、欧几里得聚类提取1. 代码2. 说明3. 运行四、区域生长分割1. 代码2. 说明3. 运行五、基于最小切割的分割1. 代码2. 说明3. 运行六、使用 ProgressiveMorphologicalFilter 分割地面1. 代码2. 说明3. 运行一、平面模型分割在本教程中,我们将学习如何对一组点进行简单的平面分割,即找到支持平面模型的点云中的所有._pclpy.pcl.pointcloud.pointxyzi转为numpy

以NFS启动方式构建arm-linux仿真运行环境-程序员宅基地

文章浏览阅读141次。一 其实在 skyeye 上移植 arm-linux 并非难事,网上也有不少资料, 只是大都遗漏细节, 以致细微之处卡壳,所以本文力求详实清析, 希望能对大家有点用处。本文旨在将 arm-linux 在 skyeye 上搭建起来,并在 arm-linux 上能成功 mount NFS 为目标, 最终我们能在 arm-linux 里运行我们自己的应用程序. 二 安装 Sky..._nfs启动 arm

攻防世界 Pwn 进阶 第二页_pwn snprintf-程序员宅基地

文章浏览阅读598次,点赞2次,收藏5次。00为了形成一个体系,想将前面学过的一些东西都拉来放在一起总结总结,方便学习,方便记忆。攻防世界 Pwn 新手攻防世界 Pwn 进阶 第一页01 4-ReeHY-main-100超详细的wp1超详细的wp203 format2栈迁移的两种作用之一:栈溢出太小,进行栈迁移从而能够写入更多shellcode,进行更多操作。栈迁移一篇搞定有个陌生的函数。C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 _pwn snprintf

推荐文章

热门文章

相关标签