vue计算属性、内容分发、自定义事件


计算属性、内容分发、自定义事件

计算属性

计算出来的结果保存在属性中。内存中运行,是一个能将计算结果缓存起来的属性(成为静态属性),可以视作缓存。

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层:模版-->
<div id="app-4">
    <!--两种调用等价-->
    <p>currentTime1: {{currentTime1}}</p>
    <p>currentTime2: {{currentTime2()}}</p>
</div>

<!-- 导入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app4 = new Vue({
        el: '#app-4',
        data: {
            msg: "hello, vue!"
        },
        computed: {     //计算属性,computed 和 methods 方法名不能重名,否则优先调用方法名
            currentTime1: function () {
                this.msg;   //当数据发生变动(增、删、改)时,计算属性才会重新生成,并保存到缓存中
                return Date.now();
            }
        },
        methods: {
            currentTime2: function () {
                return Date.now();
            }
        }
    })
</script>

</body>
</html>

内容分发

为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发 (或 “transclusion” )

Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 元素作为承载分发内容的出口。

在 2.6.0 中,为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。

规则:

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

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层:模版-->
<div id="app-4">
    <todo>
    <!--slot: 插槽-->
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
    </todo>
</div>

<!-- 导入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

    Vue.component("todo",{
        template:
            '<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });

    Vue.component("todo-title",{
        props: ['title'],
        template: '<div>{{title}}</div>'
    });

    Vue.component("todo-items",{
        props: ['item'],
        template: '<li>{{item}}</li>'
    });

    var app4 = new Vue({
        el: '#app-4',
        data: {
            title: "书籍列表",
            todoItems: ["java", "py", "c"]

        }
    })
</script>


</body>
</html>

结果

自定义事件

最终效果:点击删除按钮后,可以更改相应数据,并实时传递给视图

例:点击 py 后的 “删除” 按钮,呈现效果如下:

QQ图片20201218212449

组件内部绑定事件, 需要用到 this.$emit(“事件名”,参数)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层:模版-->
<div id="app-4">
    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <!--  :index="index" 给模版参数赋值,:是v-bind的缩写 @是v-on的缩写 remove222是自定义方法名-->
        <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item="item" :index="index" @remove222="removeItems(index)"></todo-items>
    </todo>
</div>

<!-- 导入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

    Vue.component("todo",{
        template:
            '<div>\
                <slot name="todo-title"></slot>\
                <ul>\
                <slot name="todo-items"></slot>\
                </ul>\
            </div>'
    });

    Vue.component("todo-title",{
        props: ['title'],
        template: '<div>{{title}}</div>'
    });

    Vue.component("todo-items",{
        props: ['item'],
        //定义方法 remove111() 在同一个对象中
        template: '<li>{{item}}<button @click="remove111">删除</button></li>',
        methods: {
            remove111: function () {
                //自定义事件分发
                //通过 this.$emit 将自定义方法与组件方法绑定,参数依次为【自定义方法名,入参】
                this.$emit('remove222',this.index);
            }
        }
    });

    var app4 = new Vue({
        el: '#app-4',
        data: {
            title: "书籍列表",
            todoItems: ["java", "py", "c"]
        },
        //只能绑定当前组件的方法
        methods: {
            removeItems: function (index) {
                //一次删除一个元素,splice()是js操作array的万能方法。参数为【开始索引,删除元素个数,添加元素内容(可省略)】
                this.todoItems.splice(index,1);
            }
        }
    })
</script>


</body>
</html>

文章作者: Hailong Gao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hailong Gao !
评论
  目录