vue组件
基本概念
组件概念: 组件是可复用的Vue实例,封装标签,样式和JS代码
好处: 各自独立,便于复用
组件化:封装的思想,把页面上“可复用的部分”封装为"组件”,从而方便项目的开发与维护
一个页面, 可以拆分成一个个组件,一个组件就是一个整体, 每个组件可以有自己独立的 结构 样式 和 行为(html, css和js)
组件构成
全局组件
main.js
1、创建组件 ----------文件名App.vue
2、引入组件 ----------import 组件对象 from 'vue文件路径'
3、全局注册-----------Vue.component("组件名", 组件对象)
** App.vue**
4、在子组件App.vue中把"组件名当标签名使用"-----<组件名></组件名>
局部组件
Pannel_1.vue
1、创建组件 ----------文件名Pannel_1.vue(文件名App.vue,封装组件Pannel_1.vue(标签、样式、js都放进去)
App.vue
2、引入组件 ----------import pannel from "./Pannel_1.vue";
3、全局注册-----------components: {pannely: pannel },
4、把"组件名当标签名使用"-----<pannely
scoped
原理和过程: 会自动给标签添加data-v-hash值属性,所有选择都带属性选择
操作: 给style添加scoped,只针对当前Vue组件内标签生效
组件通信
父传子
使用场景: 从一个Vue组件把值传给另一个Vue组件(父->子)
父组件自定义属性传值,子组件通过props接收,并使用
子传父
子组件通过this.$emit()触发,父组件接收,并处理业务逻辑
步骤:
1:父组件通过绑定自定义事件,绑定事件处理函数
2:子组件通过恰当事件触发父组件的事件处理函数(恰当时机---->自身绑定事件)
3:子组件使用this.$emit("自定义事件",传递的参数)触发父组件处理函数
4:父组件处理函数被触发,接收数据并处理
示列:
需要使用vue_cli脚手架创建项目,在项目中使用示列
App.vue
1 <template>
2 <div>
3 <!-- 每次循环,item变量和当前组件都是独立执行 -->
4 <!-- 组件对象 当标签使用-->
5 <!--
6 v-for="(item, ind) in list"
7 :key="item.id"
8 :title="item.proname"
9 :price="item.proprice"
10 :info="item.info"
11 子传->父--循环传值
12 自定义属性 title、price、info,把相应的变量(item.proname、item.proprice、item.info)传递给子组件
13 -->
14 <myProduct
15 v-for="(item, ind) in list"
16 :key="item.id"
17 :title="item.proname"
18 :price="item.proprice"
19 :info="item.info"
20 @subStr="fan"
21 :index="ind"
22 ></myProduct>
23 <!-- @subStr="fan" 给子组件绑定自定义事件 -->
24 </div>
25 </template>
26
27 <script>
28 // 1 目标:局部注册
29 // 1.0 新建文件 ---myproduct.vue
30 // 1.2 引入组件
31 // 1.3 注册组件components{"组件对象",组件名}}
32 // 1.4 把把局部注册的"组件对象" 当标签使用
33
34 // 2 目标 父向子传值
35 // 2.1 在父组件自定义属性给子组件传值
36 // 2.2 子组件通过props接收变量,并使用变量
37 import myProduct from "./components/study_components/myproduct.vue";
38 export default {
39 components: {
40 // myProduct:myProduct 名跟值一样的话可简写成myProduct
41 myProduct,
42 },
43 data() {
44 return {
45 list: [
46 {
47 id: 1,
48 proname: "超级好吃的棒棒糖",
49 proprice: 18.8,
50 info: "开业大酬宾, 全场8折",
51 },
52 {
53 id: 2,
54 proname: "超级好吃的大鸡腿",
55 proprice: 34.2,
56 info: "好吃不腻, 快来买啊",
57 },
58 {
59 id: 3,
60 proname: "超级无敌的冰激凌",
61 proprice: 14.2,
62 info: "炎热的夏天, 来个冰激凌了",
63 },
64 ],
65 };
66 },
67 methods: {
68 fan(index, price) {
69 // 逻辑代码
70 // console.log(index, price);
71 // 取出对应的数据并砍价
72 this.list[index].proprice =
73 this.list[index].proprice > 2 &&
74 (this.list[index].proprice -= price).toFixed(1);
75 },
76 },
77 };
78 </script>
79
80 <style>
81 </style>
myproduct.vue
1 <template>
2 <div class="my-product">
3 <h3>标题:{{ title }}</h3>
4 <p>价格:{{ price }}元</p>
5 <p>{{ info }}</p>
6 <button @click="btnBargain">砍一刀</button>
7 </div>
8 </template>
9
10 <script>
11 // 3 目标 子向父传值
12 // 3.1: 父组件中给子组件绑定自定义事件,绑定自定义处理函数
13 // 3.2: 子组件在恰当时机触发事件
14 // 3.3: 恰当时机是指用户点击砍价按钮时
15 // 3.4: 使用this.$emit()方法,触发自定义事件
16 // 3.5 :传递数据给父组件
17 // 3.6 :父组件处理函数触发,接收数据并处理砍价业务
18
19 export default {
20 // Vue规定props里变量是只读,不可进行赋值
21 //子组件通过props接收父组件传递来的自定义属性,并使用渲染到页面
22 props: ["index", "title", "price", "info"],
23 methods: {
24 // 恰当时机,触发父组件绑定的subStr自定义事件
25 // this.$emit()参数1:事件名 参数2 ~参数N:传递的参数
26 btnBargain() {
27 this.$emit("subStr", this.index, 1);
28 },
29 },
30 };
31 </script>
32
33 <style>
34 .my-product {
35 width: 400px;
36 padding: 20px;
37 border: 2px solid #000;
38 border-radius: 5px;
39 margin: 10px;
40 }
41 </style>
兄弟传值(eventBus)
使用场景: 当2个没有引用关系的组件之间要通信
本质:空白Vue对象,只负责emit
接收方:eventBus.$on("事件名",函数体)
传递方:eventBus.$emit("事件名",值)