vue基础(2):深入理解 Vue 组件、Vue中的动画特效

文章目录

一、深入理解 Vue 组件

1.1 使用组件容易遇到的坑

总结一些组件再使用时容易遇到的坑:

1.1.1 使用is='组件名'解决html表签嵌套规范造成的bug

html嵌套规范,会造成bug的标签有table、ul(有的浏览器会)、select等

	<div id="app">
		<table>
			<tbody>
				<row></row>
				<row></row>
				<row></row>
				<row></row>
			</tbody>
		</table>		
	</div>
	<script type="text/javascript">
		Vue.component('row',{
    
			template: '<tr><td>这是表格</td></tr>',
		});
		var vm = new Vue({
    
			el: '#app',
		});
	</script>

<tr>标签被渲染到<table>外面了。
在这里插入图片描述

解决方案
	<div id="app">
		<table>
			<tbody>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
			</tbody>
		</table>		
	</div>
	<script type="text/javascript">
		Vue.component('row',{
    
			template: '<tr><td>这是表格</td></tr>',
		});
		var vm = new Vue({
    
			el: '#app',
		});
	</script>



1.1.2 非根组件(子组件)中data必须是函数,返回一个对象。

子组件不像是根组件只会有一个,既然注册了子组件就是想要复用,为了保证每一个子组件数据的唯一性,避免多个子组件数据共享,通过函数将数据存在到独立的函数作用域中。

    <div id="app">
        <table>
            <tbody>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
            </tbody>
        </table>
    </div>
    <script type="text/javascript">
    Vue.component('row', {
    
        template: "<tr><td @click='addNum'>{
    {num}}</td></tr>",
        data: function() {
    
            return {
    
                num: 0,
            };
        },
        methods: {
    
            addNum: function() {
    
                this.num++;
            },
        }
    });
    var vm = new Vue({
    
        el: '#app',
    });
    </script>



1.1.3 使用引用ref="引用名"获取dom元素和组件引用

虽然使用vue我们只需要关心数据,不用操作dom。但是复杂的动画就不要指望vue,还是要使用dom。

1.使用ref获取dom元素

  • 通过在html标签上加ref="xxx"属性,可通过this.$refs.xxx取得该dom节点
    <div id="app">
		<div ref="hello" @click="getDom">{
  {message}}</div>
    </div>
    <script type="text/javascript">
    var vm = new Vue({
    
        el: '#app',
        data: {
    
        	message: ' hello poorpenguin',
        },
        methods: {
    
        	getDom: function(){
    
        		console.log(this.$refs.hello);
        	}
        }
    });
    </script>

在这里插入图片描述

2.使用ref获取组件引用

  • 组件上添加了ref属性,可以取得的是该组件的引用(也可以理解为该组件对象),因此可以访问该组件上的属性
这只是举个例子,并不推荐这样写
	<div id="app">
		<row ref="numOne" @numchange="changeTotal"></row>
		&nbsp;&nbsp;+&nbsp;&nbsp;
		<row ref="numTwo" @numchange="changeTotal"></row>
		&nbsp;&nbsp;=&nbsp;&nbsp;{
  {total}}
    </div>
    <script type="text/javascript">
   		Vue.component('row',{
    
   			template: '<span @click="addNum">{
    {number}}</span>',
   			data: function(){
    
   				return {
    
   					number: 0,
   				};
   			},
   			methods: {
    
   				addNum: function(){
    
   					this.number++;
   					this.$emit('numchange');
   				}
   			}
   		});

	    var vm = new Vue({
    
	        el: '#app',
	        data: {
    
	        	total: 0,
	        },
	        methods: {
    
	        	changeTotal: function(){
    
	        		this.total = this.$refs.numOne.number + this.$refs.numTwo.number;
	        	}
	        }

	    });
    </script>

两个组件对象。
在这里插入图片描述
在这里插入图片描述


1.1.4 子组件的单个根元素

当子组件的模板template中有多个dom元素的时候,要使用一个元素将他们包裹起来。每个组件必须只有一个根元素,所有要将模板的内容包裹在一个父元素内。

		模板中这样写是会报错的。
		var counter = {
   
			props: ['count'],
			template: '<span>123123</span><h1>poorpenguin</h1><div>{
   {count}}</div>',
		};
		
		这样式正确的写法
		var counter = {
   
			props: ['count'],
			template: '<div><span>123123</span><h1>poorpenguin</h1><div>{
   {count}}</div></div>',
		};



1.2 父子组件间的数据传递

1.2.1 父组件传值给子组件

  1. 父组件通过 属性形式 传值给子组件(不一定要使用v-bind将属性和根组件中的变量绑定)

不使用指令v-bind,直接使用属性进行传值。但是这样" "中的就不是js表达式,子组件接收到的就是字符串

	<div id="app">
		<counter count="3"></counter>
	</div>
	<script type="text/javascript">
		var counter = {
    
			props: ['count'],
			template: '<div>{
    {count}}</div>',
		};
		var vm = new Vue({
    
			el: '#app',
			components: {
    
				'counter': counter,
			}
		});
	</script>

使用指令v-bind,就可以将属性和根组件中的变量进行绑定,这时" "中就是js表达式,也可以直接传递数字。

	<div id="app">
		<counter :count="num1"></counter>	这里使用v-bind命令
		或者<counter :count="3"></counter>	这样传递的也是数字,而不是字符串
	</div>
	<script type="text/javascript">
		var counter = {
    
			props: ['count'],
			template: '<div>{
    {count}}</div>',
		};
		var vm = new Vue({
    
			el: '#app',
			data: {
    
				num1: 3,
			},
			components: {
    
				'counter': counter,
			}
		});
	</script>
  1. 子组件通过props[]接收传递过来的属性,但是不能直接操作接收的属性

子组件通过props[]接收传递过来的属性,并将传递过来的属性赋值给在data中定义新属性。
因为单项数据流,修改Object的值会导致别的引用了该对象的子组件内数据的变化,用在子组件内复制一份该对象,修改子组件内自己的data来代替。

	<div id="app">
		<counter :count="num1"></counter>
	</div>
	<script type="text/javascript">
		var counter = {
    
			props: ['count'],
			data: function(){
    
				return {
    
					number: this.count,
				};
			},
			template: '<div @click="addNum">{
    {number}}</div>',
			methods: {
    
				addNum: function(){
    
					this.number++
				},
			}
		};
		var vm = new Vue({
    
			el: '#app',
			data: {
    
				num1: 3,
			},
			components: {
    
				'counter': counter,
			}
		});
	</script>

错误示范:

	子组件
		var counter = {
   
			props: ['count'],
			template: '<div @click="addNum">{
   {count}}</div>',
			methods: {
   
				addNum: function(){
   
					this.count++
				},
			}
		};



1.2.2 子组件传值给父组件

  1. 子组件事件触发的形式this.$emit("自定义事件名","传给父组件的数据"),向父组件传值
		var counter = {
   
			props: ['count'],
			data: function(){
   
				return {
   
					number: this.count,
				};
			},
			template: '<div @click="add
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值