主要讲:

  • 资源:directives
  • 组合:mixins、extends、provide、inject

Direvtives 指令

官方文档
用途:主要用于DOM操作,并减少DOM重复操作。

指令包括:

  • v-if
  • v-for
  • v-show
  • v-html

不过这里主要讲自己创建一个指令,语法为:

  1. Vue.directive('x',{
  2. bind: function (el, info, vnode, oldVnode) {
  3. //类似created
  4. },
  5. inserted: function (参数同上) {
  6. //当元素被插入到页面时
  7. },
  8. update: function (参数同上) {
  9. //类似updated
  10. },
  11. componentUpdated: function (参数同上) {
  12. //用得不多
  13. },
  14. unbind: function (参数同上) {
  15. //类似destroyed
  16. }
  17. })

一般是用 bindinserted 。参数一般用 elinfo

如造出一个 v-x ,点击即出现一个x
例子1:

  1. Vue.directive('x',{
  2. inserted: function (el) {//当元素被插入到页面时
  3. el.addEventListener('click', ()=>{console.log('x')})
  4. }
  5. })
  6. new vue({
  7. ......
  8. })

这是一个全局指令,可以在任何地方使用 v-x

例子2:

  1. new Vue({
  2. ...,
  3. directives:{
  4. "x":{
  5. inserted(el){
  6. el.addEventListener('click', ()=>{console.log('x')})
  7. }
  8. }
  9. }
  10. })

这是一个局部指令,只能在这个组件使用。

这个创建指令甚至可以模仿一个 v-on模仿v-on

而且还能简写:函数简写

Mixin 混入

情景:如果有两个组件,这两个组件的代码存在一定的重复,如下简单的事例:
src/Test.vue

  1. <template>
  2. <div>
  3. <button v-on:click="clicked('字符串1')">
  4. Button 1
  5. </button>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. name: "Test",
  11. methods: {
  12. clicked(value) {
  13. console.log(value);
  14. }
  15. }
  16. };
  17. </script>

上面的组件展示了一个按钮,点它会输出一个字符串。下面的组件会做确切相同的功能:
src/Modal.val

  1. <template>
  2. <div>
  3. <button v-on:click="clicked('字符串2')">
  4. Button 2
  5. </button>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. name: "Modal",
  11. methods: {
  12. clicked(value) {
  13. console.log(value);
  14. }
  15. }
  16. };
  17. </script>

然后在App.vue文件引入和声明两个组件:

  1. <template>
  2. <div id="app">
  3. <img alt="Vue logo" src="./assets/logo.png">
  4. <Test />
  5. <modal />
  6. </div>
  7. </template>;
  8. <script>
  9. import Test from "./Test.vue";
  10. import Modal from "./Modal.vue";
  11. export default {
  12. name: "app",
  13. components: {
  14. Test,
  15. Modal
  16. }
  17. };
  18. </script>

看了这两个组件,代码存在一定的重复,不仅浪费内存,而且也不符合DRY原则。这时可以考虑Mixins。

Mixin

所谓的Mixin(混入),其实就是复制。
通过mixins可以封装一部份重复的代码,然后可以在需要时将其引入各种组件。

语法

  1. //定义一个mixin对象
  2. let myMixin = {
  3. created: function{
  4. this.hello()
  5. }
  6. methods: {
  7. hello: function() {
  8. console.log("来自mixin的消息")
  9. }
  10. }
  11. }
  12. //定义一个组件来使用这个 mixin
  13. let Component = Vue.extend({
  14. mixins: [myMixin]
  15. });
  16. let component = new Component();

重构上面的例子

创建Mixin.vue文件:

  1. <script>
  2. export default {
  3. methods: {
  4. clicked(value) {
  5. console.log(value);
  6. },
  7. },
  8. };
  9. </script>

Test.vue引入Mixin.vue文件:

  1. <template>
  2. <div>
  3. <button v-on:click="clicked('字符串1')">
  4. Button 1
  5. </button>
  6. </div>
  7. </template>
  8. <script>
  9. import MixinWJ from "./Mixin.vue"
  10. export default {
  11. name: "Test",
  12. mixins: [MixinWJ]
  13. };
  14. </script>

Modal.vue同理:

  1. <template>
  2. <div>
  3. <button v-on:click="clicked('字符串2')">
  4. Button 2
  5. </button>
  6. </div>
  7. </template>
  8. <script>
  9. import MixinWJ from "./Mixin.vue"
  10. export default {
  11. name: "Modal",
  12. mixins: [MixinWJ]
  13. };
  14. </script>

App.vue

  1. <template>
  2. <div id="app">
  3. <Test/>
  4. <modal />
  5. </div>
  6. </template>;
  7. <script>
  8. import Test from "./Test.vue";
  9. import Modal from "./Modal.vue";
  10. export default {
  11. name: "app",
  12. components: {
  13. Test,
  14. Modal
  15. }
  16. };
  17. </script>

这就是mixin的用法!

Mixins有两种类型

  • 局部 Mixins:仅限在引用的文件使用。
  • 全局 Mixins: 顾名思义,就是在整个项目都可以用,语法如下:
    1. <script>
    2. Vue.mixin({
    3. mountd(){
    4. console.log("来自全局mixin的消息")
    5. }
    6. })
    7. </script>
    但不推荐使用全局Mixin。

总结

:::success Mixin就是把代码相似的组件收拢到一起成为一个组件,然后继承这个组件。 :::

extends 继承

与Mixin没什么区别,就是另一种写法。

只需要把mixin的例子里的 mixin:[mixin] 改成 extends:mixin ,注意extends只接受一个,而mixin可以接受一个数组。如:

  1. const extend = {
  2. data () {
  3. return name : 'extend 消息'
  4. }
  5. }
  6. const mixin1 = {
  7. data(){
  8. return name :'mixin1 消息'
  9. }
  10. }
  11. const mixin2 = {
  12. data(){
  13. return name :'mixin2 消息'
  14. }
  15. }
  16. export default {
  17. mixins : [mixin1, mixin2],
  18. extends: extend,
  19. name: 'app',
  20. data(){
  21. return name: 'name'
  22. }
  23. }

不过还是推荐使用mixins!

provide 提供 与 inject 注入

provide允许一个祖先组件向所有子孙后代注入一个依赖。如下例子:

父组件Ba.vue

  1. <script>
  2. export default {
  3. provide: return {name :'Aresn'}
  4. }
  5. </script>

子组件Er.vue

  1. <script>
  2. export default {
  3. inject: ['name'],
  4. mounted(){
  5. console.log(this.name) //Aresn
  6. }
  7. }
  8. </script>

实例:
实现一个按钮切换颜色。
父组件App.vue

  1. <template>
  2. <div :class="`theme-${themeName}`">
  3. <Button1 />
  4. </div>
  5. </template>
  6. <script>
  7. import Button1 from "./Button1.vue";
  8. export default {
  9. name: "App",
  10. provide(){
  11. return {
  12. themeName: this.themeName,
  13. changeTheme: this.changeTheme
  14. }
  15. },
  16. data(){
  17. return {
  18. themeName: "blue",
  19. }
  20. },
  21. methods: {
  22. changeTheme(){
  23. if(this.themeName === 'blue'){
  24. this.themeName = "red"
  25. } else {
  26. this.themeName = "blue"
  27. }
  28. }
  29. },
  30. components: {
  31. Button1,
  32. }
  33. }
  34. </script>
  35. <style>
  36. .theme-blue button{
  37. background: blue;
  38. }
  39. .theme-red button{
  40. background: red
  41. }
  42. </style>

子组件

  1. <template>
  2. <div>
  3. <button @click="changeTheme">按钮</button>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. inject:['changeTheme','themeName']
  9. }
  10. </script>