zoukankan      html  css  js  c++  java
  • Vue.js组件理解

    组件使用细节点

    解决元素标签位置错误的问题:is 属性

    <div id="app">
    	<table>
    		<tbody>
    			<!--tbody里要用一个组件,但不能直接写组件名
    				会导致位置错误问题,使用 is 属性将自定义组件row
    				与 tr 标签绑定在一起
    			-->
    			<tr is='row'></tr>
    			<tr is='row'></tr>
    			<tr is='row'></tr>
    		</tbody>
    	</table>
    	
    		<ul>
    			<li is='row'></li>
    			<li is='row'></li>
    			<li is='row'></li>
    		</ul>
    </div>
    
    <script>
    	
    	Vue.component('row', {
    		template: '<tr><td>this is a row</td></tr>'
    	});
    	
    	var vm = new Vue({
    		el: "#app"
    	});
    	
    </script>
    

    组件data函数

    在子组件中,data 必须是一个函数,有可能一个子组件会被调用很多次,每个子组件数据不能产生冲突,通过一个函数返回一个对象的目的,就是让每个子组件都拥有独立的数据存储。

    Vue.component('row', {
    	//在子组件中,data 必须是一个函数
    	data: function(){
    		return {
    			content: 'this is a row'
    		}
    	},
    	template: '<tr><td>{{content}}</td></tr>'
    });
    

    ref的使用

    <div id="app">
    	<counter ref="one" @change="handleChange"></counter>
    	<counter ref="two" @change="handleChange"></counter>
    	<div>{{total}}</div>
    </div>
    
    <script>
    	
    	Vue.component('counter',{
    		template: '<div @click="handleClick">{{number}}</div>',
    		data: function(){
    			return {
    				number: 0
    			}
    		},
    		methods: {
    			handleClick: function() {
    				this.number ++;
    				// $emit() 自定义事件向父组件通信
    				this.$emit('change');
    			}
    		}
    	});
    	
    	var vm = new Vue({
    		el: "#app",
    		data: {
    			total: 0
    		},
    		methods: {
    			handleChange: function() {
    				//可以使用自加一方法
    				//this.total++;
    				//也可以求二者之和
    				// 通过 $refs 获取子组件的引用,再获取数据
    				this.total = this.$refs.one.number + this.$refs.two.number;
    			}
    		}
    	});
    

    父子组件的数据传递

    父组件通过属性的形式向子组件传递数据

    Vue 中的单项数据流:父组件可以向子组件传递参数,该参数在父组件可随便修改,子组件绝对不能反过来去修改父组件传递过来的参数,只用不改

    <div id="app">
    	<!--父往子传递-->
    	<!--父组件通过绑定属性的形式向子组件传递数据-->
    	<counter :count="3" @inc="handleIncrease"></counter>
    	<counter :count="2" @inc="handleIncrease"></counter>
    	
    	<!--子往父传递-->
    	<!--子组件通过事件触发的形式向父组件传递数据-->
    	<div>{{total}}</div>
    </div>
    
    <script>
    	var counter = {
    		props: ['count'],
    		data: function() {
    			return {
    				//定义一个number 把获取来的数据克隆一个传进去
    				number: this.count
    			}
    		},
    		template: '<div @click="handleClick">{{number}}</div>',
    		methods: {
    			handleClick: function() {
    				this.number += 2;
    				//子组件通过点击将事件触发出去
    				this.$emit('inc', 2)
    			}
    		}
    	}
    	var vm = new Vue({
    		el: "#app",
    		components: {
    			counter: counter
    		},
    		data: {
    			total: 5
    		},
    		methods: {
    			// 父组件执行的函数里可以直接接收到 $emit()的参数
    			handleIncrease: function(step) {
    				this.total += step;
    			}
    		}
    	});
    

    组件参数校验与非props特性

    <div id="app">
    	<child :content="123"></child>
    </div>
    
    <script>
    	
    	Vue.component('child',{
    		props: {
    			//设定子组件接收的content 属性,
    			//	要么是数字,要么是字符串
    			content: [String, Number]
    			/*
    			也可以这样写:
    			content: {
    				//类型
    				type: String,
    				
    				//设定这个属性是必须的
    				required: true,
    				
    				//如果不给default 传数值,默认default
    				default: 'default value',
    				
    				//对传入 content属性 添加校验
    				//规定长度必须大于5
    				validator: function(value) {
    					return (value.length > 5)
    				}
    			}
    			*/
    		},
    		template: '<div>{{content}}</div>'
    	})
    	
    	var vm = new Vue({
    		el: "#app"
    	});
    	
    

    props 特性:
    父组件传递了content 子组件又声明了一个content接收; 二者有一个对应关系。该属性不会在DOM中出现,子组件可直接通过插值表达式调用content内的内容。

    非props 特性
    父组件传递一个属性,但是子组件并没有props的内容,没有声明,无法获取父组件内容。该属性会在子组件DOM中出现

    给组件绑定原生事件

    <div id="app">
    	<!--
    		加native修饰符,监听原生点击事件,
    		方法同子组件设置自定义事件向父组件触发
    	-->
    	<child @click.native='handleClick'></child>
    </div>
    
    <script>
    	Vue.component('child',{
    		template: '<div>child</div>'
    	})
    	var vm = new Vue({
    		el: "#app",
    		methods: {
    			handleClick: function() {
    				alert('click')
    			}
    		}
    	});
    </script>
    

    非父子组件间的传值

    1. 借助官方的数据框架 vuex解决
    2. 发布订阅模式 总线机制 Bus 观察者模式
    <!--非父子组件传值
    	Bus / 总线 / 发布订阅模式 / 观察者模式
    -->
    <div id="app">
    	<!--点击一个,另一个变成相同的-->
    	<child content='anqw'></child>
    	<child content='joe'></child>
    </div>
    
    <script>
    	//每一个Vue 实例都会有bus 属性
    	Vue.prototype.bus = new Vue()
    	
    	Vue.component('child',{
    		data: function() {
    			return {
    				//父组件传过来的数据只能用不能改,
    				//所以需要拷贝一份
    				selfContent: this.content
    			}
    		},
    		props: {
    			content: String
    		},
    		template: '<div @click="handleClick">{{selfContent}}</div>',
    		methods: {
    			handleClick: function() {
    				//实例上挂载的bus ,这个bus 又是Vue 实例,
    				//所以会有$emit()方法,同时把内容传进参数
    				this.bus.$emit('change',this.selfContent);
    			}
    		},
    		//借助生命周期钩子,被挂载时执行
    		//$on 方法监听自定义事件
    		mounted: function() {
    			//固定this的指向
    			var this_ = this;
    			this.bus.$on('change', function(msg) {
    				this_.selfContent = msg
    			})
    		}
    	})
    	var vm = new Vue({
    		el: "#app"
    	});
    

    在Vue中使用插槽 slot

    <div id="app">
    	<child>
    		<!--插槽-->
    		<!--如果不传标签会显示默认内容-->
    		<h1>Anqw</h1>
    	</child>
    </div>
    
    <script>
    	Vue.component('child',{
    		//slot插槽中显示的是父组件插入的标签
    		template: '<div><p>hello</p><slot>默认内容</slot></div>'
    	})
    	var vm = new Vue({
    		el: "#app"
    	});
    	
    </script>
    

    将多个插槽一一对应

    <div id="app">
    	<body-content>
    		<div class="header" slot='header'>header</div>
    		<div class="footer" slot='footer'>footer</div>
    	</body-content>
    </div>
    
    <script>
    	Vue.component('body-content',{
    		//将插槽一一对应,用slot 与 name 属性绑定
    		template: `<div>
    						<slot name='header'></slot>
    						<div class="content">
    							content
    						</div>
    						<slot name='footer'></slot>
    					</div>`
    	});
    	var vm = new Vue({
    		el: "#app"
    	});
    	
    </script>
    <!--
    	显示结果:
    	header
    	content
    	footer
    -->
    

    Vue 中的作用域插槽

    <div id="app">
    	<child>
    		<!--首先父组件内传了一个插槽,
    			作用域插槽,必须用 template 标签包裹,
    			同时声明从子组件接收的数据都放在props中,
    			slot-scope 对应的属性名接收到数据后,
    			以li的形式进行展示.
    		-->
    		<template slot-scope="props">
    			<!--由父组件传递循环对应的模板-->
    			<li>{{props.item}} - hello</li>
    		</template>
    	</child>
    </div>
    
    <script>
    	Vue.component('child',{
    		data: function() {
    			return {
    				list: [1,2,3,4]
    			}
    		},
    		//当子组件做循环,DOM结构需要由外部传递时
    		template: `<div>
    						<ul>
    							<slot 
    								v-for="item of list" 
    								:item="item">
    							</slot>
    						</ul>
    					</div>`
    	});
    	var vm = new Vue({
    		el: "#app"
    	});
    	
    </script>
    

    动态组件与v-once指令

    <div id="app">
    	<!--动态组件-->
    	<!--会根据 is 中数据的变化去加载不同的组件-->
    	<!--<component :is="type"></component>-->
    	
    	<child-one v-if="type === 'child-one'"></child-one>
    	<child-two v-if="type === 'child-two'"></child-two>
    	
    	<button @click="handleClick">change</button>
    	
    	<!--当点击button时 两个组件 toggle显示-->
    </div>
    
    <script>
    	Vue.component('child-one',{
    		// v-once 可以把组件暂时放到内存里,
    		//	点击之后直接从内存里取出就行,提高了性能
    		template: '<div v-once>child-one</div>'
    	});
    	Vue.component('child-two',{
    		template: '<div v-once>child-two</div>'
    	});
    	var vm = new Vue({
    		el: "#app",
    		data: {
    			type: 'child-one'
    		},
    		methods: {
    			handleClick: function() {
    				this.type = (this.type === 'child-one'?
    					'child-two': 'child-one');
    			}
    		}
    	});
    </script>
    
  • 相关阅读:
    Android OpenGL ES 2.0 (四) 灯光perfragment lighting
    Android OpenGL ES 2.0 (五) 添加材质
    冒泡排序函数
    javascript object 转换为 json格式 toJSONString
    Liunx CentOS 下载地址
    jquery 图片切换特效 鼠标点击左右按钮焦点图切换滚动
    javascript 解析csv 的function
    mysql Innodb Shutdown completed; log sequence number解决办法
    Centos 添加 yum
    javascript 键值转换
  • 原文地址:https://www.cnblogs.com/anqwjoe/p/9053431.html
Copyright © 2011-2022 走看看