vue使用之自定义指令、组件开发和组件通讯

vue使用之自定义指令、组件开发和组件通讯

  • vue使用之自定义指令、组件开发和组件通讯
    • 1 自定义指令
      • 1.1 自定义指令-钩子函数
      • 1.2 自定义指令binding
      • 1.3 自定义指令v-mytext
      • 1.4 自定义指令v-mybind
      • 1.5 自定义指令v-on
      • 1.6 全局自定义指令与局部自定义指令
    • 2 组件化开发
      • 2.1 全局组件
      • 2.2 局部组件
    • 3 组件通讯
      • 3.1 组件通讯-父传子
      • 3.2 组件通讯-子到父
      • 3.3 组件通讯-非父子

vue使用之自定义指令、组件开发和组件通讯

1 自定义指令

vue除了提供了核心的一些指令,还允许注册自定义指令。

// 注册自定义指令
// 参数1,指令名称  参数2:配置参数
Vue.directive('focus', {
    // 钩子函数比较多,用的比较多的是 bind 和 update

    // 只会调用一次,当指令绑定到当前元素上时调用
    bind (el) {
    },
    // 当前元素被插入到父节点的时候调用(渲染时)
    inserted (el) {
        el.focus()
    },
    // 当指令对应的数据发生改变的时候
    update () {

    },
    // 所有的DOM都更新之后
    componentUpdated () {

    },
    // 指令与元素解绑的时候
    unbind () {

    }

})
  • 指令的参数

所有的钩子函数两个参数elbinding

el: 当前元素
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

1.1 自定义指令-钩子函数

<script>
    // 定义指定
    Vue.directive('focus', {
      // 5个钩子函数,并不是都需要写
      // 每一个钩子函数中,还有2个参数
      //el:当前元素
      //binding:一个对象
      bind: function () {
        console.log('当指令与元素绑定的时候执行,此时还没显示到页面')
      },
      inserted: function (el) {
        console.log('当前元素插入到父元素中的,触发')
        el.focus()
      },
      update: function () {
        console.log('当指令的值发生改变的时候执行')
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue'
      }
    })
  </script>

1.2 自定义指令binding

<script>
    Vue.directive('focus', {
      inserted(el, binding) {
        console.log('el', el)
        /* 
          binding参数的值
            name: 指令的名称 不带 v-
            value: 指令对应的值
            arg: 指令的参数
            modifiers: 指令的修饰符 可以有多个
         */
        console.log('binding', binding)
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue'
      }
    })
  </script>

1.3 自定义指令v-mytext

<script>
    /* 
      v-text: 功能
        设置当前元素的innerText的值
    */
    Vue.directive('cctext', {
      // 一来就设置当前元素的innerText值
      bind(el, binding) {
        el.innerText = binding.value
      },
      // 当msg发生了改变,修改innerText的值
      update(el, binding) {
        el.innerText = binding.value
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue'
      }
    })
  </script>

1.4 自定义指令v-mybind

 <script>
    // 自定义 v-mybind指令
    // v-bind:src = 'imgUrl'
    // 给src属性设置值  imgUrl对应的值
    Vue.directive('mybind', {
      bind(el, binding) {
        // binding.name: 指令的名字
        // binding.value: 指令的值imgUrl
        // binding.arg: 指令的参数src
        // binding.modifiers: 指令的修饰符
        el.setAttribute(binding.arg, binding.value)
      },
      update(el, binding) {
        el.setAttribute(binding.arg, binding.value)
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue',
        imgUrl: '01.gif'
      }
    })
  </script>

1.5 自定义指令v-on

<script>
    Vue.directive('myon', {
      /* 
        v-on:
        给当前元素注册对应的事件
       */
      bind(el, binding) {
        el.addEventListener(binding.arg, function (e) {
          // 现在可以在function内部增加很多的逻辑
          binding.value()
          // 判断是否有modifiers.prevent
          if (binding.modifiers.prevent) {
            e.preventDefault()
          }
          if (binding.modifiers.stop) {
            e.stopPropagation()
          }
        })
      },
      update(el, binding) {
        el.addEventListener(binding.arg, binding.value)
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue'
      },
      methods: {
        clickFn() {
          console.log('哈哈')
        }
      }
    })
  </script>

1.6 全局自定义指令与局部自定义指令

<script>

    // 全局自定义指令, 自定义指令可以在所有的vm实例中都使用
    // Vue.directive('color', function (el, binding) {
    //   el.style.color = binding.value
    // })
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue'
      },
      // data methods filters watch computed

      // 局部指令, 只能在当前实例中使用
      directives: {
        color: function (el, binding) {
          el.style.color = binding.value
        }
      }
    })
  </script>

2 组件化开发

组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。

在vue中都是组件化开发的,组件化开发就是把一个完整的页面分割成一个一个的小组件。

2.1 全局组件

<div id="app">
    <!-- 使用组件 -->
    <hello></hello>
  </div>

  <script src="vue.js"></script>
  <script>// 定义全局组件
    // 参数1: 组件名
    //
     参数2: 组件的配置项
    Vue.component('hello', {
      // 组件的template中,必须保证只有一个根元素
      template: '
' + '

大家好,我是hello组件

'
+ '

我是另一个p标签

'
+ '
'
}) var vm = new Vue({ el: '#app', data: { msg: 'hello vue' } }) </script>

2.2 局部组件

//在vue实例的内部,通过components属性来定义局部组件
components: {
    "my-button": {
        template: `
        

我是一个标题

我是一个段落

`
} }

注意:

  • 组件是一个独立封闭的个体,组件之间的数据是无法相互使用的
  • 组件中data属性必须是一个函数,返回值才是data的数据

3 组件通讯

因为组件是一个独立的个体,组件无法使用到外部的数据

但是在真实开发中,多个组件之间是需要相互使用彼此的数据的,因此需要使用组件通讯的技术,让组件之间能够相互传值。

组件通讯分为三类

  • 父组件传递值给子组件
  • 子组件传递值给父组件
  • 非父子组件之间的传值

3.1 组件通讯-父传子

  • 组件的通讯
1. 在父组件的模版中,给子组件增加一个自定义的属性。
<son :car="car"></son>

2. 子组件通过props属性进行接收
//接收父组件传递过来的值
props: ['car']

3. 子组件使用父组件传递过来的值
template: `

这是子组件

这是父组件传递过来的值----{{car}}

`
,

注意:props负责获取父组件的传递过来的,props中的值是只读的,不允许修改

3.2 组件通讯-子到父

1. 父组件给子组件注册一个自定义事件
2. 子组件触发这个自定义事件,触发事件时把数据传递给父组件
  • 父组件给子组件注册事件
<son @fn='getData'></son>
methods: {
    //1. 父组件中定义了一个方法,用于获取数据
    getData () {
        console.log("父组件中提供的方法");
    }
}
  • 子组件触发自定义事件,并且把要传递的数据作为参数进行传递
//$emit可以出发当前实例的事件
this.$emit('getData', this.car);
  • 父组件获取值
methods: {
    //1. 父组件中定义了一个方法,用于获取数据
    getData (skill) {
        console.log("父组件中提供的方法", skill);
        this.skill = skill;
    }
}

3.3 组件通讯-非父子

非父子组件之间通过一个空的Vue实例来传递数据。

const bus = new Vue();   //bus:公交车  事件总线
  • 核心逻辑
组件A给组件B传值:
1. 组件A给bus注册一个事件,监听事件的处理程序
2. 组件B触发bus上对应的事件,把 值当成参数来传递
3. 组件A通过事件处理程序获取数据
  • 组件A给bus注册事件
 //rose在组件创建的时候,给bus注册了一个事件
created () {
    bus.$on("get", (msg)=>{
        console.log("这是rose注册的事件", msg);
        this.msg = msg;
    });
}
  • 组件B触发bus的事件
<button @click="send">表白</button>

methods: {
    send() {
        bus.$emit("get", this.msg);
    }
}
  • 组件A通过事件处理程序可以获取到传递的值
bus.$on("get", (msg)=>{
    console.log("这是rose注册的事件", msg);
    this.msg = msg;
});

注意点:1. 必须是同一辆公交车 2. 注册的事件和触发的事件必须保持一致

你可能感兴趣的:(Vue)