模板的三种引入方法
1、Vue 完整版,写在 HTML 中
HTML:
<div id='app'>
{{n}}
<button @click='add'>+1</button>
</div>
JS:
new vue({
el: '#app',
data: {n:0}, // data 也可用函数
methods: {add(){}}
)
2、Vue 完整版,写在 options 中
new Vue({
template:`
<div>
{{n}}
<button @click='add'>+1</button>
</div>
`,
data: {n:0}, // 可用函数
methods:{add(){}},
el:'#app'
})
【注】:这种写法,原 HTMl 中的 div#app 会被替换
3、Vue 非完整版,写在 .vue 文件中
xxx.vue 文件:
<template>
<div>
{{n}}
<button @click='add'>+1</button>
</div>
</template>
<script>
export default {
data(){ return {n:0} } //!!!!此处必须写为函数
methods:{add(){}}
}
</script>
<style>
此处CSS
</style>
随后在 JS 中引入,使用 render 函数:
import Xxx from './xxx.vue' //经过 vue-loader,Xxx是一个 options 对象
new Vue({
render: h => h(Xxx)
}).$mount('#app')
【注】:
template 中并非 HTML,而是 XML。XML 的语法比 HTML 更为严格,每个标签必须有闭合符号。
XML 写法 ----
<input />HTML 写法 ----
<input>或<input />XML 的严格语法便于模板编译器进行编译。
模板的语法
指令(Directive)
指令的形式为:v-指令名:参数=值,是模板中的核心功能
1、v-text ---- 展示表达式的值
<div v-text="表达式"></div> //展示表达式的值
但这种写法稍复杂,通常用更简洁的{{ }}:
- {{ obj.a }} ---- 展示 data.obj.a 的值
- {{ n + 1 }} ---- 展示 data.n + 1
- {{ fn() }} ---- 调用 methods.fn,展示返回值
若值为 undefined 或 null,则不显示。
2、v-html ---- 展示富文本内容(如 HTML)
例如,data.x 值为 '<strong>hi</strong>',要展示解析后的结果,而并非字符串本身:
<div v-html="x"></div>
3、v-pre ---- 展示 {{ n }} 本身
<div v-pre>{{ n }}</div>
v-pre 不会对模板进行编译
4、v-bind:属性名 ---- 绑定属性
- 例
<img v-bind:src="x" /> //绑定src
<div v-bind:style="{border: '1px solid red', height: 100}"> //绑定style,它的值是一个对象
- 简写 ----
:属性名
<img :src="x" />
5、v-on:事件名 ---- 绑定事件
- 例
<button v-on:click="add">+1</button> //点击后 Vue 会执行 add()
<button v-on:click="add(1)">+1</button> //点击后执行 add(1)
<button v-on:click="n+=1">+1</button> //点击后执行 n+=1
问题:第二种用法,如果 add 的返回值是一个函数,希望将 add(1) 得到的函数作为事件处理函数,怎么办?
------> 无解,不要这样写
- 简写 ----
@事件名
<button @click="add">+1</button>
6、v-if v-else v-else-if ---- 条件判断
条件为真,则插入 DOM 中
<div v-if="x>0"> x大于0 </div>
<div v-else-if="x===0"> x等于0 </div>
<div v-else="x<0"> x小于0 </div>
7、v-show ---- 显示、隐藏
元素已在 DOM 中,指定其何时显示(控制 display: none / block),与 v-if 区分
<div v-show="n%2===0"> n是偶数 </div>
其近似等价于:
<div :style="{display: n%2===0?'block':'none'}"> n是偶数 </div>
8、v-for ---- 循环结构
- 写法:
v-for="(value, key) in obj/arr"
<ul>
<li v-for="(u, index) in users" :key="index">
索引:{{index}} 值:{{u}}
</li>
</ul>
<ul>
<li v-for="(value, name) in users" :key="name">
属性名:{{name}} 属性值:{{value}}
</li>
</ul>
- 【注】:
- 必须要带上
:key :key="index"有 bug
- 必须要带上
9、v-once ---- 只渲染一次
使用v-once的元素及其子节点只在第一渲染,之后不再更新(静态)。
修饰符
某些指令支持附加修饰符,如:
@click.stop="add" //阻止事件冒泡/传播
其中的.stop就是v-on指令的修饰符
多个修饰符可以连用:
@click.stop.prevent="add" //阻止冒泡,阻止默认动作
常用修饰符
1、 v-on的修饰符
.{keycode | keyAlias}
<input @keypress.13="fn" /> //按下 keycoe 为 13 的键执行 fn
<input @keypress.enter="fn" /> //按下 enter 键执行 fn
Vue 提供了一些 keycode 的别名
.stop---- 阻止冒泡.prevent---- 阻止默认动作
2、v-bind的修饰符
.sync
考虑一个常见的情景:
子组件接受来自父组件的外部数据,Vue 规定组件不可修改外部数据 props,那要如何修改呢?
子:
<template>
{{cData}}
<button @click="???">修改cData</button>
</template>
<script>
export default {
props: ["cData"]
}
</script>
父:
<template>
<div>
{{pData}}
<Child :cData="pData" />
</div>
</template>
<script>
import Child from './Child.vue'
export default {
data(){
return {
pData: 1000
}
},
components: {Child}
}
</script>
子组件不可修改cData,只能让父组件修改pData。
先让子组件在点击按钮时触发一个事件'update:cData',使用vm.$emit方法:
<button @click="$emit('update:cData', cData - 100)">修改cData</button>
此时,用vm.$event便可以获取$emit的第二个参数,即cData - 100
在父组件的子组件元素监听'update:cData'事件,将pData改为vm.$event即可:
<Child :cData="pData" v-on:update:cData="pData = $event" />
这样的写法很麻烦,用.sync修饰符可以大大简化:
<Child :cData.sync="pData" />
使用.sync前提是子组件触发事件名必须为'update:cData'