栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

Vue 模板书写注意点

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vue 模板书写注意点

关于 Vue 模板的语法,官方文档做了比较详细的介绍,建议读者先阅读完官网文档再继续阅读本文后续内容。

下面介绍一些比较特殊的或者说需要注意的点。

v-bind 绑定对象

通过 v-bind 可以给组件传递 prop 数据,比如有组件 A :

那么给该组件传递 name 和 age 属性就可以写成这样:

注意,在传递 prop 数据的时候,模板里面的键名和声明处的键名对应是有讲究的:在模板里面,要么严格按照声明处的大小写,要么按照声明处的键名经过类似于 lodash 中 snakeCase 转换之后的形式书写。

比如对于声明处的 anotherProp 属性,在模板里面对应写上 或者 ,是没有问题的。

如果写成 或者 ,就会对应失败。(后面一种写法会在 DOM 树中看到 another-prop attribute )

虽然,大部分时候,都不用太去关心模板标签和属性的大小写问题(毕竟绝大多数时候写的都是 HTML 模板),但是有的属性,还是要小心处理大小写问题的,比如 svg 的 viewBox 属性:



  
  
  

默认情况下,对于传递的未声明的属性,都会采用 setAttribute 设置到相应 DOM 元素上面去,比如:

这个 some-prop 会通过 setAttribute 设置到 A 组件根元素的属性上面去。

而对于一些特殊属性,是需要设置到 DOM 元素对象上去的,比如 input[type="checked"] 的 checked 属性。对于这些属性, Vue 内部做了默认配置,当然也可以通过全局的 Vue.config.mustUseProp 配置覆盖默认配置。

另外,通过 v-bind 的 prop 修饰符,可以直接给相应的 DOM 节点对象设置属性,比如:

会被转换成大致如下代码:

// 属性名做驼峰转换divElement.nameAttr = 'haha';

注意,如下形式写法:

会被转换成大致如下代码:

divElement.setAttribute('name-attr.prop', 'haha');

如果 div 换成 A 组件,那么相应的属性操作就会发生在 A 组件的根元素上面。

最后,通过 v-bind 可以批量动态地设置属性:

Vue diff

Vue diff 逻辑有很多文章都做了介绍,可以参看这篇文章。

此处主要强调由于 diff 算法,而造成的写模板必须注意的点。

key

官方有一些关于 key 的介绍。

在实际开发中, key 主要用于解决同级 DOM 元素复用引起的 bug ,以及做列表渲染优化。

在列表渲染中, Vue 会尽量复用已有 DOM 节点元素。默认情况下,对于被循环元素,会有 :key="index" 的设置,对于这中默认渲染模式,官网有一句非常非常重要的描述:

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

有两个需要搞清楚的点:

  • 什么是子组件状态?

    子组件状态就是不受 prop 属性控制的状态。比如组件 B :

    对于组件 B 来说, instanceCounter 就是子组件状态。

  • 什么是临时 DOM 状态?

    基本所有未受 Vue prop 控制的,但是自身又能随交互变化的状态,都算作临时 DOM 状态。比如不受控制的 input.value 、 input.checked 等等。

从根本原理上来讲,所有没在 VNode 中的 data 属性上表达的状态,都算是相应组件或 DOM 节点的内部状态,都会存在 key 风险。

明确了上面两个概念之后,我们看一个例子:

import Vue from 'vue';import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options';let counter = 1;const Item: ThisTypedComponentOptionsWithRecordProps = {
    template: ' --{{ instanceCounter }}--',
    data() {        return {
            instanceCounter: counter++
        };
    }
};
Vue.component('Item', Item);const KeyComponent: ThisTypedComponentOptionsWithRecordProps;}, {}, {}, {}> = {
    template: `
        
            {{ item.id }}
            +
        
    `,
    data() {        return {
            items: [
                {
                    id: '123'
                },
                {
                    id: '456'
                }
            ]
        };
    },
    methods: {
        add() {            this.items.splice(1, 0, {
                id: '789'
            });
        }
    }
};

Vue.component('KeyComponent', KeyComponent);new Vue({
    el: '#app',
    template: ''});

在第一次点击 KeyComponent 组件中的按钮之后,输出结果为:

123 --1--
789 --3--
456 --2--

如果去掉 KeyComponent 中 Item 的 key 属性设置,然后刷新页面,第一次点击 KeyCOmponent 组件中的按钮,输出结果为:

123 --1--
789 --2--
456 --3--

可以看出,只有加了正确的 key ,新插入的 768 组件才会对应到新创建的组件。

render

render 方法必须要返回一个 VNode 实例。

如果想返回一个文本节点怎么办呢?

可以借助于 createElement() 实现:

import Vue from 'vue';import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options';const Test: ThisTypedComponentOptionsWithRecordProps = {
    render(createElement) {        const nodes = createElement('div', '文本内容').children;        if (!nodes) {            throw new Error('error');
        }        return nodes[0];
    }
};
Vue.component('Test', Test);



作者:yibuyisheng
链接:https://www.jianshu.com/p/4d17c666f2c1


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/241569.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号