【Vue】Vue基础自用笔记Day04

阅读: 评论:0

【Vue】Vue基础自用笔记Day04

【Vue】Vue基础自用笔记Day04

Vue基础 - Day04

  • 1. Vue组件 - component
      • 定义全局组件
      • 定义私有组件
      • 组件中数据和方法的调用
      • 组件动画
      • 父组件传值子组件
      • 子组件传值父组件
  • 2. Vue插槽 - slot
    • 如果出现具名插槽没有效果,但是也没有报错,极有可能是Vue版本引入的问题!

1. Vue组件 - component

什么是组件:
组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。

组件化和模块化的不同:
模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用

一个优秀的组件 / 模块应该做到:高内聚,低耦合

耦合性:每个模块之间相互联系的紧密程度,模块之间联系越紧密,则耦合性越高,模块的独立性就越差

内聚性:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即‘高内聚’

高内聚是说模块内部要高度聚合,低耦合是说模块与模块之间的耦合度要尽量低。 前者说的是模块内部的关系,后者说的是模块与模块之间的关系。 看似不同,实又相关。

如一个项目中有15个模块,需要在另一个项目中调用其中的一个模块,但是必须把全部的15个模块都移植过去才能使用,这就是高耦合,只移入所需的一个模块就可以使用,就是低耦合

然后在一个模块中,各个元素(语句、程序段等)之间的联系程度越高,则内聚性越高,即高内聚


定义全局组件

1.使用 d 配合 Vueponent 方法

var login = d({template: '<h1>登录</h1>'
});
//第一个为组件名称,第二个为绑定的组件的名称
Vueponent('login', login); 

2.直接使用 Vueponent 方法

Vueponent('register', {template: '<h1>注册</h1>'
});

3.将模板字符串,定义到script标签中,同时,需要使用 Vueponent 来定义组件

<script id="tmpl" type="x-template"><div><a href="#">登录</a> | <a href="#">注册</a></div>
</script><script>Vueponent('account', {template: '#tmpl'});
</script>

4.将模板字符串,定义到template标签中

< template id="tmpl"><div><a href="#">登录</a> | <a href="#">注册</a></div>
</ template >

同时,需要使用 Vueponent 来定义组件

Vueponent('account', {template: '#tmpl'
});

一般只用第四种方式定义全局组件。

注意:
1.组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹,即最外层不能有同级的HTML标签,一般用一个 div 将其他的DOM元素包裹起来。2.命名不能和 H5 中已有的标签重名,且驼峰命名不好使,因为HTML大小写不敏感,可以用-连接

定义私有组件

在Vue实例中添加 components 属性即可:

const vm = new Vue({el: '#app',data: {flag: true},methods: {},components: {"register": {template: "#register"},"test": {template: "#login"},// 必须写ID,不可以写类名// "lll": {//   template: ".lllllll"// }}
})

引用组件:

 <div id='app'><register v-if="flag"></register><test v-if="flag"></test></div>

组件中数据和方法的调用

组件中也有data属性、methods属性、八个生命周期钩子函数等,但是data属性的属性值
由Vue实例中的对象变为了函数,并且函数中必须要有一个返回值,返回值里是组件可调用
的数据,如:
Vueponent("hello", {template: "#hello",data() {return {msg: "Hello World",nums: 666}},methods: {add() {this.nums += 6}}
})

其目的是为了组件复用时的数据隔离, 否则不同的组件都共用一个数据的话,一个发生变化每一个都会发生变化,一般情况下这不是我们想要的效果。

案例:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src=".js"></script><script src="@3.0.0/dist/vue-router.js"></script><script src=".27.2/axios.js"></script>
</head><body><div id='app'><button @click="flag=!flag">销毁Hello</button><hello v-if="flag"></hello></div><template id="hello"><div>{{msg}}<button @click="add">增6👉</button><span>{{nums}}</span></div></template>
</body>
<script>Vueponent("hello", {template: "#hello",// 组件之间数据隔离data() {return {msg: "Hello World",nums: 666}},methods: {add() {this.nums += 6}},beforeCreate() {console.log("创造哈喽前");},created() {console.log("创造哈喽后,可以调用数据了");},beforeDestroy() {console.log("销毁哈喽前");},destroyed() {console.log("销毁哈喽后");}})const vm = new Vue({el: '#app',data: {flag: true},methods: {},})
</script></html>

使用 <component> 标签来引用组件,并通过is属性来指定要加载的组件,is属性也可进行数据绑定

//指定引用的组件为'hello'
<component is="hello"></component>
//加上冒号后,引号里的内容就变成了变量引用,需要注意单/双引号的添加
<component :is="flag?'hello':'nohello'"></component>

组件动画

<transition> 标签中有一个 mode 属性,来设置组件的动画是先出后入还是先入后出,先出后入为 mode="out-in" ,先入后出为 mode="in-out",通常先出后入的情况比较符合审美。

---------------------------------------
<p>先出后入的动画:</p>
<transition mode="out-in"><component :is="flag?'hello':'nohello'"></component>
</transition>
---------------------------------------
<p>先入后出的动画:</p>
<transition mode="in-out"><component :is="flag?'hello':'nohello'"></component>
</transition>

完整案例:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src=".js"></script><script src="@3.0.0/dist/vue-router.js"></script><script src=".27.2/axios.js"></script>
</head>
<style>.v-enter,.v-leave-to {transform: translateX(200px);}.v-enter-active,.v-leave-active {transition: all 1s;}.v-enter-to,.v-leave {transform: translateX(0px);}
</style><body><div id='app'><button @click="flag=!flag">销毁Hello</button><hello v-if="flag"></hello><nohello v-else></nohello>-------------------------------------<component is="hello"></component>---------------------------------------<!-- 注意是变量还是字符串 --><component :is="flag?'hello':'nohello'"></component>---------------------------------------<p>先出后入的动画:</p><transition mode="out-in"><component :is="flag?'hello':'nohello'"></component></transition>---------------------------------------<p>先入后出的动画:</p><transition mode="in-out"><component :is="flag?'hello':'nohello'"></component></transition></div><template id="hello"><div>{{msg}}<button @click="add">增6👉</button><span>{{nums}}</span></div></template><template id="nohello"><div>ByeByeWorld</div></template>
</body>
<script>Vueponent("hello", {template: "#hello",// 组件之间数据隔离data() {return {msg: "Hello World",nums: 666}},methods: {add() {this.nums += 6}},})Vueponent("nohello", {template: "#nohello"})const vm = new Vue({el: '#app',data: {flag: true},methods: {},})
</script></html>

也可以选择不使用 <component> 标签,而是直接使用组件加 v-ifv-else,如:

<p>先出后入的动画:</p><transition mode="out-in"><hello v-if="flag"></hello><nohello v-else></nohello></transition>

父组件传值子组件

1.子组件中设置 props属性(和data同级),在props属性中设置接收数据的名称与类型,
可以使用数组设置多个接收类型,也可以使用 default函数 设置默认值;

Vueponent("course", {template: "#course",props: {type: String,'page-num': [Number, String],'page-size': [Number, String],test: {type: String,default: function () {return '这是一个默认的名字'}},},data() {return {courseList: [],baseUrl: "1.117.81.216:8086",}},
})

2.设置完成后在子组件标签中绑定props中定义的参数,属性值可以是父组件中的数据或者其他字符串,但是在标签中绑定参数时不能使用驼峰命名法,必须用kebaba-case命名法(即以-连接)

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src=".js"></script><script src="@3.0.0/dist/vue-router.js"></script><script src=".27.2/axios.js"></script>
</head><body><div id='app'><!-- 子组件标签中绑定props中定义的参数,属性值可以是父组件的数据 --><test :msgson="msgFather"></test></div><template id="test"><div><p>{{msg}}------{{msgson}}</p></div></template>
</body>
<script>const vm = new Vue({el: '#app',data: {msgFather:"我是父组件的文字信息"},methods: {},components:{"test":{template:"#test",data(){return{msg:"我是子组件的文字信息",}},props:{msgson:String}}}})</script>
</html>

子组件传值父组件

子组件传值父组件需要我们在子组件标签中自定义传值事件,如:

<son @son-to-father="theFather" ref="myson"></son>

son-to-father 是在子组件的 methods 里写的方法,在方法中调用 this.$emit() 函数向父组件传值。

自定义事件不会自己调用,需要我们根据需求设置在什么情况下触发此事件去给父组件传值。

this.$emit() 的第一个参数是我们自己自定义的事件的名称,第二个参数是子组件给父组件传递的内容,可以是子组件 data 中的数据、一段字符串等等。

即:this.$emit(‘事件名称’,传递的数据)

theFather 是在父组件的 methods 里写的方法,触发sonToFather自定义事件后,会自动接收到子组件传递过来的数据,第一个参数就是接收到的数据,接收到后进行自己需要的操作即可。

代码举例:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src=".js"></script>
</head><body><div id='app'><p>{{fatherMsg}}</p><button @click="changeMyson">改变子组件文字</button><son @son-to-father="theFather" ref="myson"></son></div><template id="son"><div><p>{{msg}}</p><button @click="sonToFather">向父组件传送</button></div></template>
</body>
<script>const vm = new Vue({el: '#app',data: {fatherMsg: "默认的父组件文字"},methods: {theFather(data) {console.log(data);this.fatherMsg = data},changeMyson() {this.$son.msg = "改成父组件中的文字"}},components: {"son": {template: "#son",data() {return {msg: "这里是子组件中的文字",}},methods: {sonToFather() {this.$emit("son-to-father", this.msg)}}}}})
</script></html>

2. Vue插槽 - slot

插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。

插槽有 具名插槽默认插槽

具名插槽就是给插槽取个名字,一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中

默认插槽就是没有名字,只有一个<slot></slot>标签。

<!-- 课程组件 -->
<course page-size='10'><!-- <slot>默认插槽</slot> --><template v-slot:free>免费</template><!-- <template v-slot:disc>限时折扣</template> -->
</course><course type="boutique"><template v-slot:free>精品</template>
</course><course type="discount"><template v-slot:discount>限时折扣</template>
</course><template id="course"><div><h2><!-- 默认插槽:<slot></slot> --><!-- 具名插槽:<slot name="free"></slot>课程 --><slot name="free"></slot><slot name="discount"></slot>课程</h2><!-- <slot></slot> --><!-- <slot name="disc"></slot> --></div>
</template>

如果出现具名插槽没有效果,但是也没有报错,极有可能是Vue版本引入的问题!

本文发布于:2024-01-28 13:25:00,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17064195027726.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:自用   基础   笔记   Vue
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23