Vue 组件的使用

一、基础组件

当Vue实例中出现了el 和 template 两个属性时,template的优先级大于el。Vue中组件的名字首字母要大写。

1.1、子组件基本用法

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Vue 组件的基本使用</title>
</head>
<body>
	<div id="app">
		<!-- 3.2使用子组件 -->
		<!-- <App /> -->
	</div>
	<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	<script>
		// 1、声明子组件
		let App = {
			data(){
				return {
					name:'Jsom'
				}
			},
			template:`
				<div>
					<h2>{{ name }}</h2>
				</div>
			`
		}
		let vm = new Vue({
			el:'#app',
			data(){
				return {
					msg:'Vue'
				}
			},
			// 3.1、使用子组件,不用template可以直接在父组件中使用子组件
			template:`<App />`,
			// 2、通过 components 属性把子组件挂载到父组件中 
			components:{
				App
			}
		})
	</script>
</body>
</html>

1.2、Vue.component(’’,{}) 声明全局组件

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>component 声明全局组件</title>
</head>
<body>
	<div id="app"><heade></heade></div>
	<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	<script>
		Vue.component('heade',{
			data:function (){
				return {
					name:'Head'
				}
			},
			template:'<div>{{ name }}</div>'
		})
		let vm = new Vue({el:'#app'})
	</script>
</body>
</html>

PS:定义组件名的时候千万不能与HTML标签名冲突。

1.3、props 父子组件传值

父组件给子组件传值方法:

  1. 声明props,将父组件要传入子组件的值通过props挂载到子组件
  2. 父组件在使用子组件时,通过 v-bind 将父组件要传给子组件的值绑定到子组件标签上。
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>父组件给子组件传值</title>
</head>
<body>
	<div id="app"></div>
	<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js'></script>
	<script>
		// 将父组件的 msg 传入子组件中
		// 子组件
		let App = {
			data(){
				return {
					name:'我是子组件'
				}
			},
			// 1、声明props,将父组件要传入子组件的值通过props挂载到子组件
			// PS:props声明的值,必须与父组件传输值的名称相同。
			props:['msg','obj'],
			template:`
				<div>
					<h2>{{ name }}</h2>
					<!--使用父组件传入的值。-->
					<h3>{{ msg }}</h3>
					<h4>{{ obj.age }}</h4>
				</div>
			`
		}

		// 父组件
		let vm = new Vue({
			el:'#app',
			data(){
				return {
					msg:'父组件给子组件的值',
					obj:{
						age:30
					},
					style:{
						style:'color:red'
					}
				}
			},
			// 2、父组件在使用子组件时,通过 v-bind 将父组件要传给子组件的值绑定到子组件标签上。
			// :msg 表示 props 中的值,='msg' 表示父组件传给子组件的值
			// 3、给子组件标签传入父组件的值。使用v-bind 把父组件要传的值绑定到子组件标签上。
			template:`<App :msg = 'msg' :obj = 'obj' v-bind = 'style' />`,
			components:{
				App
			}
		})
	</script>
</body>
</html>

结果:
在这里插入图片描述
子组件给父组件传值方法:

1. 父组件通过在子组件标签上绑定自定义事件和事件处理函数。
2. 在子组件中创建函数,通过该函数运行 e m i t 3. V u e emit方法给父组件传值。 3. 通过Vue提供的 emit方法将子组件的值传给父组件。
4. 通过自定义事件处理函数接收子组件传过来的值。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>父组件给子组件传值</title>
</head>
<body>
	<div id="app">
		<h2>{{ msg }}</h2>
	</div>
	<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js'></script>
	<script>
		// 将子组件的 name 传入父组件中
		let App = {
			data(){
				return {
					name:'我是子组件',
					obj:{
						age:25
					}
				}
			},
			props:['msg'],
			template:`
				<div>
					<h2 @click='childData'>{{ name }}</h2>
					<h3>{{ msg }}</h3>
				</div>
			`,
			methods:{
				// 2、在子组件中创建函数,通过该函数运行$emit方法给父组件传值。
				childData(){
					// 3、通过Vue提供的$emit方法将子组件的值传给父组件。
					// PS:$emit 第一个值为父组件绑定的自定义事件名称,第二个值为要传的值。
					this.$emit('fatherEven',this.obj.age);
				}
			}
		}


		// 父组件
		let vm = new Vue({
			el:'#app',
			data(){
				return {
					msg:'父组件给子组件的值'
				}
			},
			methods:{
				// 4、通过自定义事件处理函数接收子组件传过来的值。
				// PS:val为子组件传过来的值。
				fatherData(val){
					this.msg = val;
				}
			},
			template:`
				<div>
					<h2>{{ msg }}</h2>
					<!-- 1、父组件通过在子组件标签上绑定自定义事件和事件处理函数。 -->
					<App @fatherEven = 'fatherData' :msg = 'msg'/>
				</div>
			`,
			components:{
				App
			}
		})
	</script>
</body>
</html>

结果:
在这里插入图片描述
平行组件传值方法:

这种传值方法可以取代上面两种传值方法,更加简便的实现传值的需求。
Test 需要通过 $on() 声明这个事件,而App则通过 $emit() 来调用Test声明的事件。
PS:

  1. $on $emit 必须绑定在同一个示例对象中。
  2. 需要注意的是 $on 中this的指向问题,由于对象中的传统函数是谁调用this就指向谁,所以需要通过箭头函数改变this指向组件对象。
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>平行组件传值</title>
</head>
<body>
	<div id="app">
		
	</div>
	<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js'></script>
	<script>
		var bus = new Vue();
 		// 子组件App 给 组件Test 传值 
 		// Test 需要通过$on()声明这个事件,而App则通过$emit() 来调用Test声明的事件。
 		// PS:1、$on $emit 必须绑定在同一个示例对象中。
 		// 	   2、需要注意的是 $on 中this的指向问题,由于对象中的传统函数是谁调用this就指向谁,
 		// 		  所以需要通过箭头函数改变this指向组件对象。
		Vue.component('Test',{
			data(){
				return {
					text:''
				}
			},
			template:`
				<div>
					{{ text }}
				</div>
			`,
			methods:{
				
			},
			created(){
				// 1、Test 需要通过$on()声明这个事件。
				// 为什么这里的箭头函数中的this指向的组件对象?
				// 这里 bus.$on() 调用其内部匿名函数时,箭头函数指向当前调用该函数上文关系中的父对象。
				// bus.$on('',()=>{console.log(this)}) -> 上文关系 created() 函数的父对象 -> Vue.component('Test')。
				bus.$on('appData2',(val)=>{
					// 3、把传过来的值设置到接收组件中。
					this.text = val;
				});
			}
		})
		let App = {
			data(){
				return {
					name:'我是子组件App'
				}
			},
			template:`
				<div>
					<h2 @click='appData'>{{ name }}</h2>
				</div>
			`,
			methods:{
				// 2、App通过$emit() 来调用Test声明的事件。
				appData(){
					bus.$emit('appData2',this.name);
				}
			}
		}


		// 父组件
		let vm = new Vue({
			el:'#app',
			data(){
				return {
					msg:'父组件给子组件的值'
				}
			},
			methods:{
			},
			template:`
				<div>
					<App />
					<Test />
				</div>
			`,
			components:{
				App
			}
		})
	</script>
</body>
</html>

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

二、filter 过滤器

2.1、过滤器的使用

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>过滤器的使用</title>
</head>
<body>
	<div id="app"><heade></heade></div>
	<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	<script src="http://momentjs.cn/downloads/moment.js"></script>
	<script>
		// 定义全局过滤器
		Vue.filter('myStr',function(val){
			return val.split('').reverse().join('')
		})
		Vue.component('heade',{
			data:function (){
				return {
					name:'Head',
					time:new Date()
				}
			},
			template:`<div>
				<h1>过滤器的使用方法</h1>
				<h2>{{ name|myStr }}</h2>
				<div>{{ time|myTime("YYYY-MM-DD") }}</div>
			</div>`,
			// 定义局部过滤器
			filters:{
				myTime(val,t){
					return moment(val).format(t)
				}
			}
		})
		let vm = new Vue({
			el:'#app'
		})
	</script>
</body>
</html>

三、生命周期和钩子函数

	beforeCreate			          
	created					--> *组件创建完成,发送ajax获取后台数据。
	beforeMount
	mounted					--> *组件挂载完成,DOM 渲染完成,可以进行DOM操作。 
	beforeUpdate			
	updated					--> 修改DOM完成。
	activated				--> 组件激活时调用,搭配 keep-alive 组件标签使用。
	deactivated				--> 组件停用时调用,搭配 keep-alive 组件标签使用。
	beforeDestroy			--> 销毁组件前。
	destroyed				--> 已经销毁组件,定时器销毁一般在这个函数中处理。
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>生命周期和钩子函数</title>
</head>
<body>
	<div id="app">
		<keep-alive>
			<heade v-if='show'></heade>
		</keep-alive>
		<button @click="isshow">修改DOM</button>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
	<script>
		Vue.component('heade',{
			data:function (){
				return {
					name:'Head',
				}
			},
			template:`<div>
				<h2>{{ name }}</h2>
			</div>`,
			created(){
				console.log('创建组件完成!')
			},
			mounted(){
				console.log('组件更新完成!')
			},
			activated(){
				console.log('激活组件!')
			},
			deactivated(){
				console.log('停用组件!')
			}
		})
		let vm = new Vue({
			el:'#app',
			data(){
				return{
					show:true
				}
			},
			methods:{
				isshow(){
					this.show = !this.show;
				}
			},
		})
	</script>
</body>
</html>

四、refs属性获取原生DOM

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:

<input ref="input">
this.$refs.input.focus()
<child-component ref="child"></child-component>
this.$refs.child.focus()

五、模块系统

5.1、文件结构

<template>
    <div>
     <app-header></app-header>
   </div>
</template>

<style>
...
</style>

<script>
   import AppHeader from './AppHeader.vue'
    export default {
     name:'app',
     props:['data']
     data() {
        return {}
       },
     methods: {
     },
     components: {
       AppHeader
     }
   }
</script>
template 里是模板代码,这里一般是一个闭合的html标签,比如一个div。

style 里是css代码,这个代码是作用到整个页面的,如果只想作用到当前的模板中,需要用scoped属性

<style scoped>

如果想用一些css预处理器,比如sass,只需要声明lang,然后vue-loader就会自动的加载,当然,前提是对应的 sass-loader安装好。

<style lang="sass">

script 注意这里使用的是 es6 的代码,可以使用babel来编译,所以理所当然需要安装 babel,es6的preset,还要在根目录下自建 .babelrc 文件。具体可以参考官方的 vue-cli 来初始化项目。

猜你喜欢

转载自blog.csdn.net/u011146423/article/details/88739433