全局组件 & 局部组件

[ 组件作用 ]

  • 可以复用,提高开发效率
  • 方便后期维护和修改
  • 减少渲染

全局组件

  1. <body>
  2. <div id="app">
  3. <!-- 在 dom 中只支持 - 连接 -->
  4. <my-button></my-button>
  5. </div>
  6. <!-- 组件内容 -->
  7. <template id="button">
  8. <div> 111 </div>
  9. </template>
  10. </body>
  11. </html>
  12. <script src="vue.min.js"></script>
  13. <script>
  14. // 全局组件
  15. Vue.component('my-button', {
  16. // template: '<div> 1111 </div', // 所有组件
  17. template: '#button', // 查找相应组件内容
  18. data() { // 组件中的data 是一个函数 返回一个对象
  19. return {
  20. msg: 'aaa',
  21. }
  22. }
  23. })
  24. let vm = new Vue({
  25. // template: '<div> 111 </div',
  26. el: '#app',
  27. data: {},
  28. })
  29. </script>

局部组件

  1. <body>
  2. <div id="app">
  3. <!--3. 使用组件; 在 dom 中只支持 - 连接 -->
  4. <my-button>
  5. <hello></hello>
  6. </my-button>
  7. <!-- <hello></hello> -->
  8. </div>
  9. <!-- 组件内容 -->
  10. <template id="button">
  11. <div> {{ msg }}</div>
  12. </template>
  13. <template id="hello">
  14. <div> {{ hel }} </div>
  15. </template>
  16. </body>
  17. </html>
  18. <script src="vue.min.js"></script>
  19. <script>
  20. /**
  21. * 1. 定义组件
  22. * 2. 注册组件
  23. * 3. 使用组件
  24. *
  25. */
  26. let hello = {
  27. template: '#hello',
  28. data() {
  29. return {
  30. hel: 'hello'
  31. }
  32. }
  33. }
  34. // 1. 定义组件
  35. let myButton = {
  36. // template: '<div> 1111 </div', // 所有组件
  37. template: '#button', // 查找相应组件内容
  38. data() { // 组件中的data 是一个函数 返回一个对象
  39. return {
  40. msg: 'aaa',
  41. }
  42. },
  43. // myButton 的子组件 hello
  44. components: {
  45. // 在 myButton 中注册子组件 hello
  46. hello
  47. }
  48. }
  49. let vm = new Vue({
  50. // template: '<div> 111 </div',
  51. el: '#app',
  52. data: {},
  53. components: {
  54. // 2. 注册组件
  55. myButton, // myButton:myButton
  56. // hello
  57. }
  58. })
  59. </script>

组件间通信

[ 安装 ]

  • 项目开发: npm install -g @vue/cli
  • 快速原型开发(对单个 *.vue 文件开发): npm install -g @vue/cli-service-global

[ 运行 ]

  • 开发环境: vue serve App.vue
  • 生产环境: vue build App.vue

父组件传数据到子组件 : 子组件通过 props 接收

  1. <template>
  2. <div>
  3. Parent
  4. <!-- 父组件穿数据到子组件 -->
  5. <Son :money='money'></Son>
  6. </div>
  7. </template>
  8. <script>
  9. import Son from './Son';
  10. export default {
  11. data() {
  12. return {
  13. money: '400',
  14. }
  15. },
  16. components: {
  17. Son
  18. }
  19. }
  20. </script>
  21. <template>
  22. <div>
  23. Son
  24. {{ money }}
  25. </div>
  26. </template>
  27. <script>
  28. export default {
  29. // props:['money']
  30. // computed: { //计算属性
  31. // changeM() {
  32. // // 对传过来的值进行更改,变为小写
  33. // return this.money.thim().toLowerCase();
  34. // }
  35. // },
  36. // 对传过来的值进行验证
  37. props: {
  38. money: {
  39. type:[String, Number],
  40. // default: 100, 默认值
  41. required: true, // 必须传
  42. // 自定义验证规则
  43. validator:(value)=> {
  44. return value > 400 && value < 1000;
  45. }
  46. },
  47. // 数组或对象 默认值得是函数
  48. arr: {
  49. type: Array ,
  50. default: ()=> [1] //默认值 函数 返回一个数组
  51. },
  52. obj: {
  53. type:Object,
  54. default: ()=> ({}) //默认值 函数 返回一个对象
  55. },
  56. },
  57. }
  58. </script>

子组件传数据到父组件 : $emit(通过事件的方式,观察者模式)

  1. <template>
  2. <div>
  3. Parent
  4. <!-- 父组件监视子组件的事件(子组件传数据到父组件)并且给事件绑定函数 -->
  5. <!-- <Son @change="fn"></Son> -->
  6. <!-- 语法糖写法 -->
  7. <!-- <Son :money.sync="money"></Son> -->
  8. <!-- 对应子组件 语法糖 写法 -->
  9. <!-- this.$emit('update:money',1000) -->
  10. <!-- 相当于 money 绑定在属性 value 并且绑定的事件名 @input -->
  11. <Son v-model="money"></Son>
  12. <!-- <Son
  13. :value="money"
  14. @input="(data)=>money=data"
  15. ></Son> -->
  16. <!-- 对应子组件写法 -->
  17. <!-- 接受到的属性 :{{ value }} -->
  18. <!-- this.$emit('input', 1000) -->
  19. </div>
  20. </template>
  21. <script>
  22. import Son from './Son';
  23. export default {
  24. data() {
  25. return {
  26. money: '400',
  27. }
  28. },
  29. components: {
  30. Son
  31. },
  32. methods: {
  33. fn(data){ // data 子组件传回来的数据
  34. this.money = data;
  35. }
  36. },
  37. }
  38. </script>
  39. <template>
  40. <div>
  41. Son
  42. <button @click="give">传数据到父组件</button>
  43. </div>
  44. </template>
  45. <script>
  46. // import grandSon from './grandSon';
  47. export default {
  48. methods: {
  49. // 子组件传数据到父组件
  50. give() {
  51. // 子组件执行父组件监听的事件
  52. // this.$emit('change', 1000)
  53. // 语法糖 写法
  54. // this.$emit('update:money',1000)
  55. this.$emit('input', 1000)
  56. }
  57. },
  58. }
  59. </script>

批量把属性传给后代组件(子组件或孙组件): $attrs(v-bind=”$attrs”往下传)

  1. <Son :name ="1" :age= "2" @click="fn"></Son>
  2. <!-- 直接一次性拿到父组件传的所有属性 -->
  3. {{$attrs}}
  4. <!-- 只传一个数据,此时 数据里面只剩下 age -->
  5. <GrandSon v-bind="$attrs" :name="$attrs.name"></GrandSon>
  6. <script>
  7. // GrandSon 组件中接收
  8. export default {
  9. props: ['name'],
  10. }
  11. </script>

批量把方法传给后代组件: $listeners(v-on=”$listeners”往下传)

  1. <!-- 父组件中绑定事件 -->
  2. <Son :name ="1" :age= "2" @click="fn"></Son>
  3. <!-- 子组件拿到父组件的事件 -->
  4. <!-- {{ $listeners.click() }} -->
  5. <GrandSon v-on="$listeners" ></GrandSon>
  6. <!-- GrandSon 组件中直接调用 -->
  7. {{ $listeners.click() }}

跨组件 provide inject

  1. <!-- 跨组件 -->
  2. <script>
  3. import Son from './Son'
  4. export default {
  5. // 全局定义
  6. provide() {
  7. return {
  8. parentMsg: 'parent'
  9. }
  10. },
  11. }
  12. </script>
  13. <!-- grandSon 中通过 inject 注入, {{ parentMsg }}使用 -->
  14. <script>
  15. export default {
  16. inject:['parentMsg']
  17. }
  18. </script>

$parent & $children & ref

  • 拿到父组件: $parent ;
  • 拿到所有子组件: $children (返回一个所有子组件的数组) ;
  • 通过 ref 获取
  1. <!-- $parent 拿到父组件; $children 拿到所有子组件 -->
  2. <GrandSon ref="GrandSon" ></GrandSon>
  3. <script>
  4. mounted() { // dom 加载完成的钩子函数
  5. this.$parent // 拿到父组件
  6. this.$children // 拿到所有的子组件,拿到的是一个数组
  7. // 执行
  8. this.$parent.fn();
  9. this.$$children[0].fn2(); // 通过索引拿到第一个子组件
  10. // 通过 ref
  11. this.$refs.GrandSon.fn2()
  12. }
  13. </script>
  1. 兄弟间的通信 : eventBus; 通过 $on 和 $emit
  1. Vue.prototype.$bus = new Vue(); // 必须拥有公共的 vue 实例
  2. this.$bus.$on('test',function(data){
  3. console.log(data)
  4. })
  5. // 另一个兄弟组件传递数据
  6. this.$bus.$emit('test',1000)