Vue.js模版语法

319 阅读5分钟

新建Vue项目

image.png

或者命令创建启动项目,确保安装了node.js

npm create vue@latest

npm install

npm run dev

Router路由

命令创建时如果添加了Router路由项目中直接有路由相关代码,如果用IDEA创建需手动引入路由脚手架。

App.vue页面引入Router相关依赖包和布局

<script setup>  
...
import { RouterLink, RouterView } from 'vue-router' 
...
</script>

<template>
    <header>
        <img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125"/>

        <div class="wrapper">
            <HelloWorld msg="VUE"/>

            <nav>
                <RouterLink to="/">首页</RouterLink>
                <RouterLink to="/about">关于</RouterLink>
            </nav>
        </div>
    </header>

    <RouterView />
</template>

...

main.js添加router支持

import './assets/main.css'

import {createApp} from 'vue'
import App from './App.vue'
import router from './router'

createApp(App)
    .use(router)
    .mount('#app')

运行如下:

image.png

文本插值

<script>
export default {
    data() {
        return {
            msg: '最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号)',//文本
        }
    }
}
</script>

<template>
    <text>{{ msg }}</text>
</template>

运行效果:

image.png

原始HTML

双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令

<script>
export default {
    data() {
        return {
            rawHtml: '<span style="color: red">This should be red.</span>',//原始HTML
        }
    }
}
</script>

<template>
    <p>Using text interpolation: {{ rawHtml }}</p>
    <p>Using v-html directive: <span v-html="rawHtml"></span></p>
</template>

效果图:

image.png

Attribute绑定

双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令:简写可省略“:”前的v-bind

<script>
export default {
    data() {
        return {
            activeColor: 'green',
            fontSize: 20,
            isButtonDisabled: true,//按钮不可点击
        }
    }
}
</script>

<template>
        <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">
            我是Attribute绑定的样式。
        </div>
        <button :disabled="isButtonDisabled">布尔型Attribute</button>
</template>

效果图:

image.png

isButtonDisabled属性为true时按钮不可点击,为false时按钮可点击。

JavaScript表达式

Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式,下面是数值、布尔、字符串逆转的测试:

<script>
export default {
    data() {
        return {
            number: 5,
            ok: '123',
            message: '请把我倒着念出来',
        }
    }
}
</script>

<template>
        {{ number + 1 }} | {{ ok ? 'YES' : 'NO' }} | {{ message.split('').reverse().join('') }}
</template>

效果图:

image.png

调用函数

<script>
export default {
    data() {
        return {
            date: new Date().toISOString(),//日期
        }
    },
    methods: {
        // 将日期转换为标题格式
        toTitleDate(date) {
            const d = new Date(date);
            return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
        },
        // 格式化日期为更简洁显示格式
        formatDate(date) {
            const d = new Date(date);
            return d.toLocaleString('default', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                weekday: 'long',
                hour: 'numeric',
                minute: 'numeric',
                hour12: true
            });
        }
    }
}
</script>

<template>
        <time :title="toTitleDate(date)" :datetime="date">
            {{ formatDate(date) }}
        </time>
</template>

效果图:

image.png

更多属性参考:

    interface DateTimeFormatOptions {
        localeMatcher?: "best fit" | "lookup" | undefined;
        weekday?: "long" | "short" | "narrow" | undefined;
        era?: "long" | "short" | "narrow" | undefined;
        year?: "numeric" | "2-digit" | undefined;
        month?: "numeric" | "2-digit" | "long" | "short" | "narrow" | undefined;
        day?: "numeric" | "2-digit" | undefined;
        hour?: "numeric" | "2-digit" | undefined;
        minute?: "numeric" | "2-digit" | undefined;
        second?: "numeric" | "2-digit" | undefined;
        timeZoneName?: "short" | "long" | "shortOffset" | "longOffset" | "shortGeneric" | "longGeneric" | undefined;
        formatMatcher?: "best fit" | "basic" | undefined;
        hour12?: boolean | undefined;
        timeZone?: string | undefined;
    }

指令Directives

指令是带有 v- 前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的 v-bind 和 v-html

指令 attribute 的期望值为一个 JavaScript 表达式 (除了少数几个例外,即之后要讨论到的 v-forv-on 和 v-slot)。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。以 v-if 为例:

<script>
export default {
    data() {
        return {
            seen: true,//指令Directives,是否隐藏
        }
    }
}
</script>

<template>
        <p v-if="seen">Now you see me</p>
</template>

效果图:当seen属性为true时内容可见,为false时内容不可见。

参数Arguments

<script>
export default {
    data() {
        return {
           url: 'https://www.baidu.com',//属性值
           
        }
    },
    methods: {
        //onclick点击事件
        doSomething(event) {
            // 阻止a元素的默认行为(例如页面跳转)
            event.preventDefault();

            // 这里执行你需要的操作
            console.log('Link was clicked!');
        }
    }
}
</script>

<template>
        <a :href="url">百度一下,你就知道</a><br>
        <a @click="doSomething">v-on点击事件</a>
</template>

这里 href 就是一个参数,它告诉 v-bind 指令将表达式 url 的值绑定到元素的 href attribute 上。在简写中,参数前的一切 (例如 v-bind:) 都会被缩略为一个 : 字符。

这里的参数是要监听的事件名称:clickv-on 有一个相应的缩写,即 @ 字符。 效果图:

image.png

image.png

动态参数

<script>
export default {
    data() {
        return {
            url: 'https://www.baidu.com',//属性值
            attributeName: 'href', // 动态属性名
            eventName: 'click'
        }
    },
     methods: {
        //onclick点击事件
        doSomething(event) {
            // 阻止a元素的默认行为(例如页面跳转)
            event.preventDefault();

            // 这里执行你需要的操作
            console.log('Link was clicked!');
        }
    }
}
</script>

<template>
        <a :[attributeName]="url">百度一下,你就知道</a><br>
        <a @[eventName]="doSomething">动态参数</a>
</template>

这里的 attributeName 会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。举例来说,如果你的组件实例有一个数据属性 attributeName,其值为 "href",那么这个绑定就等价于 v-bind:href

相似地,你还可以将一个函数绑定到动态的事件名称上:当 eventName 的值是 "click" 时,@[eventName] 就等价于 @click

效果图:

image.png

修饰符Modifiers

<script>
export default {
    data() {
        return {
           ...
        }
    },
     methods: {
        //onclick点击事件
        doSomething(event) {
            // 阻止a元素的默认行为(例如页面跳转)
            event.preventDefault();

            // 这里执行你需要的操作
            console.log('Link was clicked!');
        }
    }
}
</script>

<template>
        <button @click.once="doSomething">once只执行一次修饰符</button>
</template>

once属性表示点击事件只执行一次,再次点击不生效。

效果图:

image.png

其他更多指令请参考官网:模版语法

AboutView.vue完整代码:

<style>
@media (min-width: 1024px) {
    .about {
        min-height: 100vh;
        display: inline-list-item;
        align-items: center;
    }
}
</style>

<script>
export default {
    data() {
        return {
            msg: '最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号)',//文本
            rawHtml: '<span style="color: red">This should be red.</span>',//原始HTML
            number: 5,
            ok: '123',
            message: '请把我倒着念出来',
            id: 123,
            activeColor: 'green',
            fontSize: 20,
            isButtonDisabled: true,//按钮不可点击
            date: new Date().toISOString(),//日期
            seen: true,//指令Directives,是否隐藏
            attributeName: 'href', // 动态属性名
            url: 'https://www.baidu.com',//属性值
            eventName: 'click'
        }
    },
    methods: {
        // 将日期转换为标题格式
        toTitleDate(date) {
            const d = new Date(date);
            return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
        },
        // 格式化日期为更简洁显示格式
        formatDate(date) {
            const d = new Date(date);
            return d.toLocaleString('default', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                weekday: 'long',
                hour: 'numeric',
                minute: 'numeric',
                hour12: true
            });
        },
        //onclick点击事件
        doSomething(event) {
            // 阻止a元素的默认行为(例如页面跳转)
            event.preventDefault();

            // 这里执行你需要的操作
            console.log('Link was clicked!');
        }
    }
}
</script>

<template>
    <div class="about">
        <h1>关于</h1>
        <hr/>
        <br>

        <h3>文本插值</h3>
        <text>{{ msg }}</text>
        <hr/>

        <h3>原始HTML</h3>
        <p>Using text interpolation: {{ rawHtml }}</p>
        <p>Using v-html directive: <span v-html="rawHtml"></span></p>
        <hr/>

        <h3>Attribute绑定</h3>
        <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">
            我是Attribute绑定的样式。
        </div>
        <button :disabled="isButtonDisabled">布尔型Attribute</button>
        <hr/>

        <h3>JavaScript表达式</h3>
        {{ number + 1 }} | {{ ok ? 'YES' : 'NO' }} | {{ message.split('').reverse().join('') }}
        <hr/>

        <h3>调用函数</h3>
        <time :title="toTitleDate(date)" :datetime="date">
            {{ formatDate(date) }}
        </time>
        <hr/>

        <h3>指令Directives</h3>
        <p v-if="seen">Now you see me</p>
        <hr/>

        <h3>参数Arguments</h3>
        <a :href="url">百度一下,你就知道</a><br>
        <a @click="doSomething">v-on点击事件</a>
        <hr/>

        <h3>动态参数</h3>
        <a :[attributeName]="url">百度一下,你就知道</a><br>
        <a @[eventName]="doSomething">动态参数</a>
        <hr/>

        <h3>修饰符Modifiers</h3>
        <button @click.once="doSomething">once只执行一次修饰符</button>
        <hr/>
    </div>
</template>

效果图:

image.png