Vue学习笔记 - 模板template

259 阅读1分钟

模板的三种引入方法

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'