七天学完Vue之第三天学习笔记(组件的应用操作以及插槽的使用)

1.6. 第三天(组件的应用操作以及插槽的使用)

1.6.1. 组件
什么是组件:组件的出现, 就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功
能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:
+模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一- ;
+组件化:是从UI界 面的角度进行划分的;前端的组件化,方便UI组件的重用;
• 创建组件
注意template 里根标签只能有一个!
• 使用Vue.extend({temlate:…})创建
组件的名称使用驼峰式命名时,引用时应该使用 - 连接使用

<body>
		<div id="app">
			<my-com1>my-mom1>
		div>
		
		<script type="text/javascript">
			
			// 步骤一:使用Vue.extend来创建全局的Vue组件
			var com1 = Vue.extend({
				template: '

这是通过Vue.extend创建的组件

'
}) // 步骤二:使用Vue.component('组件的名称', 创建传来的组建的) 例子:Vue.component('my-com1', com1) var vm = new Vue({ el: '#app', data:{ }, methods:{ } });
script> body>

• 使用Vue.component(‘组件名’,对象)创建

<body>
		<div id="app">
			<my-com2>my-com2>
		div>
		
		<script type="text/javascript">
			// Vue.component('my-com2', Vue.extend({
			// 	template: '

我是第二种方法练习组件

'
// })) Vue.component('my-com2',{ template: '

我是第二种方法练习组件

'
}) var vm = new Vue({ el:'#app', data: { name: '贾真琦' }, methods:{ } });
script> body>

• 创建template标签(字面量类型的组件模板对象)

<body>
		<div id="app">
			<seven>seven>
		div>
		<template id="tmp1">
			<div>
				<p>篮球之神:p>
				<span>hahahspan>
			div>
		template>
		
		<script type="text/javascript">
			Vue.component('seven', {
				template: "#tmp1"
			})
			
			var vm = new Vue({
				el: '#app',
				data: {
					name: '贾真琦'
				},
				methods:{
					
				}
			}); 
		script>
	body>

• 创建私有组件

var vm = new Vue({
				el: '#app1',
				data: {
					name: '贾真琦'
				},
				methods:{
					
				},
				//定义私有组件
				components:{
					login: {
						template:'#temp2'
					}
				}
			}); 

使用省略方式

<body>
		<div id="app">
			
			<login>login>
		div>
		
		<script type="text/javascript">

			//模板对象
			var login = {
				template: '

我是第二种方法练习组件

'
} var vm = new Vue({ el:'#app', data: { name: '贾真琦' }, methods:{ }, //私有组件 components:{ login //直接用模板对象,调用时名字一致 } });
script> body>

• 组件中的data与methods
注意: 组件中的data 是一个函数返回对象,而实例中是一个对象
但是组件中方法和实例中的方法一样的

var duixiang = {msg:1}

			Vue.component('count', {
				template: '#tmp',
				data:function() {
					// return {msg: 1}
					return duixiang
				},
				methods:{
					add() {
						this.msg += 1
					}
				}
			})

• 组件切换
• v-if与v-else指令切换
主要功能代码:

代码示例:

<body>
		<div id="app">
			<input type="button" value="注册" @click="show1()"/>
			<input type="button" value="登录" @click="show2()"/>
			login>
			denglu>
		div>
		
		<template id="tem1">
			<div class="s1">
				<p>注册p>
				<div class="ss1">
					
				div>
			div>
		template>
		
		<template id="tem2">
			<div class="s1">
				<p>登录p>
				<div class="ss2">
					
				div>
			div>
		template>
		
		
		<script type="text/javascript">

			
			Vue.component('login', {
				template: '#tem1'
			})
			
			Vue.component('denglu', {
				template: '#tem2'
			})
			
			var vm = new Vue({
				el: '#app',
				data: {
					msg: true
				},
				methods:{
					show1(){
						this.msg = true;
					},
					show2(){
						this.msg = false;
					}
				}
			});
			
		script>
	body>

• 标签占位符加属性:is绑定组件名切换
主要实现手段 :
在 在app的范围内 添加 标签,并添加:is属性,通过点击按钮改变data里存放组件名的变量


<html>
	<head>
		<meta charset="utf-8">
		<title>v-if与v-else切换title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8">script>
		<style type="text/css">
			.s1 {
				width: 200px;
				height: 200px;
				background-color: #1B6D85;
			}
			
			.s1>p {
				height: 20px;
				text-align: center;
			}
			
			.s1>div {
				margin-left: 20px ;
				width: 160px;
				height: 150px;
			}
			
			.s1 .ss1 {
				background-color: #2B542C;
			}
			
			.s1 .ss2 {
				background-color: red;
			}
			
		style>
	head>
	<body>
		<div id="app">
			<input type="button" value="注册" @click="zujianname='login'"/>
			<input type="button" value="登录" @click="zujianname='denglu'"/>
			<component :is="zujianname">component>
		div>
		
		<template id="tem1">
			<div class="s1">
				<p>注册p>
				<div class="ss1">
					
				div>
			div>
		template>
		
		<template id="tem2">
			<div class="s1">
				<p>登录p>
				<div class="ss2">
					
				div>
			div>
		template>
		
		
		<script type="text/javascript">

			
			Vue.component('login', {
				template: '#tem1'
			})
			
			Vue.component('denglu', {
				template: '#tem2'
			})
			
			var vm = new Vue({
				el: '#app',
				data: {
					zujianname: 'login'
				}
			});
			
		script>
	body>
html>

• 组件切换动画实现
直接将组件包裹在 标签,设置动画效果就可以.
• mode指令
属于 标签的一个属性 有 in-out与out-in值,实现组件切换时,动画效果的先进后出,与先出后进效果
• 父组件传子组件
• 父组件传数据给子组件
在子组件中 有一个 props:[] 存放的列表

1.在子组件的标签上 使用数据绑定 v-bind:seven = “父组件中变量”

2.在子组件的template中引用{{seven}}

3.在子组件的props:[‘seven’] :这里的数据是只读的,当修改时会提示错误

示例:

<body>
		<div id="app">
			
			login>
		div>
		
		<template id="tmp">
			<div>
				<p>我们接收父组件传过来的:值{{fcz}}p>
			div>>
		template>
		
		<script type="text/javascript">
			var vm = new Vue({
				el:'#app',
				data:{
					msgf : 'qiqiqiqiqiiqiqiqi'				},
				methods:{},
				components:{
					'login': {
						template: '#tmp',
						props: ['fcz']
					}
				}
			});
		script>
	body>

• 传方法
1.父组件有 方法 fu()

2.组件标签绑定父类方法 :v-on:seven=“add” (此处注意直传名,不能带括号,不然传的是方法的值)

3.组件内定义方法zi() ,zi()方法通过 this.$emit(‘seven’,参数)调用父类方法
(此处的参数,父类方法可以接收,在输出,或者把子类传来的数据保存到父类data中)

4.标签中的标签调用zi()方法即可

代码示例:

<body>
		<div id="app">
			login>
			<hr >
			<p>id:{{id}},name:{{name}}p>
		div>
		
		<template id="tmp">
			<div>
				<p>我们接收父组件传过来的:值{{fcz}}p>
				<input type="button" value="点击我" @click="count()"/>
				<p>显示数字:{{numf}}p>
			div>>
		template>
		
		<script type="text/javascript">
			var vm = new Vue({
				el:'#app',
				data:{
					msgf : 'qiqiqiqiqiiqiqiqi',
					num : 1,
					id : 0,
					name: ''
				},
				methods:{
					add(data1) {
						this.num +=1;
						console.log("我是父组件的方法:"+this.num);
						console.log(data1);
						this.id = data1.id;
						this.name = data1.name;
					}
				},
				components:{
					'login': {
						template: '#tmp',
						props: ['fcz','numf'],
						data:function(){
							return {
									shuji: {id:7,name:'贾真琦'}
								}
						},
						
						methods:{
							count() {
								this.$emit('seven',this.shuji);
							}
						}
					}
				}
			});
		script>
	body>

• $emit(‘seven’,data1,data2)
• 评论区案例


<html>
	<head>
		<meta charset="utf-8">
		<title>评论案例title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8">script>
		<link rel="stylesheet" type="text/css" href="../css/bootstrap.css"/>
	head>
	<body>
		<div id="app">
			
			<pl v-on:shuaxin="loadComment">pl>
			
			<ul class="list-group">
				<li class="list-group-item" v-for="item in list">
					<span class="badge">评论人:{{item.user}}span>
					{{item.content}}
				li>
			ul>
		div>
		
		
		<template id="pinglun">
			<div>
				<div class="form-group">
					<label>评论人:label>
					<input type="text" class="form-control" v-model="user"/>
				div>
				
				<div class="form-group">
					<label>评论内容:label>
					<textarea class="form-control" v-model="content">
						
					textarea>
				div>
				
				<div class="form-group">
					<input type="button" class="btn btn-primary" value="发表评论" @click="postComment"/>
				div>
			div>
		template>
		
		
		
		<script type="text/javascript">
			
			var commentBox = {
				template: '#pinglun',
				data: function() {
					return {
						user: '',
						content: ''
					}
				},
				methods: {
					postComment() {
						console.log(this.user);
						//获取输入数据
						var comment = {id: Date.now(), user: this.user, content: this.content};
						
						//从localStorage 获取所有评论
						var list = JSON.parse(localStorage.getItem('cmts')  '[]');
						//把新输入的放到数组中
						list.push(comment); 
						//重新保存最新数据	
						localStorage.setItem('cmts', JSON.stringify(list));					
						//输入框清空
						this.user = this.content = '';
						//自动刷新
						this.$emit('shuaxin');					
					}				
				}			
				var vm = new Vue(
					el:'#app',<w:br/>				
					data: {			
						list: [
							{id: Date.now(), user: '李白', content: '天生我才必有用'},
							{id: Date.now(), user: '科比', content: '你见过凌晨四点的洛杉矶吗'}
						]			
					},
					methods:{
						loadComment() {
							var list = JSON.parse(localStorage.getItem('cmts')  '[]');
							this.list = list;
					}
				},
				components:{
					'pl': commentBox
				},
				beforeCreate(){},
				created() {
					this.loadComment();
				}
			});
		script>
	body>
html>

1.6.2. 插槽
• 插槽的使用
1.在组件中加入标签(可带参数)

2.在引用组件的时候 直接传入用到的标签即可
<自定义标签>使用的标签(可多个)<自定义标签>
例子:

<login>
	<p>hahap>
	<img src="..." />
login>

• 具名插槽

组件中含多个 标签时,进行区别每个插槽 为每个 标签设置name属性: 例如: 在使用时指定标签的slot属性为插槽的name
例如:我是按钮

我是p

注意: 当全部的插槽指定了名字后,传入标签无slot属性的话,不会该表默认插槽的值,除非有没有name属性的插槽

代码示例:

<div id="app">
	<c1>
		<button type="button">我是按钮button>
		<p slot="s1">我是pp>
	c1>
div>
<template id="tmp1">
	<div>
		<h1>以下为插槽无默认值h1>
		<slot>无线slot>
		<slot name="s1">slot>
		<slot name="s2">slot>
		<slot name="s3">slot>
	div>
template>

• 编译作用域
官方准则:
父组件模板的东西都会在父级的作用域内编译,子组件模板的所有定西都会在子级作用域内编译

编译作用域, 看当时设置属性的标签属于那个实例,则就是那个实例的数据

例如;

这一组都属于app实例

<div id="app">
	<p v-show="isshow">哈哈哈p>
	<cc v-show="isshow">
		<button type="button" v-show="isshow">我是按钮button>
	cc>
div>

这一组都属于组件实例,但是slot好像不受控制

<template id="tmp">
	<div>
		<p v-show="isshow">测试编译作用域p>
		<slot v-show="isshow">
			<p>默认的插槽p>
		slot>
	div>
template>

• 作用域插槽
父组件替换插槽里的标签,但是内容由子组件来提供

个人理解:父类提供显示模板,子类提供数据

具体操作步骤:
1.在组件得插槽中 指定 属性绑定变量 :seven

2.在使用标签时,指定属性 slot-scope=“自定义值”,例如 slot-scope=“slot_t”

3.在使用插值表达式 时,可以使用 {{slot_t.seven}},使用到子组件的变量值了

谢谢观看~~
七天学完Vue之第三天学习笔记(组件的应用操作以及插槽的使用)_第1张图片

你可能感兴趣的:(前端,vue,vue-cli3)