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>
    
  • 相关阅读:
    【Python入门 】—— 关于Numpy的使用
    CSP 201512 | 201604考试题目
    【Python入门】 —— 用pycharm写7道简单的PTA题目吧!
    【Python入门】 —— 用pycharm写两道超简单的PTA题目~
    Crypto.AES 报错 | TypeError: Object type <class 'str'> cannot be passed to C code
    windows安装Pytorch报错:from torch._C import * ImportError: DLL load failed: 找不到指定的模块”解决方案
    Python中的self通俗理解(自己理解的,自我感觉比官网解释要容易懂)
    python获取token数据
    python根据对象的实例获取对象的属性值
    oracle查询某个字段不为空的sql语句
  • 原文地址:https://www.cnblogs.com/anqwjoe/p/9053431.html
Copyright © 2011-2022 走看看