插槽、自定义指令、render函数、过滤器、插件

1.插槽

普通插槽,具名插槽,作用域插槽

插槽允许我们在调用子组件的时候为子组件传递模板。

<slot> 元素作为承载分发内容的出口。 一个不带 name 的 <slot> 出口会带有隐含的名字“default”。

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

 ### 1.默认插槽
    没有名字的插槽就是默认插槽
    <slot>123</slot>
    <slot name="default">123</slot>
### 2. 具名插槽
    具有名字的插槽
    <slot name="slot2">123</slot>
### 3.插槽填充
    <my-com>hello</my-com>
    内容填充到模板的哪个插槽中?
    指定插槽
    <my-com>
      <template v-slot:default>
        hello
      </template>
      <template v-slot:slot>
        123
      </template>
      <template #slot>
        123
      </template>
    </my-com>
### 插槽声明 {template:`<slot>插槽默认模板</slot>`}
    插槽模板
    ### 1.默认模板
    <slot>插槽默认模板</slot>
    ### 2.自定义模板
    <my-com>
      <template #name>
        插槽自定义模板
      </template>
    </my-com>
  在插槽默认模板中,可以直接访问子组件的数据,可以通过props间接访问父组件的数据
  在插槽自定义模板中,可以直接访问父组件的数据,可以通过插槽属性间接访问子组件的数据(插槽作用域)

<!DOCTYPE html>
<html lang="en">
​
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
</head>
​
<body>
    <div id="app">
        <my-a :arr="arr">
            <div>我是子组件</div>
            <template v-slot:header> 开始的内容</template>
            <template v-slot:center> 中间的内容</template>
            <template v-slot:footer> 结束的内容</template>
            <template slot-scope="scope"> {{scope.row}}</template>
        </my-a>
    </div>
    <script>
        let myA = {
            props: ['arr'],
            data() {
                return {
                    msg: '222'
                }
            },
            template: `
            <div>
                A组件
                <slot name='default'></slot>
                <div class="header"><slot name='header'></slot></div>
                <div class="center" >
                    <slot name='center'></slot>
                </div>
                <div class="footer"><slot name='footer'></slot></div>
                <ul>
                    <li v-for="item in arr">
                        <slot  v-bind:row='item'></slot>
                    </li>
                </ul>
            </div>
            `
        };
        Vue.component('my-a', myA)
        new Vue({
            el: "#app",
            data: {
                arr: [1, 2, 3, 4]
            },
            methods: {}
        })
    </script>
</body>
​
</html>

2.自定义指令

directive

Vue中多有的指令都以 v- 来调用。但是,有时候Vue提供给我们的指令并不能满足我们的需求,这个时候 我们就需要自定义指令。

指令允许我们对普通 DOM 元素进行底层操作。可以全局注册也可以局部注册

全局注册

使用Vue.directive

局部注册

在Vue实例或组件中添加新的选项directives

钩子函数

钩子函数可以在指令的生命周期内的关键时刻加入代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
</head>
<body>
    <div id="app">
        <input v-focus="msg" type="text" >
        {{msg}}
        <input v-myshow="msg" type="text" >
    </div>
    <script>
        Vue.directive('focus',{
            inserted(el){
                el.focus()
            },
            bind(el,binding,vnode){
                el.style.backgroundColor=binding.value
            }
        })
        new Vue({
            directives:{
                'myshow':{
                    inserted(el){
                    },
                    bind(el,binding,vnode){
                        el.value=binding.value;
                    }
                }
            },
            el:"#app",
            data:{
                msg:'red'
            },
            methods:{}
        })
    </script>
</body>
</html>

3.render渲染函数

Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <my-a  :friuts="friuts">
            列表
        </my-a>
    </div>
    <script>
        let myA={
            props:{
                friuts:{
                    type:Array,
                }
            },
            beforeMount(){
                alert('beforeMount')
            },
            mounted(){
                alert('mounted')
            },
            render(h){
                alert('2222')
                let lis=this.friuts.map(item=>{
                    return h('li',{},item)
                })
                return h('ul',{},[this.$slots.default,...lis])
            },
            // template:`
            //  <div>
            //      <ul>
            //          <li v-for='item in friuts'>{{item}}</li>    
            //      </ul>
            //  </div>
            // `,
            data(){
                return {
                    
                }
            }
        }
        new Vue({
            components:{
                'my-a':myA
            },
            el:"#app",
            data:{
                friuts:['苹果','香蕉','菠萝']
            },  
            methods:{}
        })
    </script>
</body>
</html>

4.过滤器

Vue.js 允许自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”|符号指示:

<!-- 在双花括号中 --> {{ message | filterMethod }} <!-- 在 `v-bind` 中 -->

​​

首先引入 `moment`第三方库,再进行接下来的操作。引入moment仅供实现功能,与过滤器没有关系。
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/locale/af.js"></script>
<script>
    // 全局注册
    Vue.filter("fmtDate_global", function (date) {
        return moment(date).format("YYYY-MM-DD HH:mm:ss");
        // 或者return自己编写的时间处理函数
    })
    new Vue({...})
</script>

<!DOCTYPE html>
<html lang="en">
​
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello world</title>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
</head>
​
<body>
  <div id="app">
    <!-- 使用过滤器 -->
    <div>{{ new Date() | fmtDate_global}}</div>
    <div :title="new Date() | fmtDate_global">鼠标悬停查看时间</div>
  </div>
  <script>
    // 全局注册过滤器
    Vue.filter("fmtDate_global", function (date) {
      return moment(date).format("YYYY-MM-DD HH:mm:ss");
     
    })
    new Vue({
      el: '#app',
    })
  </script>
</body>
​
</html>

5.插件

plugin

插件通常用来为 Vue 添加全局功能。Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或 property
Vue.myGlobalMethod = function () {
 // 逻辑...
}
​
// 2. 添加全局资源
Vue.directive('my-directive', {
 bind (el, binding, vnode, oldVnode) {
   // 逻辑...
 }
 ...
})
​
// 3. 注入组件选项
Vue.mixin({
 created: function () {
   // 逻辑...
 }
 ...
})
​
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
 // 逻辑...
}
}

通过全局方法 Vue.use() 使用插件。它需要在你调用 new Vue() 启动应用之前完成:

// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
​
new Vue({
// ...组件选项
})
<!DOCTYPE html>
<html lang="en">
​
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
​
</head>
​
<body>
    <div id="app">
        {{time | fmtTime}}
        <input type="text" v-focus>
    </div>
    <script>
        let MyPlugin = {
            install(Vue, options) {
                Vue.filter('fmtTime', (val) => {
                    return moment(val).format('YYYY--MM-DD')
                }),
                Vue.prototype.$message=function(val){
                    alert(val)
                },
                    Vue.directive('focus', {
                        inserted(el) {
                            el.focus()
                        },
                        bind(el, binding, vnode) {
                            el.style.backgroundColor = binding.value
                        }
                    })
            },
        };
        Vue.use(MyPlugin)
        new Vue({
            el: "#app",
            data: {
                time: new Date().getTime()
            },
            created(){
                this.$message('请求成功')
            },
            methods: {}
        })
    </script>
</body>
​
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值