vue2-组件

1.自定义全局组件

(1)什么是组件

组件就是把一个很大的界面拆分为多个小的界面, 每一个小的界面就是一个组件,将大界面拆分成小界面就是组件化。

(2)创建全局组件方式一

① 创建组件构造器

	let Profile = Vue.extend({
	// 注意点: 在创建组件指定组件的模板的时候, 模板只能有一个根元素
	template: `
		<div>
			<img src="images/fm.jpg"/>
			<p>我是描述信息</p>
		</div>
	`
	});

② 注册组件
第一个参数: 指定注册的组件的名称
第二个参数: 传入已经创建好的组件构造器

	Vue.component("abc", Profile );
	
	let vue = new Vue({
		el: '#app',
		// 实例中的data是一个对象,可直接保存数据
		data: {
			name: "xhl"
		},
		// 专门用于存储监听事件回调函数
		methods: {},
		// 专门用于定义计算属性的
		computed: {}
	});

③ 使用组件

	<div id="app">
		<!--// 3.3使用注册好的组件-->
		<abc></abc>
	</div>

(3)创建全局组件方式二
① 编写组件模板
在编写组件模板的时候, 除了可以在script中编写以外, vue还专门提供了一个编写模板的标签template。

	<template id="info">
	<div>
		<img src="images/fm.jpg"/>
		<p>我是描述信息</p>
		<button @click="abcFn">我是按钮</button>
		<p>{{abcMsg}}</p>
	</div>
	</template>

② 注册组件
在注册组件的时候, 除了传入一个组件构造器以外, 还可以直接传入一个对象。

	Vue.component("abc", {
	// 注意点: 在创建组件指定组件的模板的时候, 模板只能有一个根元素
		template: "#info",
		data: function () {
			return {
				abcMsg: "学院"
			}
		},
		methods: {
			abcFn(){
				alert("abcFn");
			}
		}
	});
	let vue = new Vue({
	el: '#app',
	// 实例中的data是一个对象,可直接保存数据
	data: {
		name: "xhl"
	},
	// 专门用于存储监听事件回调函数
	methods: {},
	// 专门用于定义计算属性的
	computed: {}
	});

③ 使用组件

	<div id="app">
		<!--// 3.3使用注册好的组件-->
		<abc></abc>
	</div>

2.自定义局部组件

(1)全局组件和局部组件的区别

全局组件:在任何一个Vue实例控制的区域中都可以使用
局部组件:只能在自定义的那个Vue实例控制的区域中可以使用

(2)创建局部组件

① 编写组件模板

	<template id="info">
	<div>
		<img src="images/fm.jpg"/>
		<p>我是描述信息</p>
	</div>
	</template>

② 在vue实例中创建组件

	let vue2 = new Vue({
	el: '#app2',
	// 专门用于定义局部组件的
	components: {
		"abc": {
			template: "#info"
		}
	}
	});

③ 局部使用组件

	<div id="app2">
		<abc></abc>
	</div>

3.切换组件(v-if)

	<div id="app">
		<button @click="toggle">切换</button>
		<home v-if="isShow"></home>
		<photo v-else></photo>
	</div>
	<template id="home">
		<div>
			<p>我是首页</p>
		</div>
	</template>
	<template id="photo">
		<div>
			<img src="images/fm.jpg" alt="">
		</div>
	</template>

自定义全局组件

	Vue.component("home", {
		template: "#home",
	});
	Vue.component("photo", {
		template: "#photo",
	});
	// 这里就是MVVM中的View Model
	let vue = new Vue({
		el: '#app',
		// 这里就是MVVM中的Model
		data: {
			isShow: true
		},
		// 专门用于存储监听事件回调函数
		methods: {
			toggle() {
				this.isShow = !this.isShow;
			}
		}
	});

4.动态组件

(1)动态组件格式:

	<component v-bind:is="需要显示组件名称"></component>

(2)为什么可以通过v-if切换还要有component

因为component可以配合keep-alive来保存被隐藏组件隐藏之前的状态。
示例:

<div id="app">
	<button @click="toggle">切换</button>
	<keep-alive>
		<component v-bind:is="name"></component>
	</keep-alive>
</div>
<template id="home">
	<div>
		<p>我是首页</p>
		<input type="checkbox">
	</div>
</template>
<template id="photo">
	<div>
		<img src="images/fm.jpg" alt="">
	</div>
</template>

自定义全局组件

	Vue.component("home", {
		template: "#home",
	});
	Vue.component("photo", {
		template: "#photo",
	});
	// 这里就是MVVM中的View Model
	let vue = new Vue({
		el: '#app',
		// 这里就是MVVM中的Model
		data: {
			name: "home"
		},
		// 专门用于存储监听事件回调函数
		methods: {
			toggle() {
				this.name = this.name === "home" ? "photo" : "home";
			}
		}
	});

5.组件动画

(1)如何给组件添加动画?

给组件添加动画和过去给元素添加动画一样,
如果是单个组件就使用transition,
如果是多个组件就使用transition-group。

(2)注意点

默认情况下进入动画和离开动画是同时执行的,
如果想一个做完之后再做另一个, 需要指定动画模式。

(3)示例

	<div id="app">
		<button @click="toggle">切换</button>
		<transition mode="out-in">
			<component v-bind:is="name"></component>
		</transition>
	</div>

6.父子组件

(1)父子组件格式

	<div id="app">
		<father></father>
	</div>
	<template id="father">
		<div>
			<p>我是父组件</p>
			<son></son>
		</div>
	</template>
	<template id="son">
		<div>
			<p>我是子组件</p>
		</div>
	</template>
	
	let vue = new Vue({
		el: '#app',
		data: {},
		methods: {},
		computed: {},
		// 专门用于定义局部组件的
		components: {
			"father": {
				template: "#father",
					components: {
						"son": {
							template: "#son"
						}
				}
			}
		}
	});

(2)父组件传递数据给子组件

① 在父组件中通过v-bind传递数据:
在用子组件的时候,v-bind:自定义接收名称 = “要传递数据”
② 在子组件中通过props接收数据:
在子组件中,props: [“自定义接收名称”]

	<template id="father">
		<div>
			<!--注意点: 组件是可以使用自己的数据的-->
			<p>{{name}}</p>
			<p>{{age}}</p>
			<!--这里将父组件的name通过parentname传递给了子组件-->
			<son :parentname="name" :abc="age"></son>
		</div>
	</template>
	<template id="son">
		<div>
			<!--这里通过parentname使用了父组件传递过来的数据-->
			<p>{{parentname}}</p>
			<p>{{abc}}</p>
		</div>
	</template>
	
	Vue.component("father", {  // 父组件
		template: "#father",
		data: function(){
			return {
				name: "lnj",
				age: 33
			}
		},
		components: {  // 子组件
			"son": {
				template: "#son",
				// 这里通过parentname接收了父组件传递过来的数据,然后可以直接使用
				props: ["parentname", "abc"]
			}
		}
	});

(3)父组件传递方法给子组件

① 在父组件中通过v-on传递方法
在用子组件的时候,@自定义接收名称 = “要传递方法”
② 在子组件中自定义一个方法,在自定义方法中通过 this.$emit(‘自定义接收名称’);
触发传递过来的方法。

	<template id="father">
		<div>
			<button @click="say">我是按钮</button>
			<!--这里通过parentsay将父组件的say方法传递给了子组件-->
			<son @parentsay="say"></son>
		</div>
	</template>
	<template id="son">
		<div>
			<button @click="sonFn">我是按钮</button>
		</div>
	</template>
	Vue.component("father", { // 父组件
		template: "#father",
		methods: {
			say(){
				alert("www.it666.com");
			}
		},
		components: { // 子组件
			"son": {
				template: "#son",
				methods: {
					//在子组件中自定义方法,调用该方法就触发父组件传过来的方法
					sonFn(){  
						this.$emit("parentsay");//触发父组件传过来的方法
					}
				}
			}
		}
	});

(4)子组件传递数据给父组件

① 父组件给子组件传递方法
② 子组件接收方法然后给父组件传递数据(return数据)
③ 父组件在传递的方法参数中接收到数据

	<template id="father">
		<div>
		<button @click="say">我是按钮</button>
		<son @parentsay="say"></son>
		</div>
	</template>
	<template id="son">
		<div>
		<button @click="sonFn">我是按钮</button>
		</div>
	</template>
	Vue.component("father", {
		template: "#father",
		methods: {
			say(data) {
				// alert("www.it666.com");
				console.log(data);  //子组件传递过来的数据
			}
		},
		components: {  // 子组件
			"son": {
				template: "#son",
				methods: {
					sonFn() {
						//触发父组件方法的同时向父组件传递参数
						// 第一个参数: 需要调用的函数名称
						// 后续的参数: 给调用的函数传递的参数
						this.$emit("parentsay", "知播渔");
					}
				}
			}
		}
	});

7.组件命名

(1)注册组件的时候使用了"驼峰命名", 那么在使用时需要转换成"短横线分隔命名",例如: 注册时: myFather -> 使用时: my-father。
(2)在传递参数的时候如果想使用"驼峰名称", 那么就必须写"短横线分隔命名"
传递时: parent-name=“name” -> 接收时: props: [“parentName”]。
(3)在传递方法的时候不能使用"驼峰命名", 只能用"短横线分隔命名"
@parent-say=“say” -> this.$emit(“parent-say”);

	<div id="app">
		<my-father></my-father>
	</div>
	<template id="father">
		<div>
			<p>{{name}}</p>
			<button @click="say">我是按钮</button>
			<son :parent-name="name" @parent-say="say"></son>
		</div>
	</template>
	<template id="son">
		<div>
			<p>{{parentName}}</p>
			<button @click="sonFn">我是按钮</button>
		</div>
	</template>
	
	Vue.component("myFather", {  // 父组件
		template: "#father",
		data: function(){
			return {
			name: "lnj"
			}
		},
		methods: {
			say(){
				console.log("www.it666.com");
			}
		},
		components: {  // 子组件
			"son": {
				template: "#son",
				props: ["parentName"],
				methods: {
					sonFn(){
						this.$emit("parent-say");
					}
				}
			}
		}
	});

8.特定组件缓存(新添加)

	<keep-alive include="Singer,Search">
	  <router-view></router-view>
	</keep-alive>

9.数据和方法的多级传递

在Vue中如果儿子想使用爷爷的数据和方法, 必须一层一层往下传递。

	<template id="grandfather">
		<div>
			<p>{{name}}</p>
			<button @click="say">我是按钮</button>
			<father :gfname="name" @gfsay="say"></father>
		</div>
	</template>
	<template id="father">
		<div>
			<p>{{gfname}}</p>
			<button @click="fatherFn">我是按钮</button>
			<son :fname="gfname" @fsay="fatherFn"></son>
		</div>
	</template>
	<template id="son">
		<div>
			<p>{{fname}}</p>
			<button @click="sonFn">我是按钮</button>
		</div>
	</template>
Vue.component("grandfather", {
	template: "#grandfather",
	data: function(){
		return {
			name: "lnj"
		}
	},
	methods: {
		say(){
			console.log("我是爷爷的方法");
		}
	},
	components: {
		"father": {
			template: "#father",
			props: ["gfname"],
			methods:{
				fatherFn(){
					this.$emit("gfsay");
				}
			},
			// 儿子组件
			components: {
				"son": {
					template: "#son",
					props: ["fname"],
					methods: {
						sonFn(){
							this.$emit("fsay");
						}
					},
				}
			}
		}
	}
});

10.插槽

(1)插槽

默认情况下使用子组件时在子组件中编写的元素是不会被渲染的,如果我们想在使用子组件中在子组件中编写元素,那么我们就可以使用插槽,插槽就是在子组件中放一个"坑", 以后由父组件来"填"。

(2)匿名插槽

没有指定名称的插槽, 会利用使用时指定的内容替换整个插槽。
匿名插槽默认为default。
注意点: 插槽可以指定默认数据, 如果使用者没有填这个坑, 那么就会显示默认数据。
如果使用者填了这个坑, 那么就会利用使用者填坑的内容替换整个插槽。
如果有多个匿名插槽,有多少个匿名插槽, 填充的数据就会被拷贝几份,每一个匿名插槽都会被指定的内容替换。
虽然写多个匿名插槽不会报错, 但是在企业开发中不推荐使用多个匿名插槽。

	<template id="father">
		<div>
			<!--需求: 在使用子组件的时候给子组件动态的添加一些内容-->
			<son>
				<div>我是追加的内容1</div>
				<div>我是追加的内容2</div>
				<div>我是追加的内容3</div>
			</son>
		</div>
	</template>
	<template id="son">
		<div>
			<div>我是头部</div>
			<!-- 有填坑显示填坑内容,没有填坑显示默认数据 -->
			<slot>我是默认数据</slot>
			<div>我是底部</div>
		</div>
	</template>
	
	Vue.component("father", {
		template: "#father",
		// 子组件
		components: {
			"son": {
			template: "#son",
			}
		}
	});

(3)具名插槽(slot=“name”)

通过插槽的name属性给插槽指定名称,在使用时可以通过slot="name"方式, 指定当前内容用于替换哪一个插槽。如果没有指定要替换哪个插槽中的内容, 则不会被替换。

	<template id="father">
		<div>
			<son>
				<!--这里通过slot属性告诉Vue,
				当前的内容是要填充到哪一个插槽中的-->
				<div slot="one">我是追加的内容1</div>
				<div slot="one">我是追加的内容11</div>
				<div slot="two">我是追加的内容2</div>
				<div slot="two">我是追加的内容22</div>
			</son>
		</div>
	</template>
	<template id="son">
		<div>
			<div>我是头部</div>
			<slot name="one">我是默认内容</slot>
			<slot name="two">我是默认内容</slot>
			<div>我是底部</div>
		</div>
	</template>
	
	Vue.component("father", {  // 父组件
		template: "#father",
		// 子组件
		components: {
			"son": {
				template: "#son",
			}
		}
	});

(4)v-slot(#)

v-slot指令是Vue2.6中用于替代slot属性的一个指令,
在Vue2.6之前, 我们通过slot属性告诉Vue当前内容填充到哪一个具名插槽,
从Vue2.6开始, 我们通过v-slot指令告诉Vue当前内容填充到哪一个具名插槽。
我们除了可以通过v-slot指令告诉Vue内容要填充到哪一个具名插槽中,
还可以通过v-slot指令告诉Vue如何接收作用域插槽暴露的数据。
注意点: v-slot指令只能用在template标签上
可以使用#号替代v-slot;
简写字符:

	v-bind: : 
	v-on: @ 
	v-slot:#

v-slot指令告诉Vue内容要填充到哪一个具名插槽中示例:

	<template id="father">
		<div>
			<son>
				<template v-slot:one>
					<div>我是追加的内容1</div>
					<div>我是追加的内容11</div>
				</template>
				<template v-slot:two>
					<div>我是追加的内容2</div>
					<div>我是追加的内容22</div>
				</template>
				<!-- 简写 -->
				<template #one>
					<div>我是追加的内容1</div>
					<div>我是追加的内容11</div>
				</template>
				<template #two>
					<div>我是追加的内容2</div>
					<div>我是追加的内容22</div>
				</template>
			</son>
		</div>
	</template>
	<template id="son">
		<div>
			<div>我是头部</div>
			<slot name="one">我是one默认内容</slot>
			<slot name="two">我是two默认内容</slot>
			<div>我是底部</div>
		</div>
	</template>
	<script>
	// 父组件
	Vue.component("father", {
		template: "#father",
		// 子组件
		components: {
			"son": {
				template: "#son",
			}
		}
	});

v-slot指令告诉Vue如何接收作用域插槽暴露的数据:v-slot:插槽名称=“作用域名称”

	<template id="father">
		<div>
			<son>
				<template slot-scope="abc">
					<li v-for="(name, index) in abc.names">{{name}}</li>
				</template>
				//匿名插槽默认为default.
				<template v-slot:default="abc">
					<li v-for="(name, index) in abc.names">{{name}}</li>
				</template>
				<template #default="abc">
					<li v-for="(name, index) in abc.names">{{name}}</li>
				</template>
				<template #one="abc">
					<li v-for="(name, index) in abc.names">{{name}}</li>
				</template>
			</son>
		</div>
	</template>
	<template id="son">
		<div>
			<div>我是头部 {{names}}</div>
			<slot name="one" v-bind:names="names">
			我是默认内容 {{names}}</slot>
			<div>我是底部</div>
		</div>
	</template>
	
	// 父组件
	Vue.component("father", {
		template: "#father",
		// 子组件
		components: {
			"son": {
				template: "#son",
				data: function () {
					return {
						names: ["zs", "ls", "ww", "zl"]
					}
				}
			}
		}
	});

(5)作用域插槽(slot-scope)

作用域插槽就是带数据的插槽, 就是让父组件在填充子组件插槽内容时也能使用子组件的数据。
应用场景: 子组件提供数据, 父组件决定如何渲染。
如何使用作用域插槽:
在slot中通过 v-bind:数据名称=“数据名称” 方式暴露数据
在父组件中通过 接收数据
在父组件的中通过作用域名称.数据名称方式使用数据。

<template id="father">
	<div>
		<son>
			<!-- 自定义作用域名称,接收子组件插槽暴露的数据 -->
			<template slot-scope="abc">
				<!-- 利用作用域名称.数据名称使用子组件传递过来的数据 -->
				<li v-for="(name, index) in abc.names">{{name}}</li>
			</template>
		</son>
	</div>
</template>
<template id="son">
	<div>
		<div>我是头部 {{names}}</div>
		<!-- 将当前子组件的names数据暴露给父组件 -->
		<slot v-bind:names="names">我是默认内容 {{names}}</slot>
		<div>我是底部</div>
	</div>
</template>

Vue.component("father", {  // 父组件
	template: "#father",
	// 子组件
	components: {
		"son": {
			template: "#son",
			data: function () {
				return {
					names: ["zs", "ls", "ww", "zl"]
				}
			}
		}
	}
});
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vue2-svg-icon 是一个 Vue.js 的 SVG 图标组件,可以用于快速加载和使用 SVG 图标。以下是使用步骤: 1. 安装 vue2-svg-icon 可以使用 npm 或 yarn 进行安装: ```bash npm install vue2-svg-icon --save ``` 或者 ```bash yarn add vue2-svg-icon ``` 2. 引入组件 在你的 Vue.js 组件中引入 vue2-svg-icon: ```js import SvgIcon from 'vue2-svg-icon' Vue.component('svg-icon', SvgIcon) ``` 3. 使用组件 在模板中使用 `svg-icon` 标签,并指定 `icon` 属性为对应的图标名称: ```html <svg-icon icon="arrow-up"></svg-icon> ``` 其中 `arrow-up` 是图标的名称,具体的图标名称需要查看你所使用的 SVG 图标库。 4. 配置 SVG 图标库 vue2-svg-icon 默认使用的是 [icomoon](https://icomoon.io/) 的 SVG 图标库,你可以在 `SvgIcon` 组件中通过 `set` 方法来配置使用其他的 SVG 图标库。 例如,如果你想使用 [fontawesome](https://fontawesome.com/) 的 SVG 图标库,可以这样配置: ```js import SvgIcon from 'vue2-svg-icon' import { library } from '@fortawesome/fontawesome-svg-core' import { faCoffee } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' library.add(faCoffee) Vue.component('font-awesome-icon', FontAwesomeIcon) SvgIcon.set({ name: 'fontawesome', classPrefix: 'fa-', classSuffix: '', defaultWidth: '1em', defaultHeight: '1em' }) ``` 这里我们使用了 `@fortawesome/fontawesome-svg-core` 和 `@fortawesome/free-solid-svg-icons` 来引入 fontawesome 的 SVG 图标库,并且配置了 `SvgIcon` 组件使用 `fontawesome` 图标库,并指定了图标的 class 前缀为 `fa-`,这样我们就可以在模板中使用 `fa-coffee` 这个图标了: ```html <svg-icon icon="fa-coffee"></svg-icon> ``` 更多关于 vue2-svg-icon 的使用方法,可以参考它的官方文档:https://github.com/cenkai88/vue-svg-icon#readme

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值