美文网首页
Vue-(5)自定义指令-路由

Vue-(5)自定义指令-路由

作者: 物非0人非 | 来源:发表于2021-08-18 09:21 被阅读0次

    一:自定义指令

    除了默认设置的核心指令(v-modelv-show ), Vue 也允许注册自定义指令。
    下面我们注册一个全局指令v-focus,该指令的功能是在页面加载时,元素获得焦点:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        <p>页面载入时,input 元素自动获取焦点:</p>
        <input v-focus>
    </div>
    
    <script>
    // 注册一个全局自定义指令 v-focus
    Vue.directive('focus', {
      // 当绑定元素插入到 DOM 中。
      inserted: function (el) {
        // 聚焦元素
        el.focus()
      }
    })
    // 创建根实例
    new Vue({
      el: '#app'
    })
    </script>
    </body>
    </html>
    

    结果:

    image.png

    我们也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
      <p>页面载入时,input 元素自动获取焦点:</p>
      <input v-focus>
    </div>
    
    <script>
    // 创建根实例
    new Vue({
      el: '#app',
      directives: {
        // 注册一个局部的自定义指令 v-focus
        focus: {
          // 指令的定义
          inserted: function (el) {
            // 聚焦元素
            el.focus()
          }
        }
      }
    })
    </script>
    </body>
    </html>
    

    结果:

    image.png
    钩子

    钩子函数
    指令定义函数提供了几个钩子函数(可选):

    • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
    • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
    • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
    • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
    • unbind: 只调用一次, 指令与元素解绑时调用。
    钩子函数参数

    钩子函数的参数有:

    • el: 指令所绑定的元素,可以用来直接操作 DOM 。
    • binding: 一个对象,包含以下属性:
          name: 指令名,不包括 v- 前缀。
          value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
          oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
          expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" , >* expression 的值是 "1 + 1"。
          arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
          modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
    • vnode: Vue 编译生成的虚拟节点。
    • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    以下实例演示了这些参数的使用:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="app"  v-runoob:hello.a.b="message">
    </div>
    
    <script>
    Vue.directive('runoob', {
      bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML =
          'name: '       + s(binding.name) + '<br>' +
          'value: '      + s(binding.value) + '<br>' +
          'expression: ' + s(binding.expression) + '<br>' +
          'argument: '   + s(binding.arg) + '<br>' +
          'modifiers: '  + s(binding.modifiers) + '<br>' +
          'vnode keys: ' + Object.keys(vnode).join(', ')
      }
    })
    new Vue({
      el: '#app',
      data: {
        message: '菜鸟教程!'
      }
    })
    </script>
    </body>
    </html>
    

    结果:

    name: "runoob"
    value: "菜鸟教程!"
    expression: "message"
    argument: "hello"
    modifiers: {"a":true,"b":true}
    vnode keys: tag, data, children, text, elm, ns, context, functionalContext, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce
    

    有时候我们不需要其他钩子函数,我们可以简写函数,如下格式:

    Vue.directive('runoob', function (el, binding) {
      // 设置指令的背景颜色
      el.style.backgroundColor = binding.value.color
    })=
    

    指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        <div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div>
    </div>
    
    <script>
    Vue.directive('runoob', function (el, binding) {
        // 简写方式设置文本及背景颜色
        el.innerHTML = binding.value.text
        el.style.backgroundColor = binding.value.color
    })
    new Vue({
      el: '#app'
    })
    </script>
    </body>
    </html>
    

    结果:

    image.png

    另外: 添加一个自定义指令,有两种方式:

    • 通过 Vue.directive() 函数注册一个全局的指令。
    • 通过组件的 directives 属性,对该组件添加一个局部的指令。

    创建全局指令:
    需要传入指令名称以及一个包含指令钩子函数的对象,该对象的键即钩子函数的函数名,值即函数体,钩子函数可以有多个。

    Vue.directive('self_defined_name',{
      bind:function(el,binding){
      //do someting
      },
      inserted: function(el,binding){
      //do something
      },
    }
    

    创建局部指令:
    直接向创建的 Vue 实例的 directives 字典属性添加键值对,键值对即需要添加的自定义指令及对应钩子函数字典对象。键值对可以有多个,对应多个自定义指令。

    new Vue({
      el:'#app',
      directives:{
        self_defined_name1:{
            bind:function(el,binding){
              //do something
            }
            inserted:function(el,binding){
                      //do something
            },
         }
    
        self_defined_name2:{
            bind:function(el,binding){
              //do something
            }
            inserted:function(el,binding){
                      //do something
            },
         }
      }
    
    })  
    

    二:路由

    Vue.js 路由允许我们通过不同的 URL 访问不同的内容。
    通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)。

    Vue.js 路由需要载入 vue-router 库
    中文文档地址:vue-router文档

    安装

    1、直接下载 / CDN

    https://unpkg.com/vue-router/dist/vue-router.js
    

    NPM
    推荐使用淘宝镜像:

    cnpm install vue-router
    

    简单实例
    Vue.js + vue-router可以很简单的实现单页应用。
    <router-link>是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。
    以下实例中我们将 vue-router加进来,然后配置组件和路由映射,再告诉 vue-router在哪里渲染它们。代码如下所示:
    HTML 代码:

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
     
    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    

    JavaScript 代码:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script>
    </head>
    <body>
    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    
    <script>
    // 0. 如果使用模块化机制编程,導入Vue和VueRouter,要调用 Vue.use(VueRouter)
    
    // 1. 定义(路由)组件。
    // 可以从其他文件 import 进来
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }
    
    // 2. 定义路由
    // 每个路由应该映射一个组件。 其中"component" 可以是
    // 通过 Vue.extend() 创建的组件构造器,
    // 或者,只是一个组件配置对象。
    // 我们晚点再讨论嵌套路由。
    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    ]
    
    // 3. 创建 router 实例,然后传 `routes` 配置
    // 你还可以传别的配置参数, 不过先这么简单着吧。
    const router = new VueRouter({
      routes // (缩写)相当于 routes: routes
    })
    
    // 4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    const app = new Vue({
      router
    }).$mount('#app')
    
    // 现在,应用已经启动了!
    </script>
    </body>
    </html>
    

    结果:点击蓝色的按钮 下面的黑色字体就会改变


    image.png

    点击过的导航链接都会加上样式 class ="router-link-exact-active router-link-active"

    <router-link> 相关属性

    接下来我们可以了解下更多关于 <router-link> 的属性。

    to

    表示目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

    <!-- 字符串 -->
    <router-link to="home">Home</router-link>
    <!-- 渲染结果 -->
    <a href="home">Home</a>
    
    <!-- 使用 v-bind 的 JS 表达式 -->
    <router-link v-bind:to="'home'">Home</router-link>
    
    <!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
    <router-link :to="'home'">Home</router-link>
    
    <!-- 同上 -->
    <router-link :to="{ path: 'home' }">Home</router-link>
    
    <!-- 命名的路由 -->
    <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
    
    <!-- 带查询参数,下面的结果为 /register?plan=private -->
    <router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
    
    replace

    设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。

    <router-link :to="{ path: '/abc'}" replace></router-link>
    
    append

    设置 append 属性后,则在当前 (相对) 路径前添加其路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

    <router-link :to="{ path: 'relative/path'}" append></router-link>
    
    tag

    有时候想要 <router-link> 渲染成某种标签,例如 <li>。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。

    <router-link to="/foo" tag="li">foo</router-link>
    <!-- 渲染结果 -->
    <li>foo</li>
    
    active-class

    设置 链接激活时使用的 CSS 类名。可以通过以下代码来替代。

    <style>
       ._active{
          background-color : red;
       }
    </style>
    <p>
       <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
       <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
    </p>
    

    注意这里 class 使用 active-class="_active"。

    exact-active-class

    配置当链接被精确匹配的时候应该激活的 class。可以通过以下代码来替代。

    <p>
       <router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
       <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
    </p>
    
    event

    声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。

    <router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>
    

    以上代码设置了 event 为 mouseover ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。

    NPM 路由实例

    接下来我们演示了一个使用 npm 简单的路由实例,开始前,请先下载该实例源代码,在 Github 上下载::https://github.com/chrisvfritz/vue-2.0-simple-routing-example
    下载完后,解压该目录,重命名目录为 vue-demo,vu 并进入该目录,执行以下命令:

    # 安装依赖,使用淘宝资源命令 cnpm
    cnpm install
    
    # 启动应用,地址为 localhost:8080
    cnpm run dev
    

    如果你需要发布到正式环境可以执行以下命令:

    cnpm run build
    

    执行成功后,访问 http://localhost:8080 即可看到如下界面:

    image.png

    相关文章

      网友评论

          本文标题:Vue-(5)自定义指令-路由

          本文链接:https://www.haomeiwen.com/subject/kocibltx.html