Vue组件和Vue脚手架

文章目录

😹 作者: gh-xiaohe
😻 gh-xiaohe的博客
😽 觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!!

🚏 一、Vue组件化编程 components

🚬 传统方式编写应用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MXesNWXD-1659019607716)(VUE入门.assets/image-20220728210813070.png)]

在这里插入图片描述

🚬 组件式编写应用

在这里插入图片描述

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

🚬 组件的概念

    实现应用中局部功能代码资源集合

🚬 组件的作用

    复用编码,简化项目编码,提高运行效率

🚀 1、非单文件组件

  • 一个文件中包含n个组件
  • 缺点 : 样式不能跟着组件走

🚬 组件的定义

总结:

		<!-- 
			Vue中使用组件的三大步骤:
					一、定义组件(创建组件)
					二、注册组件
					三、使用组件(写组件标签)

			一、如何定义一个组件?
						使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
						区别如下:
								1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
								2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
						备注:使用template可以配置组件结构。

			二、如何注册组件?
							1.局部注册:靠new Vue的时候传入components选项
							2.全局注册:靠Vue.component('组件名',组件)

			三、编写组件标签:
							<school></school>
		-->

① 基础

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>一个重要的内置关系</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>

		<div id="root">
			<h2>学校名称:{{schoolName}}</h2>
			<h2>学校地址:{{address}}</h2>
			<hr>
			<h2>学生姓名:{{studentName}}</h2>
			<h2>学生年龄:{{age}}</h2>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el: "#root",
			data: {
				schoolName: '清华大学',
				address: '北京',
				studentName: '张三',
				age: 18
			}
		})
		

	</script>
</html>

在这里插入图片描述

② 创建school组件 局部组件(常用)

步骤:

  • 创建组件
  • 注册组件
  • 编辑组件标签
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>一个重要的内置关系</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
   </head>
    <body>

        <div id="root">
			<hr>
			<!-- 第三步:编写组件标签 -->
			<school></school>
			<hr>
			<!-- 第三步:编写组件标签 -->
			<student></student>
           <student></student>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

       //第一步:创建school组件
        const school = Vue.extend({ // 传入配置对象
            template:`
               <div>
                    <h2>学校名称:{{schoolName}}</h2>
                    <h2>学校地址:{{address}}</h2>
                </div>
           `,
            // el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            data(){ // data 函数式(普通函数),不能书写成对象时,使用对象式时,有引用关系
                return {
                    schoolName:'Tom',
                    address:'北京昌平'
                }
            },
       })

       //第一步:创建student组件
		const student = Vue.extend({
			template:`
				<div>
					<h2>学生姓名:{{studentName}}</h2>
					<h2>学生年龄:{{age}}</h2>
				</div>
			`,
			data(){
				return {
					studentName:'张三',
					age:18
				}
			}
		})

        new Vue({
         el: "#root",
         //第二步:注册组件(局部注册)
		  components:{
				school, // 组件名 或者 组件名 school:创建组件时的名字
				student
			}
        })


   </script>
</html>

在这里插入图片描述

③ 交互点我提示学校名

        const school = Vue.extend({ // 传入配置对象
            template:`
               <div>
                    <h2>学校名称:{{schoolName}}</h2>
                    <h2>学校地址:{{address}}</h2>
                    <button @click="showName">点我提示学校名</button> 

                </div>
           `,
            data(){ 
                return {
                    schoolName:'Tom',
                    address:'北京昌平'
                }
            },
            methods: {
                showName(){
                	alert(this.schoolName)
                }
           },
       })

在这里插入图片描述

④ 全局注册组件

  • Vue.component(‘hello’,hello) // 组件的名字 组件的位置
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>基本使用</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<!-- 第三步:编写组件标签 -->
			<school></school>
			<!-- 第三步:编写组件标签 -->
			<student></student>
		</div>

		<div id="root2">
			<!-- 第三步:编写组件标签 -->
			<hello></hello>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false
       
		//第一步:创建hello组件
		const hello = Vue.extend({
			template:`
				<div>	
					<h2>你好啊!{{name}}</h2>
				</div>
			`,
			data(){
				return {
					name:'Tom'
				}
			}
		})
		
		//第二步:全局注册组件
		Vue.component('hello',hello) // 组件的名字 组件的位置

		//创建vm
		new Vue({
			el:'#root',
			data:{
				msg:'你好啊!'
			},
			//第二步:注册组件(局部注册)
			components:{
				school,
				student
			}
		})

		new Vue({
			el:'#root2',
		})
	</script>
</html>

在这里插入图片描述

🚬 组件的注意事项

总结:

		<!-- 
			几个注意点:
					1.关于组件名:
								一个单词组成:
											第一种写法(首字母小写):school
											第二种写法(首字母大写):School
								多个单词组成:
											第一种写法(kebab-case命名):my-school 'my-school'
											第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
								备注:
										(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
										(2).可以使用name配置项指定组件在开发者工具中呈现的名字。

					2.关于组件标签:
								第一种写法:<school></school>
								第二种写法:<school/>
								备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。

					3.一个简写方式:
								const school = Vue.extend(options) 可简写为:const school = options
		-->

简写 创建组件 (推荐)

  • 单文件组件时,常用
		const hello = {
			template:`
				<div>	
					<h2>你好啊!{{name}}</h2>
				</div>
			`,
			data(){
				return {
					name:'Tom'
				}
			}
		}

🚬 组件的嵌套

school 是父 student 是子

  • student 组件应该写在 school组件的上面
  • student 组件中定义 school组件
  • school 的使用 定义哪个组件 在 template 中 使用

① 组件的嵌套

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>一个重要的内置关系</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
   </head>
    <body>

        <div id="root">
			<school></school>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

       //创建 student 组件
		const student = Vue.extend({
			template:`
				<div>
					<h2>学生姓名:{{studentName}}</h2>
					<h2>学生年龄:{{age}}</h2>
				</div>
			`,
			data(){
				return {
					studentName:'张三',
					age:18
				}
			},
		})

       //创建 school组件
        const school = Vue.extend({ // 传入配置对象
            template:`
               <div>
                    <h2>学校名称:{{schoolName}}</h2>
                    <h2>学校地址:{{address}}</h2>
                    <student></student> 
                </div>
           `,
            data(){ 
                return {
                    schoolName:'Tom学校',
                    address:'北京昌平'
                }
            },
            components:{
				student,
			}
       })

        new Vue({
         el: "#root",
		  components:{
				school,
			}
        })

   </script>
</html>

在这里插入图片描述

② 定义个 hello 组件 要求:和school是平级的

        <div id="root">
			<school></school>
           <hello></hello>
        </div>

		//定义hello组件
		const hello = Vue.extend({
			template:`<h1>{{msg}}</h1>`,
			data(){
				return {
					msg:'欢迎来和Tom一起学习!'
				}
			}
		})

		new Vue({
         el: "#root",
		  components:{
				school,
               hello,
			}
        })

在这里插入图片描述

开发中常用技巧 定义一个:app组件

作用:用于管理应用里面所有的组件

		<div id="root">
			<app></app>
		</div>		

		//定义app组件
		const app = Vue.extend({
			template:`
				<div>	
					<hello></hello>
					<school></school>
				</div>
			`,
			components:{
				school, // 引入 school 组件, 不用在引用student 引用父组件即可
				hello
			}
		})

		//创建vm
		new Vue({
			el:'#root',
			//注册组件(局部)
			components:{app}
		})

如果 容器中什么都不想写,怎么办

  • 容器里面干干净净
		//创建vm
		new Vue({
			template:'<app></app>',
			el:'#root',
			//注册组件(局部)
			components:{app}
		})

在这里插入图片描述

🚬 VueComponent的构造函数

总结:

		<!-- 
			关于VueComponent:
						1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

						2.我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,
							即Vue帮我们执行的:new VueComponent(options)。

						3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

						4.关于this指向:
								(1).组件配置中:
											data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
								(2).new Vue(options)配置中:
											data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

						5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
							Vue的实例对象,以后简称vm。
		-->
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>VueComponent</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>

		<div id="root">
			<school></school>
			<hello></hello>
			school	
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false
		
		//定义school组件
		const school = Vue.extend({
			name:'school',
			template:`
				<div>
					<h2>学校名称:{{name}}</h2>	
					<h2>学校地址:{{address}}</h2>	
					<button @click="showName">点我提示学校名</button>
				</div>
			`,
			data(){
				return {
					name:'Tom',
					address:'北京'
				}
			},
			methods: {
				showName(){
					console.log('showName',this)
				}
			},
		})

		const test = Vue.extend({
			template:`<span>atguigu</span>`
		})

		//定义hello组件
		const hello = Vue.extend({
			template:`
				<div>
					<h2>{{msg}}</h2>
					<test></test>	
				</div>
			`,
			data(){
				return {
					msg:'你好啊!'
				}
			},
			components:{test}
		})


		console.log('@',school) // Vue 的 VueComponent的构造函数
		console.log('#',hello)  // 每次调用都会 创建一个新的 构造函数对象
      	 					    // 每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

		//创建vm
		const vm = new Vue({
			el:'#root',
			components:{school,hello}
		})
	</script>
</html>

在这里插入图片描述

体现vm 管理 一个一个的vc
在这里插入图片描述

🚬 Vue实例与组件实例

  • vc有的功能vm都有,vm有一个功能vc就没有,vm可以通过el决定来为哪个容器服务,vc不可以
    在这里插入图片描述

🚬 重要的内置关系

总结:

		<!-- 
				1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
				2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
		-->

① 原型相关知识

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>一个重要的内置关系</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>

		<div id="root">

		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		
		//定义一个构造函数
	     function Demo(){
			this.a = 1
			this.b = 2
		}
		//创建一个Demo的实例对象
		const d = new Demo()

		console.log(Demo.prototype) // 函数身上的 显示原型属性 

		console.log(d.__proto__) // 实例身上的 隐式原型属性  统统都指向的了一个对象 原型对象

		console.log(Demo.prototype === d.__proto__)

		//程序员通过显示原型属性操作原型对象,追加一个x属性,值为99
		Demo.prototype.x = 99

       console.log('@',d.__proto__.x) // 在顺着这条线去找 或者 console.log('@',d.x) 
		console.log('@',d) 

	</script>
</html>

在这里插入图片描述

② 内置关系

  • .prototype.proto === Vue.prototype
  • 在这里插入图片描述
  • 目的:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>一个重要的内置关系</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>

		<div id="root">
			<school></school>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		Vue.prototype.x = 99

		//定义school组件    本质 是VueComponent
		const school = Vue.extend({
			name:'school',
			template:`
				<div>
					<h2>学校名称:{{name}}</h2>	
					<h2>学校地址:{{address}}</h2>	
					<button @click="showX">点我输出x</button>
				</div>
			`,
			data(){
				return {
					name:'Tom',
					address:'北京'
				}
			},
			methods: {
				showX(){
					console.log(this)
					console.log(this.x)
				}
			},
		})

		//创建一个vm
		const vm = new Vue({
			el:'#root',
			data:{
				msg:'你好'
			},
			components:{school}
		})
		
		// VueComponent 需要调用 extend 此时换成 school 
		// console.log(VueComponent.prototype.__proto__ === Vue.prototype)
		console.log(school.prototype.__proto__ === Vue.prototype)  // true
	</script>
</html>

在这里插入图片描述

🚄 2、单文件组件

  • 一个文件中包含1个组件
  • 单文件组件后缀都是==.vue==结尾

① Vue文件的基本结构

<template>
	 // 组件的结构 
</template>

<script>
	// 组件交互相关的代码(数据、方法等等)
</script>

<style>
	// 组件的样式
</style>

组件的定义 基本使用(简单使用)

school 组件

<template>
	<div class="demo">
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
		<button @click="showName">点我提示学校名</button>	
	</div>
</template>

<script>
	 export default { // 默认暴露
		name:'School', // 组件的名字
		data(){
			return {
				name:'Tom', // 数据
				address:'北京昌平'
			}
		},
		methods: {
			showName(){
				alert(this.name)
			}
		},
	}
</script>

<style>
	.demo{
		background-color: orange;
	}
</style>

student 组件

<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生年龄:{{age}}</h2>
	</div>
</template>

<script>
	 export default {
		name:'Student',
		data(){
			return {
				name:'张三',
				age:18
			}
		}
	}
</script>

App组件

<template>
	// ③ 使用组件
	<div>
		<School></School>
		<Student></Student>
	</div>
</template>

<script>
	// ① 引入组件
	import School from './School.vue'
	import Student from './Student.vue'

	export default {
		name:'App', // 汇总所有的组件
       // ② 注册组件
		components:{
			School,
			Student
		}
	}
</script>

创建vm:main.js

// 引入 App 组件 .vue 可以省略
import App from './App.vue'

new Vue({
	el:'#root',
	// template:`<App></App>`, 和 ④ 书写一个即可
	components:{App}, // 注册组件 App
})

④ 容器 index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>练习一下单文件组件的语法</title>
	</head>
	<body>
		<!-- 准备一个容器 -->
		<div id="root">
       	<App></App>
       </div>
		<!-- Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
       <!-- 先让模板出来在 引入main.js 入口文件-->
		<script type="text/javascript" src="./main.js"></script>
	</body>
</html>

逻辑:

在这里插入图片描述

🚏 二、Vue脚手架

  • 官网:https://cli.vuejs.org/zh/

🚀 1、创建Vue脚手架

  • 第一步(仅第一次执行):全局安装@vue/cli。
    npm install -g @vue/cli
  • 第二步:切换到你要创建项目的目录>,然后使用命令创建项目
    vue create xxxx
  • 第三步:启动项目
    npm run serve
  • 备注:
    • 如出现下载缓慢请配置 npm 淘宝镜像:npm config set registry https://registry.npm.taobao.org
    • Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置,
      请执行:vue inspect > output.js

🚄 2、使用Vue脚手架创建项目步骤–自定义

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行

  • cd 02myvue1
  • npm run serve

在这里插入图片描述

🚒 3、使用Vue脚手架创建项目–2.0/3.0默认

在这里插入图片描述
在这里插入图片描述
运行

  • cd vue-test1
  • npm run serve

在这里插入图片描述

🚤 4、分析Vue脚手架结构

在这里插入图片描述

在这里插入图片描述

index.html 结构

<!DOCTYPE html>
<html lang="">
 <head>
   <meta charset="utf-8">
		<!-- 针对IE浏览器的一个特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 -->
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
		<!-- 开启移动端的理想视口 -->
   <meta name="viewport" content="width=device-width,initial-scale=1.0">
		<!-- 配置页签图标 -->
   <link rel="icon" href="<%= BASE_URL %>favicon.ico">
		<!-- 引入第三方样式 -->
		<link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
		<!-- 配置网页标题 -->
   <title>硅谷系统</title>
 </head>
 <body>
		<!-- 当浏览器不支持js时noscript中的元素就会被渲染 -->
   <noscript>
     <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
   </noscript>
		<!-- 容器 -->
   <div id="app"></div>
   <!-- built files will be auto injected -->
 </body>
</html>

🚗 5、render函数

总结:

<--
	关于不同版本的Vue:
	
		1.vue.js与vue.runtime.xxx.js的区别:
				(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。
				(2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

		2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用
			render函数接收到的createElement函数去指定具体内容。
-->

① mian.js 不认识书写成---->自己认为的写法

//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false


//创建Vue实例对象---vm
new Vue({
	el:'#app',
	template:`<App></App>`,
	components:{App},
})

在这里插入图片描述

② 精简代码,验证信息

//引入Vue
import Vue from 'vue'

Vue.config.productionTip = false

new Vue({
	el:'#app',
	template:`<h1>你好啊</h1>`,
})

在这里插入图片描述

在这里插入图片描述

验证

在这里插入图片描述

解决办法2—> 引入完整版本的Vue

//引入Vue
import Vue from 'vue/dist/vue'

Vue.config.productionTip = false

new Vue({
	el:'#app',
	template:`<h1>你好啊</h1>`,
})

在这里插入图片描述

解决办法1—> 使用render(渲染)函数

  • render需要返回值
  • 可以接收参数
new Vue({
	el:'#app',
	render(createElement) { // createElement 创建元素
		// 查看createElement的类型 看是函数还是对象
       // createElement 创建具体的元素,编写具体的内容
		console.log(typeof createElement) // function 是函数
		return null
	}
})

推导过程

// ①
new Vue({
	el:'#app',
	render(createElement) { 
		return createElement('h1','你好啊')
	}
})
// ② 没有使用到this可以写成箭头函数
new Vue({
	el:'#app',
	render:(createElement)=> { 
		return createElement('h1','你好啊')
	}
})
// ③ 箭头函数左面含有一个参数 可以省略小括号
new Vue({
	el:'#app',
	render:createElement=> { 
		return createElement('h1','你好啊')
	}
})
// ④ 箭头函数只有一句函数体,并且还return
new Vue({
	el:'#app',
	render:createElement=> createElement('h1','你好啊')
})
// ⑤ createElement 使用字母替代 render:q=> q('h1','你好啊')
new Vue({
	el:'#app',
	render:h=> h('h1','你好啊')
})

// 页面上成功返回

和创建的基础代码 还有一点区别:参数

  • 原因:h1是HTML中的内置元素,里面需要写具体的内容,需要传递第二个参数
  • 如果使用的是组件 就不用内容
// 两个参数
new Vue({
	el:'#app',
	render:h=> h('h1','你好啊') 
})
// 一个参数
import App from './App.vue'

new Vue({
	el:'#app',
   // render函数完成了这个功能:将App组件放入容器中
	render: h => h(App) // 不加入引号 读取变量
})
  • 如果一直使用完整版本的Vue开发时不会有任何问题,webpack打包,发布后,已经变成浏览器认识的纯粹js文件template模板解析器就没有什么作用了

🚲 6、修改默认配置

总结:

## vue.config.js配置文件

1. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

🚬 查看Vue的配置文件

  • vue把核心的配置文件给隐藏了,怕不小心,修改错误,项目跑不起来程序,查看核心配置文件命令vue inspect > output.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JoFPw6st-1659274698960)(VUE入门.assets/image-20220731210811627.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-86MVRmCC-1659274698960)(VUE入门.assets/image-20220731211501331.png)]

🚬 脚手架默认的配置哪些文件不可以修改

在这里插入图片描述

🚬 修改Vue的默认配置

  • 官网左侧栏中的都可以进行修改:https://cli.vuejs.org/zh/config/
  • 写个vue.config.js 文件 和 package.json同级,在vue.config.js中书写需要修改的配置,程序读取时,会把vue.config.js中程序员书写的相关内容,与vue的核心配置文件进行整合,最核心的配置碰不到,之后需要重新的启动npm run serve
module.exports = {
  pages: {
    index: {
      //入口
      entry: 'src/main.js',
    },
  },
  lintOnSave:false, //关闭语法检查
}

🚀 7、ref属性

总结:

在这里插入图片描述

原生

	<div>
		<h1 v-text="msg" id="title"></h1>
		<button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
	</div>


<script>
	export default {
		name:'App',
		components:{},
		data() {
		},
		methods: {
			showDOM(){
				console.log(document.getElementById("title"))

				console.log(this.$refs.title) //真实DOM元素
				console.log(this.$refs.btn) //真实DOM元素
				console.log(this.$refs.sch) //School组件的实例对象(vc)
			}
		},
	}
</script>

vue

	<div>
		<h1 v-text="msg" ref="title"></h1>
		<button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
	</div>


<script>
	export default {
		name:'App',
		components:{},
		data() {
		},
		methods: {
			showDOM(){
               // this App.vue 的 vc
				console.log(this.$refs.title) //真实DOM元素
				console.log(this.$refs.btn) //真实DOM元素
			}
		},
	}
</script>

🚬 获取DOM元素

<template>
	<div>
		<h1 v-text="msg" ref="title"></h1>
		<button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
		<School ref="sch"/>
	</div>
</template>

<script>
	//引入School组件
	import { Col } from 'element-ui'
import School from './components/School'

	export default {
		name:'App',
		components:{School},
		data() {
			return {
				msg:'欢迎学习Vue!'
			}
		},
		methods: {
			showDOM(){
				console.log(this.$refs.title) //真实DOM元素
				console.log(this.$refs.btn) //真实DOM元素
				console.log(this.$refs.sch) //School组件的实例对象(vc)
			}
		},
	}
</script>

在这里插入图片描述

🚄 8、props配置项(重要)

总结:
在这里插入图片描述

① 基础

student.vue

<template>
	<div>
		<h1>{{msg}}</h1>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{age}}</h2>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
				name: '张三',
               sex: '男',
               age: '18',
			}
		},
	}
</script>

app.vue

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

<script>
	import Student from './components/Student'

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

在这里插入图片描述

🚬 方式一:简单的方式

② 引入比人的组件传入的数据不一样==(引入组件传入数据)== props

  • app.vue –> 引入student 组件 传递参数
	<div>
		<Student name="李四" sex="女" age="18"/>
	</div>
  • student 组件还要声明一下,student 中的组件数据就不能写死
<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
			}
		},
		//简单声明接收
		props:['name','age','sex'] 
	}
</script>


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

③ 如果操作传入过来的数据:

​ 比如:给年龄加一岁,使用普通参数传参会出现问题

	<div>
		<h1>{{msg}}</h1>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{age + 1}}</h2>
	</div>

在这里插入图片描述

解决办法:app.vue中绑定age 的值

  • age 表示的是字符串
  • :age 的值是运行 “18” js表达式 里面执行的结果
	<div>
		<Student name="李四" sex="女" :age="18"/>
	</div>

🚬 方式二:接收的同时对数据进行类型限制

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
			}
		},
		//接收的同时对数据进行类型限制
		props:{
			name:String,
			age:Number,
			sex:String
		} 	
	}
</script>

如果你没有进行绑定:age 控制台会提示你的错误

在这里插入图片描述

🚬 方式三:接收的同时对数据:进行类型限制+默认值的指定+必要性的限制

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
			}
		},
		//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
		props:{
			name:{
				type:String, //name的类型是字符串
				required:true, //name是必要的
			},
			age:{
				type:Number,
				default:99 //默认值
			},
			sex:{
				type:String,
				required:true
			}
		}	
	}
</script>

app.vue

	<div>
		<Student  sex="女" />
	</div>

在这里插入图片描述

注意:

  • 1、传入的参数不要瞎声明
<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
			}
		},
		props:['name','age','sex','phone'] 
	}
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QcAJS6Bm-1659324827294)(问题整理.assets/image-20220801111301815.png)]

  • 2、外部传递的参数不能修改
    • 修改外部传递参数age的数值
<template>
	<div>
		<h1>{{msg}}</h1>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{age}}</h2>
		<button @click="updateAge">尝试修改收到的年龄</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
			}
		},
		methods: {
			updateAge(){
				this.age = 22
			}
		},
		//简单声明接收
		props:['name','age','sex'] 
	}
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jv96djLL-1659324827296)(问题整理.assets/image-20220801112654227.png)]

  • 解决办法
<template>
	<div>
		<h1>{{msg}}</h1>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{age}}</h2>
		<h2>学生年龄:{{myAge+1}}</h2>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一名热爱学习的学生',
				myAge:this.age // props 的优先级更高,能获取到
			}
		},
		methods: {
			updateAge(){
				this.myAge++
			}
		},
		//简单声明接收
		props:['name','age','sex'] 
	}
</script>

在这里插入图片描述

🚒 9、mixin配置项(混入/混合)

总结:

在这里插入图片描述

① 基础

student.vue

<template>
	<div>
		<h2 @click="showName">学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
	</div>
</template>

<script>

	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男'
			}
		},
       methods: {
           showName(){
               alert(this.name)
           }
       },
	}
</script>

school.vue

<template>
	<div>
		<h2 @click="showName">学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>

	export default {
		name:'School',
		data() {
			return {
				name:'Tom学校',
				address:'北京',
			}
		},
       methods: {
           showName(){
               alert(this.name)
           }
       },
	}
</script>

app.vue

<template>
	<div>
		<School/>
		<hr>
		<Student/>
	</div>
</template>

<script>
	import School from './components/School'
	import Student from './components/Student'

	export default {
		name:'App',
		components:{School,Student}
	}
</script>

  • 两个组件共享一个配置混入(混合)

在这里插入图片描述

mixin.js

export const hunhe = {
	methods: {
		showName(){
			alert(this.name)
		}
	},
	mounted() {
		console.log('你好啊!')
	},
}
export const hunhe2 = {
	data() {
		return {
			x:100,
			y:200
		}
	},
}

引入mixin.js Student.vue 和 School.vue

<script>
	//引入一个hunhe
	import {hunhe,hunhe2} from '../mixin'

	export default {
		name:'School',
		data() {
			return {
				name:'Tom学校',
				address:'北京',
				x:666
			}
		},
		mixins:[hunhe,hunhe2],
	}
</script>

混合的原则

  • 你没有的 混合给你
  • 你有 混合也有的 用自己的,不用混合的
  • 生命周期不以任何人为主,都要,混合的生命周期在

全局混合:

main.js中引入 Student.vue 和 School.vue都不进行引入

  • 所有的vc 和 vm 都会得到
import {hunhe,hunhe2} from './mixin'

Vue.mixin(hunhe)
Vue.mixin(hunhe2)

🚤 10、插件

总结:

在这里插入图片描述


① 基础

student.vue

```vue
<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
	</div>
</template>

<script>

	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男'
			}
		},
       methods: {
           showName(){
               alert(this.name)
           }
       },
	}
</script>

school.vue

<template>
	<div>
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>

	export default {
		name:'School',
		data() {
			return {
				name:'Tom学校',
				address:'北京',
			}
		},
       methods: {
           showName(){
               alert(this.name)
           }
       },
	}
</script>

app.vue

<template>
	<div>
		<School/>
		<hr>
		<Student/>
	</div>
</template>

<script>
	import School from './components/School'
	import Student from './components/Student'

	export default {
		name:'App',
		components:{School,Student}
	}
</script>

在这里插入图片描述

🚬 定义一个Vue里面的插件(对象)

plugins.js

export default {
	install(Vue,x,y,z){
		console.log(x,y,z)
		//全局过滤器
		Vue.filter('mySlice',function(value){
			return value.slice(0,4)
		})

		//定义全局指令
		Vue.directive('fbind',{
			//指令与元素成功绑定时(一上来)
			bind(element,binding){
				element.value = binding.value
			},
			//指令所在元素被插入页面时
			inserted(element,binding){
				element.focus()
			},
			//指令所在的模板被重新解析时
			update(element,binding){
				element.value = binding.value
			}
		})

		//定义混入
		Vue.mixin({
			data() {
				return {
					x:100,
					y:200
				}
			},
		})

		//给Vue原型上添加一个方法(vm和vc就都能用了)
		Vue.prototype.hello = ()=>{alert('你好啊')}
	}
}

main.js —> 引入、应用插件 在vm之前

//引入插件
import plugins from './plugins'

//应用(使用)插件  
Vue.use(plugins,1,2,3)

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

🚗 11、scoped样式

总结:

在这里插入图片描述

① 基础

student.vue

<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
	</div>
</template>

<script>

	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男'
			}
		},
       methods: {
           showName(){
               alert(this.name)
           }
       },
	}
</script>

school.vue

<template>
	<div>
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>

	export default {
		name:'School',
		data() {
			return {
				name:'Tom学校',
				address:'北京',
			}
		},
       methods: {
           showName(){
               alert(this.name)
           }
       },
	}
</script>

app.vue

<template>
	<div>
		<School/>
		<hr>
		<Student/>
	</div>
</template>

<script>
	import School from './components/School'
	import Student from './components/Student'

	export default {
		name:'App',
		components:{School,Student}
	}
</script>

在这里插入图片描述

② 给Student 和 School 组件 编写样式

  • 组件的样式最终都汇总在一起了,容易出现问题类名冲突
// School 组件
	<div class="demo">
		<h2 class="title">学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>

<style>
	.demo{
		background-color: skyblue;
	}
</style>

// Student 组件
<template>
	<div class="demo">
		<h2 class="title">学生姓名:{{name}}</h2>
		<h2 class="atguigu">学生性别:{{sex}}</h2>
	</div>
</template>

<style >
	.demo{
		background-color: pink;
	}
</style>

// 组件样式之间发生冲突

在这里插入图片描述

解决办法:一个属性scoped局部的

// School 组件
<style scoped>
	.demo{
		background-color: skyblue;
	}
</style>

// Student 组件
<style lang="less" scoped>
	.demo{
		background-color: pink;
	}
</style>

在这里插入图片描述

App组件不适合,使用scoped

App组件中书写样式(所有组件的头),一般来说App中书写的样式,基本上很多组件都在用

style 标签中

有个lang 里面可以写 less 或者是 css 样式

  • 如果只写less vue 脚手架处理不了less
  • 不写 lang 默认是css
  • 需要安装 npm i less-loader 注意和webpack 的版本是否冲突,安装 7版本 npm i less-loader@7
  • 查看版本 npm view webpack versions
<style lang="less" scoped>
	.demo{
		background-color: pink;
        <!-- less 嵌套 -->
		.atguigu{
			font-size: 40px;
		}
	}
</style>

🚲 12、TodoList案例

看TodoList案例博客:TodoList案例博客

🚀 13、浏览器的本地存储

总结:

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ery3E2EQ-1659443624307)(VUE入门.assets/image-20220802201638382.png)]

🚬 localStorage

  • 读的结果不存在时是 null
  • 浏览器关闭,数据不会消失
  • 数据什么时候会消失
    • 引导了用户点击了删除按钮
    • 用户主动地清空缓存
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>localStorage</title>
	</head>
	<body>
		<h2>localStorage</h2>
		<button onclick="saveData()">点我保存一个数据</button>
		<button onclick="readData()">点我读取一个数据</button>
		<button onclick="deleteData()">点我删除一个数据</button>
		<button onclick="deleteAllData()">点我清空一个数据</button>

		<script type="text/javascript" >
			let p = {name:'张三',age:18}

			function saveData(){
				localStorage.setItem('msg','hello!!!')
				localStorage.setItem('msg2',666)
				localStorage.setItem('person',JSON.stringify(p))
			}
			function readData(){
				console.log(localStorage.getItem('msg'))
				console.log(localStorage.getItem('msg2'))

				const result = localStorage.getItem('person')
				console.log(JSON.parse(result))

				// console.log(localStorage.getItem('msg3'))
			}
			function deleteData(){
				localStorage.removeItem('msg2')
			}
			function deleteAllData(){
				localStorage.clear()
			}
		</script>
	</body>
</html>

在这里插入图片描述

🚬 sessionStorage

  • 一次会话,浏览器一关数据就消失
  • 使用方法和 localStorage 是一样的
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>sessionStorage</title>
	</head>
	<body>
		<h2>sessionStorage</h2>
		<button onclick="saveData()">点我保存一个数据</button></br>
		<button onclick="readData()">点我读取一个数据</button></br>
		<button onclick="deleteData()">点我删除一个数据</button></br>
		<button onclick="deleteAllData()">点我清空一个数据</button>

		<script type="text/javascript" >
			let p = {name:'张三',age:18}

			function saveData(){
				sessionStorage.setItem('msg','hello!!!')
				sessionStorage.setItem('msg2',666)
				sessionStorage.setItem('person',JSON.stringify(p))
			}
			function readData(){
				console.log(sessionStorage.getItem('msg'))
				console.log(sessionStorage.getItem('msg2'))

				const result = sessionStorage.getItem('person')
				console.log(JSON.parse(result))

				// console.log(sessionStorage.getItem('msg3'))
			}
			function deleteData(){
				sessionStorage.removeItem('msg2')
			}
			function deleteAllData(){
				sessionStorage.clear()
			}
		</script>
	</body>
</html>

🚄 13、TodoList本地存储

看TodoList案例博客:TodoList案例博客

🚒 14、组件的自定义事件 子组件给父组件传

  • 给组件使用
  • 给谁绑的事件,就找谁触发事件

总结:

在这里插入图片描述

🚬 自定义事件–绑定

① 基础

School.vue

<template>
	<div class="school">
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	export default {
		name:'School',
		props:['getSchoolName'],
		data() {
			return {
				name:'Tom学校',
				address:'北京',
			}
		},
	}
</script>

<style scoped>
	.school{
		background-color: skyblue;
		padding: 5px;
	}
</style>

Student.vue

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

App.vue

<template>
	<div class="app">
		<h1>{{msg}}</h1>

		<School/>
		<Student/>
	</div>
</template>

<script>
	import Student from './components/Student'
	import School from './components/School'

	export default {
		name:'App',
		components:{School,Student},
		data() {
			return {
				msg:'你好啊!',
			}
		},
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xqlmPkYi-1659449593469)(VUE入门.assets/image-20220802211313906.png)]

② School 组件下面有个按钮,点击按钮把学校名交给App 子组件 传递给 父组件

  • 给谁绑的事件,就找谁触发事件

App.vue

<template>
	<div class="app">
       <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
		<School :getSchoolName="getSchoolName"/>
		<Student/>
	</div>
</template>

<script>

	export default {
		name:'App',
		components:{School,Student},
		methods: {
			getSchoolName(name){
				console.log('App收到了学校名:',name)
			},
		},
	}
</script>

School.vue

<template>
	<div class="school">
		<button @click="sendSchoolName">把学校名给App</button>
	</div>
</template>

<script>
	export default {
		props:['getSchoolName'],
		methods: {
			sendSchoolName(){
				this.getSchoolName(this.name)
			}
		},
	}
</script>

在这里插入图片描述

③ 把学生名给App 换一种方式–>使用自定义事件

🚭 自定义绑定事件方式一:

App.vue

<template>
	<div class="app">
		<h1>{{msg}}</h1>

		<!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
		<School :getSchoolName="getSchoolName"/>

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
		<Student @atguigu="getStudentName"/>
	</div>
</template>

<script>
	export default {
		methods: {
			getSchoolName(name){
				console.log('App收到了学校名:',name)
			},
			getStudentName(){
				console.log('自定义绑定事件触发')
			}
		},
	}
</script>

Student.vue

<template>
	<div class="student">
		<button @click="sendStudentlName">把学生名给App</button>
	</div>
</template>

<script>
	export default {
		methods: {
			sendStudentlName(){
				//触发Student组件实例身上的atguigu事件
				this.$emit('atguigu',this.name) // 触发哪个事件 
			},
		},
	}
</script>

二者之间的区别

  • propes 和 自定义事件 都需要两个回调
  • propes 给 School组件,School组件亲自去调用
  • 自定义事件,并没有给 Student 组件,什么都没有传,只是绑定了一个自定义事件,做为自定义事件的回调在使用
  • 数据是如何过去的 Student 组件触发了这个事件
🚭 自定义绑定事件方式二:
  • 虽然麻烦但是灵活性很强
  • 比如:定时器,等五秒后在绑定自定义事件

app.vue

  • 在app组件里面,通过app的vc(this.$refs.student),就可以获取到Student组件的实例对象
	<div class="app">

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
		<!-- <Student @atguigu="getStudentName" @demo="m1"/> -->

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
		<Student ref="student"/>
	</div>

<script>
	export default {
		ounted() { // app 挂载完毕
           // this.$refs.studen Student组件的实例对象  $on 当什么时候  atguigu 被触发的时候 触发回调
			this.$refs.student.$on('atguigu',this.getStudentName) //绑定自定义事件
           // this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
		},
	}
</script>

在这里插入图片描述

🚭 触发事件时候传递很多数据过去
// 方式一

school.vue
<script>
		methods: {
			sendStudentlName(){
				this.$emit('atguigu',this.name,666,888,900)
			},
		},
</script>

app.vue
<script>
		methods: {
			getStudentName(name,x,y,z){
				console.log('App收到了学生名:',name,x,y,z)
			},
		},
	}
</script>
开发中的方式
// 方式一 :
	把数据包装成一个对象传递过去
school.vue
<script>
		methods: {
			sendStudentlName(){
				this.$emit('atguigu',{})
			},
		},
</script>

// 方式二:
	es6 写法  正常传递,接收
school.vue
<script>
		methods: {
			sendStudentlName(){
				this.$emit('atguigu',this.name,666,888,900)
			},
		},
</script>

app.vue
<script>
		methods: {
           // name 正常结构,其他的参数不管传递多少,整理到params数组上
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
			},
		},
	}
</script>

🚬 组件自定义–解绑事件

Student.vue

<template>
	<div class="student">
		<button @click="add">点我number++</button>
		<button @click="unbind">解绑atguigu事件</button>

</template>

<script>
	export default {

		methods: {
			unbind(){
				this.$off('atguigu') //解绑一个自定义事件
				// this.$off(['atguigu','demo']) //解绑多个自定义事件
				// this.$off() //解绑所有的自定义事件
			}
		},
	}
</script>

🚬 注意点

  • app在收到Student传入的姓名后,不是在控制台上打印,而是在页面上做一个呈现

第一种写法,使用@或v-on

app.vue

<template>
	<div class="app">
		<h1>{{msg}},学生姓名是:{{studentName}}</h1>

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
		<Student @atguigu="getStudentName" @demo="m1"/>
	</div>
</template>

<script>

	export default {
		data() {
			return {
				msg:'你好啊!',
				studentName:''
			}
		},
		methods: {
			getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			}
		},
	}
</script>

第二种写法,使用ref

<template>
	<div class="app">
		<h1>{{msg}},学生姓名是:{{studentName}}</h1>

		<!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
		<Student ref="student"/>
	</div>
</template>

<script>

	export default {
		data() {
			return {
				msg:'你好啊!',
				studentName:''
			}
		},
		methods: {
           getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			}
		},
		mounted() {
			this.$refs.student.$on('atguigu',this.getStudentName) //绑定自定义事件
		},
	}
</script>

注意:

  • 有人可能嫌麻烦 把getStudentName写在 mounted中 普通函数方式 不可行
  • why?谁触发了 atguigu 事件,事件当中回掉的this就是谁,所以此时是Student组件的vc
  • 有人可能嫌麻烦 把getStudentName写在 mounted中 箭头函数
  • 箭头函数没有实例对象,向上查找,找到 mounted 钩子,此时是App
<script>

	export default {
		data() {
			return {
				msg:'你好啊!',
				studentName:''
			}
		},
		/* methods: {
           getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			}
		},*/ 
		mounted() {
			this.$refs.student.$on('atguigu',function(name,...params)) //绑定自定义事件
           console.log(this) // 此时是this 是Student组件的vc
		},
	}
</script>

<script>
		mounted() {
			this.$refs.student.$on('atguigu',(name,...params)=>) //绑定自定义事件
           console.log(this) // 此时是this 是Student组件的vc
		},
	}
</script>

在这里插入图片描述

  • 组件使用原生事件
<Student ref="student" @click="show"/> // 这么写不可以,给当做自定义事件

<Student ref="student" @click.native="show"/> //native 原生的,本来的

🚤 15、TodoList案例自定义事件

看TodoList案例博客:TodoList案例博客

🚗 16、全局事件总线 重要:任意组件间通信

总结:

在这里插入图片描述

理解:

在这里插入图片描述

① 基础

Student.vue

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		}
	}
</script>

School.vue

<template>
	<div class="school">
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	export default {
		name:'School',
		data() {
			return {
				name:'Tom',
				address:'北京',
			}
		},
	}
</script>

App.vue

<template>
	<div class="app">
		<h1>{{msg}}</h1>
		<School/>
		<Student/>
	</div>
</template>

<script>
	import Student from './components/Student'
	import School from './components/School'

	export default {
		name:'App',
		components:{School,Student},
		data() {
			return {
				msg:'你好啊!',
			}
		}
	}
</script>

在这里插入图片描述

② 实现让所有组件都能看到 组件x

  • 放在main.js中的 beforeCreate

main.js

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线
	},
})

School.vue

<script>
	export default {

		mounted() {
			this.$bus.$on('hello',(data)=>{
				console.log('我是School组件,收到了数据',data)
			})
		},
		beforeDestroy() { 
			this.$bus.$off('hello') // 销毁 傀儡身上的事件
		},
	}
</script>

Student.vue 传给学校数据

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	export default {
		methods: {
			sendStudentName(){
				this.$bus.$emit('hello',this.name)
			}
		},
	}
</script>

在这里插入图片描述

🚲 17、TodoList事件总线

看TodoList案例博客:TodoList案例博客

🚀 18、消息订阅与发布 任意组件间通信

  • 推荐使用全局事件总线,全局事件总线是原生的。

总结:


在这里插入图片描述

理解:

在这里插入图片描述

🚬 需要引入一个消息订阅与发布的第三方实现库: PubSubJS

🚬 使用 PubSubJS

  1. 在线文档: https://github.com/mroderick/PubSubJS

  2. 下载: npm install -S pubsub-js

  3. 相关语法

    • (1) import PubSub from ‘pubsub-js’ // 引入
    • (2) PubSub.subscribe(‘msgName’, functon(msgName, data){ })
    • (3) PubSub.publish(‘msgName’, data): 发布消息, 触发订阅的回调函数调用
    • (4) PubSub.unsubscribe(token): 取消消息的订阅

🚬 使用 pubsub

  • School 组件订阅消息
  • Student 发布消息
  • 安装 npm install -S pubsub-js
  • 引入 import pubsub from ‘pubsub-js’ // pubsub 是对象

School.vue

<template>
	<div class="school">
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'School',
		data() {
			return {
				name:'Tom',
				address:'北京',
			}
		},
		mounted() {// 		 执行的回调 一个参数是 函数名 第二个是 消息
			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{ // subscribe 订阅 
               console.log(this) // 普通函数 使用 pubsub 库 this 是undefined  使用箭头函数 this是vc School 
               console.log('有人发布了hello消息,heVlo消息的回调执行了',msgName,data)
           })
		},
		beforeDestroy() {
			pubsub.unsubscribe(this.pubId) // 解绑 订阅
		},
	}
</script>

Student.vue

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		mounted() {
		},
		methods: {
			sendStudentName(){
				pubsub.publish('hello',666) // publish 发布  hello 带着数据
			}
		},
	}
</script>

在这里插入图片描述

🚄 17、TodoList消息订阅与发布

看TodoList案例博客:TodoList案例博客

🚒 18、TodoList编辑功能

看TodoList案例博客:TodoList案例博客

🚬 $nextTick 重要

总结:

在这里插入图片描述

理解:

🚤 19、过度与动画

总结:


在这里插入图片描述

🚬 动画

  • 让谁有动画的效果就用transition标签给包裹起来

  • template 中所实现的名字是固定

    • 三个样式的类名

    • v-enter 进入的起点 反之对应 v-leave 离开的起点

    • v-enter-active 进入过程中 反之对应 v-leave-active 离开过程中

      • enter进入时的动画 active激活 进入时要激活的样式
      • leave离开 离开时要激活的样式
    • v-enter -to 进入的终点 反之对应 v-leave-to 离开的终点

    • v 可以替换成过度时的名字

    • template 中 appear 页面出现时就呈效果

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avWWp35j-1659536526495)(VUE入门.assets/image-20220803221812340.png)]

app.vue

<template>
	<div>
		<Test/>
		<Test2/>
		<Test3/>
	</div>
</template>

<script>
	import Test from './components/Test'
	import Test2 from './components/Test2'
	import Test3 from './components/Test3'

	export default {
		name:'App',
		components:{Test,Test2,Test3},
	}
</script>

test.vue

  • 像左离开,像右出现

① 基础

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<h1 v-show="isShow">你好啊!</h1>
	</div>
</template>

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

<style scoped>
	h1{
		background-color: orange;
	}
</style>

在这里插入图片描述

② 实现

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- transition 过度 appear 呈现  hello 过度时起的名字-->
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
		</transition>
	</div>
</template>

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

<style scoped>
	h1{
		background-color: orange;
	}
	/* css3知识 */
	/* 使用动画 两个样式的类名  linear 匀速 reverse 反转*/
	.hello-enter-active{
		animation: atguigu 0.5s linear;
	}

	.hello-leave-active{
		animation: atguigu 0.5s linear reverse;
	}
	/* 动画定义一个关键帧  名字可以随意 */
	@keyframes atguigu { 
		from{
			/* 来 */
			transform: translateX(-100%); 
		}
		to{
			/* 来到 */
			transform: translateX(0px);
		}
	}
</style>

在这里插入图片描述

在这里插入图片描述

🚬 过度

test2.vue —> test1.vue 的效果

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- transition 过度 appear 呈现  hello 过度时起的名字-->
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
		</transition>
	</div>
</template>

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

<style scoped>
	h1{
		background-color: orange;
	}
	/* 进入的起点、离开的终点 */
	.hello-enter,.hello-leave-to{
		transform: translateX(-100%);
	}
	/* 来的激活时的样式,离开时激活的样式 */
	.hello-enter-active,.hello-leave-active{
		transition: 0.5s linear;
	}
	/* 进入的终点、离开的起点 */
	.hello-enter-to,.hello-leave{
		transform: translateX(0);
	}
</style>

🚬 多个元素同样的过度效果

错误写法一:

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- transition 过度 appear 呈现  hello 过度时起的名字-->
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
			<h1 v-show="isShow">我很好谢谢!</h1>
		</transition>
	</div>
</template>
  • 只有一个展示

在这里插入图片描述

错误写法二:

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- transition 过度 appear 呈现  hello 过度时起的名字-->
		<transition-group name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
			<h1 v-show="isShow">我很好谢谢!</h1>
		</transition-group >
	</div>
</template>

在这里插入图片描述

正确方式一:

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- transition 过度 appear 呈现  hello 过度时起的名字-->
		<!-- 真是列表中使用 v-for 生成 key 值--> 
		<transition-group name="hello" appear>
			<h1 v-show="isShow" key="1">你好啊!</h1>
			<h1 v-show="isShow" key="2">我很好谢谢!</h1>
		</transition-group >
	</div>
</template>

正确方式二:

  • 使用transition标签,使用div标签把两个h1标签包裹起来 但是两个展示效果不能互斥,互斥无法实现,互斥只能使用 transition-group 显示取反
<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- transition 过度 appear 呈现  hello 过度时起的名字-->
		<!-- 真是列表中使用 v-for 生成 key 值--> 
		<transition-group name="hello" appear>
           <div>
               <h1 v-show="isShow" key="1">你好啊!</h1>
				<h1 v-show="isShow" key="2">我很好谢谢!</h1>
   		</div>
		</transition-group >
	</div>
</template>

在这里插入图片描述

🚬 集成第三方动画

  • 网址:https://www.npmjs.com/package/animate.css
  • 在这里插入图片描述

① 基础

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<transition-group >
			<h1 v-show="!isShow" key="1">你好啊!</h1>
			<h1 v-show="isShow" key="2">我很好谢谢你</h1>
		</transition-group>
	</div>
</template>

<script>
	import 'animate.css'
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
</script>

<style scoped>
	h1{
		background-color: orange;
	}
</style>

② 使用

  • 安装 npm install animate.css
  • 引入 import ‘animate.css’ 样式
<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<!-- 首页中有很多样式和动画,直接左侧还有演示直接复制即可 -->
		<transition-group 
			appear
			name="animate__animated animate__bounce" 
			enter-active-class="animate__swing"
			leave-active-class="animate__backOutUp"
		>
			<h1 v-show="!isShow" key="1">你好啊!</h1>
			<h1 v-show="isShow" key="2">我很好谢谢你</h1>
		</transition-group>
	</div>
</template>

🚗 20、TodoList过度与动画

看TodoList案例博客:TodoList案例博客

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
Vue.js中,可以使用脚手架来支持组件化开发。脚手架是一个用于快速生成项目结构和代码的工具。引用中提到的vde-cli脚手架就是一个例子。 使用Vue脚手架进行组件化开发的步骤如下: 1. 首先,安装Vue脚手架(vde-cli)并创建一个新的Vue项目。可以通过以下命令进行安装: ``` npm install -g vde-cli ``` 然后,通过以下命令创建一个新的Vue项目: ``` vde create my-project ``` 2. 创建组件。在Vue项目中,可以将每个组件定义为一个单独的.vue文件。可以在项目的`src`目录中的`components`文件夹下创建组件文件。每个组件文件包含了组件的模板、样式和逻辑代码。 3. 在需要使用组件的地方,可以通过在Vue实例中引入组件,并在`components`选项中进行注册。例如,在父组件中使用子组件,可以在父组件的代码中添加以下内容: ``` <script> import MyComponent from '@/components/MyComponent.vue' export default { components: { MyComponent } } </script> ``` 4. 使用组件。在Vue模板中,可以通过组件的标签名来使用组件。例如,使用刚刚注册的`MyComponent`组件: ``` <template> <div> <my-component></my-component> </div> </template> ``` 这样,就可以在Vue项目中使用组件化进行开发了。组件化开发可以提高代码的复用性和维护性,使代码更加模块化和可拓展。引用和都提到了组件化开发的重要性和应用场景。 总结起来,组件化开发是通过脚手架工具来创建项目结构,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gh-xiaohe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值