接着前面的内容:https://www.cnblogs.com/yanggb/p/12563162.html

模板语法

vue使用了基于html的模板语法,允许开发者声明式地将dom绑定到底层vue实例的数据。所有vue的模板都是合法的html,因此能被遵循规范的浏览器或html解析器解析。在底层的实现上,vue将模板编译成虚拟dom渲染函数,并结合响应系统,智能地计算出最少需要重新渲染多少组件,来将dom操作的次数减到最少。

插值-文本

数据绑定最常见的形式就是使用mustache语法(双大括号)的文本插值。

<span>i love {{ someone }}.</span>

mustache标签(双大括号)中的内容将会被替代为对应数据对象上someone的值,比如如果【someone】的值是【yanggb】,那么页面上渲染的内容就会是【i love yanggb.】。无论任何时候,只要绑定的数据对象上someone的属性值发生了改变,插值处的内容也会被同步更新。另外,如果你想要插值中的数据只能被替换一次的话,可以使用【v-once】指令,这个指令的作用是限制插值的内容只会被更新一次,之后无论多少次改变someone的值,插值处的内容都一直是【i love yanggb forever.】。

<span v-once>i love {{ someone }} forever.</span>

使用【v-once】指令的时候要格外注意不要影响到该节点上的其他数据绑定。

插值-原始html

双大括号会将数据解释为普通文本,而非html代码。为了输出真正的html,你会需要使用【v-html】指令。

<p>使用mustache语法: {{ rawHtml }}</p>
<p>使用v-html指令: <span v-html="rawHtml"></span></p>

这个时候,如果rawHtml的值是'<span>我是原始的html代码</span>'的话,使用mustache语法会将此字符串原样输出,而使用【v-html】指令,则会被解析成html渲染。要注意的是,不应该选择使用【v-html】指令来复合局部模板,因为vue不是基于字符串的模板引擎,这样做可能会造成意料之外的问题。再说了,vue还提供了组件这样的特性,组件在用户界面(UI)中更适合作为可重用和可组合的基本单位。

你的站点上动态渲染的任意HTML可能会非常危险,因为它很容易导致XSS 攻击。请只对可信内容使用HTML插值,绝不要对用户提供的内容使用插值。

官方文档上特别注明了使用【v-html】指令进行原始html插值是一项可能造成危险的行为,因此建议在开发中禁止使用这个语法,除非有非用不可的理由,将危险扼杀在摇篮里,只要知道有这个语法就可以了。

插值-attribute(属性)

因为mustache语法并不能作用在html的attribute上,因此vue提供了【v-bind】指令来满足这一场景。

<div v-bind:id="dynamicId"></div>

而对于布尔attribute来说,它们只要存在就意味着值为true,比如disabled属性,因此使用【v-bind】指令的时候会与常规的使用javascript操作原生html的方式有所不同。

<button v-bind:disabled="isButtonDisabled">Button</button>

在上面这个例子中,如果isButtonDisabled的值是null、undefined或false的话,disabled这个attribute是不会被包含在渲染出来的<button>元素中的。

使用javascript表达式

在前面的例子中,在模板中都是绑定的简单的属性键值。而实际上,对于所有的数据绑定,vue都提供了完全的javascript表达式支持。

{{ number + 1 }}

{{ ok ? 'yes' : 'no' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

这些表达式会在所属vue实例的数据作用域下作为javascript被解析。但是有个限制是,每个绑定都只能包含单个表达式,非单个表达式的话,数据绑定会失效,可能导致表达式被原样输出,甚至导致直接报错。

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }} <!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

此外,模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如Math和Date,开发者不应该在模板表达式中试图访问用户定义的全局变量。

/* not type checking this file because flow doesn't play well with Proxy */

import config from 'core/config'
import { warn, makeMap, isNative } from '../util/index' let initProxy if (process.env.NODE_ENV !== 'production') {
const allowedGlobals = makeMap(
'Infinity,undefined,NaN,isFinite,isNaN,' +
'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
'require' // for Webpack/Browserify
) const warnNonPresent = (target, key) => {
warn(
`Property or method "${key}" is not defined on the instance but ` +
'referenced during render. Make sure that this property is reactive, ' +
'either in the data option, or for class-based components, by ' +
'initializing the property. ' +
'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
target
)
} const warnReservedPrefix = (target, key) => {
warn(
`Property "${key}" must be accessed with "$data.${key}" because ` +
'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
'prevent conflicts with Vue internals' +
'See: https://vuejs.org/v2/api/#data',
target
)
} const hasProxy =
typeof Proxy !== 'undefined' && isNative(Proxy) if (hasProxy) {
const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact')
config.keyCodes = new Proxy(config.keyCodes, {
set (target, key, value) {
if (isBuiltInModifier(key)) {
warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`)
return false
} else {
target[key] = value
return true
}
}
})
} const hasHandler = {
has (target, key) {
const has = key in target
const isAllowed = allowedGlobals(key) ||
(typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
if (!has && !isAllowed) {
if (key in target.$data) warnReservedPrefix(target, key)
else warnNonPresent(target, key)
}
return has || !isAllowed
}
} const getHandler = {
get (target, key) {
if (typeof key === 'string' && !(key in target)) {
if (key in target.$data) warnReservedPrefix(target, key)
else warnNonPresent(target, key)
}
return target[key]
}
} initProxy = function initProxy (vm) {
if (hasProxy) {
// determine which proxy handler to use
const options = vm.$options
const handlers = options.render && options.render._withStripped
? getHandler
: hasHandler
vm._renderProxy = new Proxy(vm, handlers)
} else {
vm._renderProxy = vm
}
}
} export { initProxy }

上面这段代码是vue中定义全局变量的访问白名单,因为用户自定义的全局变量不在白名单内,在模板表达式中访问将会出现问题。

指令

指令(directives)是带有【v-】前缀的特殊attribute。指令attribute的值预期是单个javascript表达式(v-for是个例外)。指令的职责是,当表达式的值发生改变的时候,就将其产生的连带影响,响应式地作用到dom中。

参数

一些指令是能够接收一个参数的,这个参数跟在指令的后面,以冒号表示。

比如,可以使用【v-bind】指令响应式地更新html的attribute。

<a v-bind:href="url">...</a>

在这里,href是参数,作用是告知【v-bind】指令将该元素的href属性与表达式url的值进行绑定。

又比如,可以使用【v-on】指令监听dom事件。

<a v-on:click="doSomething">...</a>

在这个例子中,这样写就给这个<a>元素绑定了click点击事件。

动态参数

从2.6.0开始,可以用方括号括起来的javascript表达式作为一个指令的参数。

<!-- 注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。-->
<a v-bind:[attributeName]="url"> ... </a>

这里的attributeName会被作为一个javascript表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的vue实例有一个data属性attributeName,其值为href的话,那么这个绑定将等价于【v-bind:href】。

同样的,你可以使用动态参数为一个动态的事件名绑定处理函数。

<a v-on:[eventName]="doSomething"> ... </a>

在上面的这个例子中,当eventName的值为【focus】的时候,这个绑定将等价于【v-on:focus】。

对动态参数值的约束

动态参数预期会求出一个字符串,异常情况下值为null,这个特殊的null值可以被显性地用于移除绑定,任何其他非字符串类型的值都将会触发一个警告。

<a v-on:[eventName]="doSomething"> ... </a>

比如在上面这个例子中,如果eventName的值为null,那么这个<a>标签就不会被绑定任何dom事件了。

对动态参数表达式的约束

动态参数表达式有一些语法约束,因为某些字符,比如空格和引号,放在html的属性名里是无效的。

<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>

变通的办法是使用没有空格或者引号的表达式,或使用计算属性替代这种复杂的表达式。

另外,在dom中使用模板的时候(直接在一个html文件中编写模板),还需要避免使用大写字符来命名键名,因为浏览器会把attribute名全部强制转换为小写。

<!-- 在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。-->
<a v-bind:[someAttr]="value"> ... </a>

动态参数的使用场景在现有的开发场景中并没有使用到,大概只有特殊的场景才会用得上,有所了解就好了。

修饰符

修饰符(modifier)是以半角句号【.】指明的特殊后缀,用于指出一个指令应该以特殊的方式绑定。例如【.prevent】修饰符的作用是告诉【v-on】指令对于触发的事件调用【event.preventDefallut()】方法。

<form v-on:submit.prevent="onSubmit">...</form>

这个语法在一些特定的场景中十分有用,后面会详细了解。

缩写

【v-】前缀作为一种视觉提示,可以用于识别模板中vue特定的attribute。虽然在使用vue为现有的标签添加动态行为(dynamic behavior)的时候【v-】前缀会很有帮助,但是对于一些频繁使用到的指令来说,反复编写相同的代码就会让开发者觉得厌烦。同时,在构建由vue管理所有模板的单页面应用程序(SPA,single page application)的时候,【v-】前缀也变得没有那么重要了。因此,vue为【v-bind】和【v-on】这两个最常用的指令提供了特定的缩写,方便开发者编写vue应用程序。

【v-bind】指令的缩写

<!-- 完整语法 -->
<a v-bind:href="url">...</a> <!-- 缩写 -->
<a :href="url">...</a> <!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>

【v-on】指令的缩写

<!-- 完整语法 -->
<a v-on:click="doSomething">...</a> <!-- 缩写 -->
<a @click="doSomething">...</a> <!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

虽然它们看起来可能和普通的html略有不同,但是【:】和【@】对于attribute名来说都是合法字符,在所有支持vue的浏览器中都能被正确解析,而且它们并不会出现在最终渲染的标记中。缩写语法是完全可选的,你在编写vue应用的时候,完全可以选择完整的语法或使用缩写的语法,但是随着你深入的使用缩写语法和了解它们的作用,你会像我一样喜欢上缩写的语法。

"我还是很喜欢你,像日月轮回交替,不问朝夕。"

vue2.x学习笔记(四)的更多相关文章

  1. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  2. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  3. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  5. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  7. vue2.0学习笔记之路由(二)路由嵌套+动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. vue2.0学习笔记之路由(二)路由嵌套

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制

    目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...

  10. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

随机推荐

  1. 记录一个不同的流媒体网站实现方法,和用Python爬虫爬它的坑

    今天找到一片电影,想把它下载下来. 先开Networks工具分析一下: 初步分析发现,视频加载时会拉取TS格式的文件,推测这是一个m3u8的索引,记录着几百段TS文件,这样方便快进时加载. 但是实际分 ...

  2. vscode vue 模版生成,vue 一键生成

    vscode vue 模版 继上篇文章(vue 格式化),顺便记录下 vue 模版生成.图片就不在贴了,如果有找不到 vscode 插件商店的可以访问上篇文章. 一.安装 VueHelper 在 vs ...

  3. Downgrade ASM DATABASE_COMPATIBILITY (from 11.2.0.4.0 to 11.2.0.0.0) on 12C CRS stack.

    使用Onecommand完成快速Oracle 12c RAC部署后 发现ASM database compatibilty无法设置,默认为11.2.0.4.0. 由于我们还有些数据库低于这个版本,所以 ...

  4. [bzoj1029]建筑抢修<贪心>

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1029 解析:这也算bzoj中比较简单的一道题,其实想通了就是非常的简单. 这题用贪心的方式 ...

  5. windows使用的奇淫技巧

    找回刚才打开的网页 记事本 特殊符号输入 窗口变化为1/2,1/4 批量重命名 复制文件路径 万能命令

  6. Linux - Ubuntu18.04下更改apt源为阿里云源

    进入apt目录,备份原来的源地址 cd /etc/apt mv ./source.list ./source.list.bak 修改源文件source.list vim source.list 更换阿 ...

  7. Java中的get()方法和set()方法

    在Java中,为了数据的安全,换句话说就是为了隐藏你的代码的一些实现细节,我们会用private来修饰属性,使用private修饰的属性就不能被其他类直接访问了,想要访问就需要通过set.get方法: ...

  8. PTA数据结构与算法题目集(中文) 7-32

    PTA数据结构与算法题目集(中文)  7-32 7-32 哥尼斯堡的“七桥问题” (25 分)   哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示. 可否走过这样的七 ...

  9. PTA数据结构与算法题目集(中文) 7-10

    PTA数据结构与算法题目集(中文)  7-10 7-10 公路村村通 (30 分)   现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低 ...

  10. 浅谈Java构造器

    Java构造器 每个类都有构造方法.如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法. 在创建一个对象的时候,至少要调用一个构造方法.构造方法的名称必须与类同名,一个类可以 ...