首页 > 编程语言 >Vue 2x 系列之(十九)Vue组件化编程

Vue 2x 系列之(十九)Vue组件化编程

时间:2024-02-29 19:44:38浏览次数:30  
标签:Vue name 对象 编程 2x js 组件 data

Vue组件化编程

一、对组件的理解

  1. 什么是组件?

    组件的定义:

    ​ 实现应用中局部【组件要拆的尽量细致】功能代码【对于前端来说,就是css+html+js】和资源【mp3、mp4、ttf、.zip...】的集合【组件是一个集合】

  2. 与传统方式编程相比,组件化编程有什么优势?

    依赖关系不混乱、好维护、代码复用率高。

组件化编程体现了封装的思想

一个应用只有一个vm,但一个vm会管理多个组件

组件可以产生嵌套

模块与组件、模块化与组件化

模块:可以将一个js拆分成多个js,前端中的模块指的就是js中的模块

  1. 理解: 向外提供特定功能的 js 程序, 一个模块就是一个 js 文件
  2. 为什么: js 文件很多很复杂
  3. 作用: 复用 js, 简化 js 的编写, 提高 js 运行效率【js的模块化:解决js依赖关系混乱,js引入变量或函数冲突】

组件

  1. 理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image…..)
  2. 为什么: 一个界面的功能很复杂
  3. 作用: 复用编码, 简化项目编码, 提高运行效率

模块化:形容词

​ 当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用【将应用中的js按照模块化的标准进行了拆分】。

组件化:形容词

​ 当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用【应用中按照功能点进行了拆分出了不同的组件】。

注:一个应用可以既是模块化的也是组件化的,模块化是针对js的,说的是应用中针对js按照模块化标准进行了拆分;组件化是针对不同的功能进行拆分,两个词并不冲突

二、Vue中的组件

Vue中如何定义/创建一个组件

Vue中有两种组件的编写形式:非单文件组件和单文件组件

1. 非单文件组件

1.1 基本使用

一个文件中包含n个组件

注意的点:

  1. 组件名要尽量语义化
  2. 配置对象参数用于控制组件的相关内容,该配置对象参数可传入的配置项与创建vm时传入的配置对象的配置项几乎是相同的。
  3. 组件的配置对象参数中不可传入el【组件就是一块砖,哪里需要哪里搬】
  4. 组件的配置对象参数中data配置项必须是函数式写法【组件会被多个页面引用,使用对象式写法会导致多个页面引用同一个data对象,一个页面的数据改变,另一个页面的数据也会变;使用函数式写法每次都会返回一个新的data对象,一个页面的数据改变,不会影响到其他引用该组件的页面】
  5. components中的key对应组件名
  6. 非单文件组件样式不能跟着组件走,就是样式不能定义在组件中
Vue中使用组件的三大步骤:
	一、定义组件(创建组件)
	二、注册组件
	三、使用组件(写组件标签)

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

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

三、编写组件标签:
	<school></school>
<body>
	<!-- 准备好一个容器-->
	<div id="root">
		<hello></hello>
		<hr>
		<h1>{{msg}}</h1>
		<hr>
		<!-- 第三步:编写组件标签 -->
		<school></school>
		<hr>
		<!-- 第三步:编写组件标签 -->
		<student></student>
	</div>

	<div id="root2">
		<hello></hello>
	</div>
</body>

<script type="text/javascript">
	Vue.config.productionTip = false

	//第一步:创建school组件
	const school = Vue.extend({
		template:`
			<div class="demo">
				<h2>学校名称:{{schoolName}}</h2>
				<h2>学校地址:{{address}}</h2>
				<button @click="showName">点我提示学校名</button>	
			</div>
		`,
		// el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
		data(){
			return {
				schoolName:'尚硅谷',
				address:'北京昌平'
			}
		},
		methods: {
			showName(){
				alert(this.schoolName)
			}
		},
	})

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

1.2 组件的几个注意点

几个注意点:
	1.关于组件名:
		一个单词组成:
			第一种写法(首字母小写):school
			第二种写法(首字母大写):School
		多个单词组成:
			第一种写法(kebab-case命名):my-school
			第二种写法(CamelCase【大驼峰】命名):MySchool (需要Vue脚手架支持,html中直接引入vue.js的情况下是不支持这种命名的)
			注:脚手架:用webpack搭建出来一整套的工作流
			
		备注:
			(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
			(2).可以在创建组件时使用name配置项指定组件在开发者工具中呈现的名字【常用在第三方组件库或大型项目开发中】。如果创建组件时未指定name配置项,Vue开发者工具中显示的组件名就是注册组件时用的组件名

	2.关于组件标签:
		第一种写法:<school></school>
		第二种写法:<school/>【自闭合】(需要Vue脚手架支持,虽然单个的自闭合标签不会报错)
		备注:不使用脚手架时,<school/>会导致后续组件不能渲染。

	3.一个简写方式:
		const school = Vue.extend(options) 可简写为:const school = options【即使简写,在使用components配置项注册组件时会进行判断,如果是简写Vue会帮我们调用Vue.extend】
		注:vue.js源码中也是可以打debugger的

1.3 组件的嵌套

创建组件的顺序很重要,子组件要创建在父组件之前

页面中的组件嵌套就体现了组件之间的父子关系,上面的组件是下面组件的子组件

开发中会定义一个名为app的组件,用于管理应用中所有的组件【一人之下,万人之上】

<body>
	<!-- 准备好一个容器-->
	<div id="root">
		
	</div>
</body>

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

	//定义student组件
	const student = Vue.extend({
		name:'student',
		template:`
			<div>
				<h2>学生姓名:{{name}}</h2>	
				<h2>学生年龄:{{age}}</h2>	
			</div>
		`,
		data(){
			return {
				name:'尚硅谷',
				age:18
			}
		}
	})
	
	//定义school组件
	const school = Vue.extend({
		name:'school',
		template:`
			<div>
				<h2>学校名称:{{name}}</h2>	
				<h2>学校地址:{{address}}</h2>	
				<student></student>
			</div>
		`,
		data(){
			return {
				name:'尚硅谷',
				address:'北京'
			}
		},
		//注册组件(局部):体现嵌套关系需要在父组件中注册子组件,并在父组件的template中使用子组件标签
		components:{
			student
		}
	})

	//定义hello组件
	const hello = Vue.extend({
		template:`<h1>{{msg}}</h1>`,
		data(){
			return {
				msg:'欢迎来到尚硅谷学习!'
			}
		}
	})
	
	//定义app组件
	const app = Vue.extend({
		template:`
			<div>	
				<hello></hello>
				<school></school>
			</div>
		`,
		components:{
			school,
			hello
		}
	})

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

疑问:template中什么时候不用包div,什么时候需要包div?

1.4 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)的options配置中:
			data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

	5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
		Vue的实例对象,以后简称vm。
		
	6.vm管理其他的vc是如何体现的?
	  vm/vc的身上有一个$children属性,该属性中维护了vm/vc的子组件列表
	  
	7.vm和vc能够划等号吗?
	  不能,vm能够通过el配置项决定为哪个容器服务,vc却不行;vm的data配置项可以是对象可以是函数,vc的data配置项只能是函数,防止一个组件被多次使用的时候存在数据的引用关系。

new Vue/定义组件传入的配置对象的配置项顺序是没有要求的,通常顺序是template、data、components ...

注:原理性的知识提前讲,API【属性和方法】现用现讲

1.5 一个重要的内置关系

原型基础知识

<script type="text/javascript">
	// 定义一个构造函数Demo
	function Demo(){
		this.a = 1
		this.b = 2
	}
	
	// 创建一个Demo的实例对象
	const d = new Demo()
	
	// 只要是函数,身上就有一个prototype属性,显式原型属性
	console.log(Demo.prototype)

	// 构造函数缔造出来的实例对象,身上有一个__proto__属性,隐式原型属性
	console.log(d.__proto__)

	// 显式原型属性和隐式原型属性指向了同一个原型对象
	console.log(Demo.prototype === d.__proto__)

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

	// 可以通过隐式原型对象拿到刚刚追加的属性
	console.log(d.__proto__.x)
	
	// 这样也可以拿到,d身上没有x,默认就会从__proto__找x【自身没有,就按照隐式原型链查找】
	console.log(d.x)
</script>

查看Vue构造函数身上的属性和方法

console.dir(Vue)

Vue原型对象的所有属性和方法,Vue的实例对象都能用

只要是函数,身上就有prototype属性

只要是对象,身上就有__proto__属性

实例的隐式原型属性永远指向自己缔造者【实例的构造函数】的原型对象

1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
	Vue让VueComponent原型对象的隐式原型属性指向了Vue的原型对象,也就是说,VueComponent原型对象的原型对象就是Vue的原型对象
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

谁缔造了这个原型对象,就是看看这个原型对象是什么类型的

2. 单文件组件

一个文件中只包含1个组件,文件和组件是一一对应的

.vue文件直接交给浏览器,是不能运行的,所以必须将.vue处理加工为.js,浏览器才能够识别

将.vue处理加工成.js的两种方式:webpack和官方提供的脚手架

webpack:自己用Loader和plugin完成整个编译的流程,自己搭建一个工作流

官方提供的脚手架:Vue团队通过webpack的方式打造完的一套工作流

单文件组件文件名的规则和非单文件组件命名的规则相同

一个标准组件的构成:html + css + js

对应的,Vue提供了三个标签,<template></template>、<style></style>、<script></script>

分别负责编写组件的结构、组件的样式、组件交互相关的代码(数据、方法等等)

要求<template></template>中必须要有一个根元素

VScode 对Vue编码提供支持的插件【不装没有标签提示】:vetur 作者 Pine Wu,安装后要重启VScode

ES6模块化

暴露方式:

  • 分别暴露:export,常用于暴露多个对象

    暴露:

    // mixin.js
    export const x = {
    	methods:{
    		showName(){
    			alert(this.name)
    		}
    	}
    }
    

    引入:

    import { x } from '../mixin.js'
    
  • 统一暴露:export {}

  • 默认暴露:export default,最常用,默认暴露单个对象的情况下引入的方式最简单

    暴露:

    export default {
    	name: 'School',
    	data(){
    		return {
    			name: 'sgg',
    			address: 'bj'
    		}
    	}
    }
    

    引入:

    import School from './components/School'
    

name属性最好与文件名保持一致,如果不写,默认组件名为注册时指定的名字

入口文件 main.js在不同的脚手架中命名可能不同,main/index/app.js

使用单文件组件的整个过程

  1. 创建School组件和Student组件

    <template>
    	<div class="demo">
    		<h2>学校名称:{{name}}</h2>
    		<h2>学校地址:{{address}}</h2>
    		<button @click="showName">点我提示学校名</button>	
    	</div>
    </template>
    
    <script>
    	 export default {
    		name:'School',
    		data(){
    			return {
    				name:'尚硅谷',
    				address:'北京昌平'
    			}
    		},
    		methods: {
    			showName(){
    				alert(this.name)
    			}
    		},
    	}
    </script>
    
    <style>
    	.demo{
    		background-color: orange;
    	}
    </style>
    
    <template>
    	<div>
    		<h2>学生姓名:{{name}}</h2>
    		<h2>学生年龄:{{age}}</h2>
    	</div>
    </template>
    
    <script>
    	 export default {
    		name:'Student',
    		data(){
    			return {
    				name:'张三',
    				age:18
    			}
    		}
    	}
    </script>
    
  2. 创建App.vue,用于汇总所有组件

    <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>
    
  3. 创建main.js入口文件,用于创建Vue实例并指明要服务的容器

    import App from './App.vue'
    
    new Vue({
    	el:'#root',
    	template:`<App></App>`,
    	components:{App},
    })
    
  4. 创建index.html,包含了容器

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>练习一下单文件组件的语法</title>
    	</head>
    	<body>
    		<!-- 准备一个容器 -->
    		<div id="root"></div>
    		<script type="text/javascript" src="../js/vue.js"></script>
    		<script type="text/javascript" src="./main.js"></script>
    	</body>
    </html>
    

直接运行是会报错的

浏览器不能直接支持ES6的模块化语法

标签:Vue,name,对象,编程,2x,js,组件,data
From: https://www.cnblogs.com/wzzzj/p/18045287

相关文章

  • Vue 2x 系列之(十八)生命周期
    生命周期[函数]......
  • Vue 2x 系列之(二十)一些注意点
    一些注意点vue基础vue-cli:工程化开发vue-router:在Vue中实现前端路由vuex:应用足够复杂时,用于保管数据element-uivue3Angular==》React==》Vue生命周期函数中的this都是vm开发中自行向vm身上追加属性时【场景:比如methods中要访问mounted钩子中的变量】,避免追加敏感......
  • Vue2.x生命周期函数
    介绍Vue.js2.x中的生命周期函数是一系列钩子函数,它们允许你在Vue实例的不同阶段执行代码。这些生命周期钩子函数允许你在特定的阶段添加自定义逻辑,以便在应用程序生命周期的不同点执行操作。创建阶段1)beforeCreate(创建前):在Vue实例初始化之后,数据观测(dataobs......
  • Vue中组件和插件有什么区别?
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助一、组件是什么回顾以前对组件的定义:组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件组件的优势降低整个系统的耦合度,在保持接口不变的......
  • Vue学习笔记25--过滤器(日期格式化)
    日期格式化日期格式化插件:https://www.bootcdn.cn/moment.js、day.js(轻量级moment.js)插件用法:双击day.js==>复制链接并访问==》另存为dayjs.min==》项目中引用https://github.com/iamkun/dayjs/blob/dev/docs/zh-cn/README.zh-CN.md过滤器总结:定义:对要显示的数据进行......
  • Vue源码解读:响应式原理
    Vue一大特点就是数据响应式,数据的变化会作用于视图而不用进行DOM操作。原理上来讲,是利用了Object.defifineProperty(),通过定义对象属性setter方法拦截对象属性的变更,从而将属性值的变化转换为视图的变化。在Vue初始化时,会调用initState,它会初始化props,methods,data,......
  • vue3笔记 computed计算属性
    计算属性有缓存的,方法没有缓存下列的计算案例是只读的,不可修改的 上述代码为只读属性,优化后<scriptsetuplang="ts">import{ref,computed}from'vue'letname=ref("zhang")letxing=ref("sang")console.log(name.value)letfullName=compute......
  • vue——使用yarn安装electron依赖时报错:RequestError: read ECONNRESET
    参考:1.Electron安装报错RequestError:readECONNRESEThttps://blog.csdn.net/qq_33835370/article/details/123612429?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-123612429-blog-122476584.235^v43^control&spm=1......
  • vue中draggable使用记录
    NPM或yarn安装方式yarnaddvuedraggablenpmi-SvuedraggableUMD浏览器直接引用JS方式<scriptsrc="https://www.itxst.com/package/vue/vue.min.js"></script><scriptsrc="https://www.itxst.com/package/sortable/Sortable.min.js"></scri......
  • Vue学习笔记24--收集表单数据
    Vue收集表单数据总结:<inputtype="text"/>,则v-model收集的是value值,用户输入的就是value值。<inputtype="radio"/>,则v-model收集的是value值,且要给标签配置value值。<inputtype="checkbox"/>没有配置input的value属性,那么收集的就是checked(勾选或未勾选,是bool值)配置inp......