一、prop 校验

使用带校验的 props,props 的值不再是数组而是一个对象,对象的属性名就是注册的 prop,属性值是一个对象,这个对象中包含了校验规则,如果不符合规则会引发警告;

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <child :msg="pmsg"></child>
  10. </div>
  11. <script src="vue.js"></script>
  12. <script>
  13. let child = {
  14. template: `<div>{{msg}}</div>`,
  15. data() {
  16. return {}
  17. },
  18. props: {
  19. msg: {
  20. type: Number, // 校验类型
  21. required: true, // 如果为 true 必传,不传就会报错
  22. // default: 200, // 默认值
  23. default() {
  24. // 如果默认值是一个对象或者数组,default 要写成一个函数,在函数中 return 这个对象或者数组
  25. return {
  26. name: '马宾',
  27. age: 18
  28. }
  29. },
  30. validator(val) {
  31. // validator 是自定义的校验函数
  32. // val 就是这个 prop 收到的值
  33. // 自定义校验规则,如果校验通过 return true,否则抛出异常或者 return false
  34. if (val >= 250) {
  35. // throw new Error('你真是个250');
  36. console.error('你真是250');
  37. return false;
  38. } else {
  39. return true
  40. }
  41. }
  42. }
  43. }
  44. };
  45. let vm = new Vue({
  46. el: '#app',
  47. data: {
  48. pmsg: 250
  49. },
  50. components: {
  51. child
  52. }
  53. })
  54. </script>
  55. </body>
  56. </html>

二、sync 修饰符和事件简写

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <!--使用 sync 修饰符可以简化子组件向父组件传递数据的过程;-->
  10. <!--1. 在父组件使用子组件时,prop 后面跟一个 .sync ,然后取消显式声明的事件监听-->
  11. <!--2. 子组件触发事件:this.$emit('update:prop 名字', 新数据)-->
  12. <child :msg.sync="pmsg"></child>
  13. </div>
  14. <script src="vue.js"></script>
  15. <script type="module">
  16. import child from './2-child.js';
  17. let vm = new Vue({
  18. el: '#app',
  19. data() {
  20. return {
  21. pmsg: 'hello from parent'
  22. }
  23. },
  24. methods: {
  25. },
  26. components: {
  27. child
  28. }
  29. })
  30. </script>
  31. </body>
  32. </html>

child.js

  1. export default {
  2. template: `<div>{{msg}} <button @click="changeMsg">修改msg</button></div>`,
  3. props: {
  4. msg: {
  5. type: [String, Number] // 类型校验有多个类型可以用一个数组
  6. }
  7. },
  8. methods: {
  9. changeMsg() {
  10. // 把 msg 修改成 呵呵
  11. // 配合 sync 修饰符,简化事件写法 :this.$emit('update:prop名', 数据)
  12. this.$emit('update:msg', '呵呵')
  13. }
  14. }
  15. }

三、父子组件 mounted

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <style>
  7. * {
  8. margin: 0;
  9. padding: 0;
  10. }
  11. .modal {
  12. width: 100vw;
  13. height: 100vh;
  14. position: fixed;
  15. top: 0;
  16. display: flex;
  17. justify-content: center;
  18. align-items: center;
  19. background: rgba(0, 0, 0, .5);
  20. }
  21. .modal .content {
  22. width: 400px;
  23. height: 300px;
  24. padding: 15px;
  25. background: #00b38a;
  26. }
  27. </style>
  28. </head>
  29. <body>
  30. <div id="app">
  31. <button @click="openModal">打开</button>
  32. <modal :open.sync="flag" ref="theModal"></modal>
  33. </div>
  34. <script src="vue.js"></script>
  35. <script type="module">
  36. import modal from './3-modal.js';
  37. let vm = new Vue({
  38. el: '#app',
  39. data() {
  40. return {
  41. flag: true
  42. }
  43. },
  44. methods: {
  45. openModal() {
  46. this.flag = true;
  47. }
  48. },
  49. components: {
  50. modal
  51. },
  52. mounted() {
  53. console.log('y');
  54. // 当父子组件都有 mounted 时,子组件的 mounted 先执行;
  55. // 每个组件都是一个 Vue 的实例,子组件的 mounted 先执行,方便父组件获取子组件的实例;
  56. console.log(this.$refs.theModal); // ref 如果加在原生的 DOM 元素上,通过 ref 获取的是原生的 DOM 对象;如果加在组件上,获取的是这个组件实例的一个引用;拿到这个实例后可以
  57. // 访问上面的数据、调用组件的方法
  58. // debugger;
  59. // this.$refs.theModal.closeModal(); // 调用子组件上的closeModal
  60. }
  61. })
  62. </script>
  63. </body>
  64. </html>

四、动态组件

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <div>
  10. <label>HOME: <input type="radio"
  11. v-model="title"
  12. value="home"></label>
  13. <label>LIST: <input type="radio"
  14. value="list"
  15. v-model="title"></label>
  16. <!--条件渲染-->
  17. <!--<home v-show="title == 'home'"></home>
  18. <list v-show="title == 'list'"></list>-->
  19. <!--动态组件-->
  20. <component :is="title"></component>
  21. <!--动态组件是实现在多个组件间来回切换,用法;-->
  22. <!--1. 写一个内置的 component 组件-->
  23. <!--2. 给 component 动态绑定 is 属性,当 is 属性绑定的值发生变化时,Vue 会按照 is 绑
  24. 定的最新的值自动渲染对应的组件-->
  25. <!--失活的组件会被销毁,存在实例中的数据都被销毁了-->
  26. </div>
  27. </div>
  28. <script src="vue.js"></script>
  29. <script>
  30. // 动态组件:
  31. let home = {
  32. template: '<div>HOME:<input type="text" v-model="home"></div>',
  33. data() {
  34. return {
  35. home: ''
  36. }
  37. },
  38. beforeDestroy() {
  39. console.log('HOME 要销毁了');
  40. },
  41. destroyed() {
  42. console.log('HOME 真的被销毁了');
  43. }
  44. };
  45. let list = {
  46. template: '<div>LIST:<input type="text" v-model="list"></div>',
  47. data() {
  48. return {
  49. list: ''
  50. }
  51. },
  52. beforeDestroy() {
  53. console.log('LIST 要销毁了');
  54. },
  55. destroyed() {
  56. console.log('LIST 真的被销毁了');
  57. }
  58. };
  59. let vm = new Vue({
  60. el: '#app',
  61. data() {
  62. return {
  63. title: 'home'
  64. }
  65. },
  66. components: {
  67. // home: home,
  68. // list: list
  69. home,
  70. list
  71. }
  72. })
  73. </script>
  74. </body>
  75. </html>

五、动态组件-keep-alive

  1. <body>
  2. <div id="app">
  3. <div>
  4. <label>HOME: <input type="radio"
  5. v-model="title"
  6. value="home"></label>
  7. <label>LIST: <input type="radio"
  8. value="list"
  9. v-model="title"></label>
  10. <keep-alive>
  11. <component :is="title"></component>
  12. </keep-alive>
  13. <!--keep-alive 也是内置的组件,它可以让失活的组件不销毁,所以保存在组件实例中的数据也不会销毁-->
  14. <!--动态组件常和 keep-alive 一起使用-->
  15. </div>
  16. </div>
  17. <script src="vue.js"></script>
  18. <script>
  19. // 动态组件:
  20. let home = {
  21. template: '<div>HOME:<input type="text" v-model="home"></div>',
  22. data() {
  23. return {
  24. home: ''
  25. }
  26. },
  27. beforeDestroy() {
  28. console.log('HOME 要销毁了');
  29. },
  30. destroyed() {
  31. console.log('HOME 真的被销毁了');
  32. }
  33. };
  34. let list = {
  35. template: '<div>LIST:<input type="text" v-model="list"></div>',
  36. data() {
  37. return {
  38. list: ''
  39. }
  40. },
  41. beforeDestroy() {
  42. console.log('LIST 要销毁了');
  43. },
  44. destroyed() {
  45. console.log('LIST 真的被销毁了');
  46. }
  47. };
  48. let vm = new Vue({
  49. el: '#app',
  50. data() {
  51. return {
  52. title: 'home'
  53. }
  54. },
  55. components: {
  56. // home: home,
  57. // list: list
  58. home,
  59. list
  60. }
  61. })
  62. </script>