准备
https://vuejs.org/guide/quick-start.html
代码编辑器:VSCode
浏览器开发工具(用于调试):Vue.js devtools
rkun1@LAPTOP-TUS5FU0D MINGW64 /c/code
$ mkdir VUE-STARTrkun1@LAPTOP-TUS5FU0D MINGW64 /c/code
$ cd VUE-START/rkun1@LAPTOP-TUS5FU0D MINGW64 /c/code/VUE-START
$ code .
创建index.html
文件
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><div id="app" class="container"><h1>{{ pageTitle }}</h1><p>{{ content }}</p></div><script>Vue.createApp({data() {return {pageTitle: "Hello,Vue",content: "Welcome to the wonderful world of Vue"}}}).mount('#app')</script>
</body></html>
- 引入了 Vue.js 库和 Bootstrap 样式。
- 在页面中创建了一个 Vue 应用的根元素( )。
- 使用 Vue 数据绑定将数据(pageTitle 和 content)渲染到页面上。
- 在脚本部分使用 Vue.createApp 创建了一个 Vue 应用,并通过 mount 方法将其挂载到具有 id “app” 的元素上。
- 定义了两个数据属性 pageTitle 和 content,它们分别用于渲染页面上的标题和段落内容。
使用循环创建内容
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg bg-body-tertiary"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="link in links" class="nav-item"><a class="nav-link" aria-current="page" href="#">{{ link }}</a></li></ul></div></nav><div id="app" class="container"><h1>{{ pageTitle }}</h1><p>{{ content }}</p></div><script>Vue.createApp({data() {return {links: ['Home', 'About', 'Contact']}}}).mount('nav')Vue.createApp({data() {return {pageTitle: "Hello,Vue",content: "Welcome to the wonderful world of Vue"}}}).mount('#app')</script>
</body></html>
- 新增的部分主要是一个bootstrap简单的导航栏(navbar),以及对导航栏中链接的动态渲染。
- v-for=“link in links”:使用 Vue 的 v-for 指令,遍历 links 数组中的每个元素。
- 通过 Vue 的数据绑定和循环指令,动态地生成了一个简单的导航栏,链接的文本内容来自于 links 数组。
绑定数据到属性
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg bg-body-tertiary"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="link in links" class="nav-item"><a class="nav-link" aria-current="page" :href="link.url":title="`this link goes to the ${link.text} page`">{{ link.text }}</a></li></ul></div></nav><div id="app" class="container"><h1>{{ pageTitle }}</h1><p>{{ content }}</p></div><script>Vue.createApp({data() {return {links: [{ text: 'Home', url: 'home.html' },{ text: 'About', url: 'about.html' },{ text: 'Contact', url: 'contact.html' },],pageTitle: "Hello,Vue",content: "Welcome to the wonderful world of Vue"}}}).mount('body')</script>
</body></html>
- 在导航栏链接的部分,使用了动态绑定(:href 和 :title)来使链接的href属性和title属性动态地从数据中获取。
- :href=“link.url”:链接的 href 属性被绑定到 link.url,这样每个链接都有不同的目标页面。
- :title=“this link goes to the ${link.text} page”:链接的 title 属性也被绑定到一个动态字符串,以提供更具体的链接说明。
- links 数组的数据结构进行了更改,每个链接现在包含了 text 和 url 两个属性。这使得链接的文本和目标 URL 可以动态配置。
- 数据动态变化
因为没有编写页面,所以点击任意一个导航,都会出现
设置事件
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg bg-body-tertiary"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="(page,index) in pages " class="nav-item"><a class="nav-link" aria-current="page" :href="page.link.url":title="`this link goes to the ${page.link.text} page`" @click.prevent="activePage = index">{{ page.link.text }}</a></li></ul></div></nav><div id="app" class="container"><h1>{{ pages[activePage].pageTitle }}</h1><p>{{ pages[activePage].content }}</p></div><script>Vue.createApp({data() {return {activePage: 0,pages: [{link: { text: 'Home', url: 'index.html' },pageTitle: 'Home Page',content: 'This is the home content'},{link: { text: 'About', url: 'about.html' },pageTitle: 'About Page',content: 'This is the about content'},{link: { text: 'Contact', url: 'contact.html' },pageTitle: 'Contact Page',content: 'This is the Contact content'},]}}}).mount('body')</script>
</body></html>
使用 v-for 遍历 pages 数组中的每个页面,并将其相关信息绑定到导航栏链接。通过 @click.prevent 监听点击事件,当用户点击链接时,更新 activePage 的值为当前页面的索引,从而切换到对应的页面。prevent 修饰符用于防止点击事件的默认行为,例如阻止链接跳转或表单的提交。
@click.prevent=“activePage = index” 这行代码表示当用户点击导航栏中的链接时,将会触发一个点击事件,而 .prevent 修饰符阻止了这个点击事件的默认行为。在这个上下文中,默认行为通常是链接跳转。因此,点击链接时不会像通常一样跳转到链接指定的页面,而是触发了你在 @click 处理函数中定义的逻辑,即更新 activePage 的值为当前页面的索引,实现了页面切换的功能。
绑定CSS样式类
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg ":class="{'navbar-light bg-light':!useDarkNavBar ,'navbar-dark bg-dark': useDarkNavBar }"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="(page,index) in pages " class="nav-item"><a class="nav-link" aria-current="page" :href="page.link.url":title="`this link goes to the ${page.link.text} page`" @click.prevent="activePage = index">{{ page.link.text }}</a></li></ul><form class="d-flex"><button class="btn btn-primary" @click.prevent="useDarkNavBar = !useDarkNavBar">Toggle NavBar</button></form></div></nav><div id="app" class="container"><h1>{{ pages[activePage].pageTitle }}</h1><p>{{ pages[activePage].content }}</p></div><script>Vue.createApp({data() {return {useDarkNavBar: false,activePage: 0,pages: [{link: { text: 'Home', url: 'index.html' },pageTitle: 'Home Page',content: 'This is the home content'},{link: { text: 'About', url: 'about.html' },pageTitle: 'About Page',content: 'This is the about content'},{link: { text: 'Contact', url: 'contact.html' },pageTitle: 'Contact Page',content: 'This is the Contact content'},]}}}).mount('body')</script>
</body></html>
- 使用了 Vue.js 的动态 class 绑定功能,通过 :class 属性动态地设置 navbar 元素的类,以根据 useDarkNavBar 的值切换不同的样式。
- :class 属性,它接受一个对象,对象的键是类名,值是布尔表达式。如果值为 true,则该类名将被应用,如果值为 false,则该类名将被移除。因此,根据 useDarkNavBar 的值,navbar 元素会切换在明亮主题和暗黑主题之间。
点击按钮,切换样式
使用Computed Properties
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg " :class=navbarClasses><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="(page,index) in pages " class="nav-item"><a class="nav-link" aria-current="page" :href="page.link.url":title="`this link goes to the ${page.link.text} page`" @click.prevent="activePage = index">{{ page.link.text }}</a></li></ul><form class="d-flex"><button class="btn btn-primary" @click.prevent="useDarkNavBar = !useDarkNavBar">Toggle NavBar</button></form></div></nav><div id="app" class="container"><h1>{{ pages[activePage].pageTitle }}</h1><p>{{ pages[activePage].content }}</p></div><script>Vue.createApp({computed: {navbarClasses() {return {'navbar-light': !this.useDarkNavBar,'bg-light': !this.useDarkNavBar,'navbar-dark': this.useDarkNavBar,'bg-dark': this.useDarkNavBar,}}},data() {return {useDarkNavBar: false,activePage: 0,pages: [{link: { text: 'Home', url: 'index.html' },pageTitle: 'Home Page',content: 'This is the home content'},{link: { text: 'About', url: 'about.html' },pageTitle: 'About Page',content: 'This is the about content'},{link: { text: 'Contact', url: 'contact.html' },pageTitle: 'Contact Page',content: 'This is the Contact content'},]}}}).mount('body')</script>
</body></html>
Vue.js的computed属性来计算navbarClasses,这是一个基于useDarkNavBar数据属性的计算属性。computed属性允许你在Vue实例中定义依赖于其他响应式数据的属性,这些属性会在其依赖发生变化时自动更新。
绑定CSS样式类 II
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg " :class="[`navbar-${theme}`,`bg-${theme}`,'navbar','navbar-expand-lg']"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="(page,index) in pages " class="nav-item"><a class="nav-link" aria-current="page" :href="page.link.url":title="`this link goes to the ${page.link.text} page`" @click.prevent="activePage = index">{{ page.link.text }}</a></li></ul><form class="d-flex"><button class="btn btn-primary" @click.prevent="changeTheme()">Toggle NavBar</button></form></div></nav><div id="app" class="container"><h1>{{ pages[activePage].pageTitle }}</h1><p>{{ pages[activePage].content }}</p></div><script>Vue.createApp({data() {return {theme: 'light',activePage: 0,pages: [{link: { text: 'Home', url: 'index.html' },pageTitle: 'Home Page',content: 'This is the home content'},{link: { text: 'About', url: 'about.html' },pageTitle: 'About Page',content: 'This is the about content'},{link: { text: 'Contact', url: 'contact.html' },pageTitle: 'Contact Page',content: 'This is the Contact content'},]};},methods: {changeTheme() {let theme = 'light';if (this.theme == 'light') {theme = 'dark';}this.theme = theme;}}}).mount('body')</script>
</body></html>
- changeTheme 方法:这是一个在 Vue 实例的 methods 属性中定义的方法。
- let theme = ‘light’;:首先,定义了一个局部变量 theme 并初始化为 ‘light’。
- if (this.theme == ‘light’) { theme = ‘dark’; }:检查当前主题是否为 ‘light’,如果是,则将 theme 设置为 ‘dark’,实现了主题的切换。
- this.theme = theme;:将更新后的主题应用到 Vue 实例的 theme 数据属性上,触发视图的重新渲染,从而实现导航栏样式的动态切换。
组件
index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><!-- 开发环境版本 --><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><nav class="navbar navbar-expand-lg " :class="[`navbar-${theme}`,`bg-${theme}`,'navbar','navbar-expand-lg']"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="(page,index) in pages " class="nav-item"><a class="nav-link" aria-current="page" :href="page.link.url":title="`this link goes to the ${page.link.text} page`" @click.prevent="activePage = index">{{ page.link.text }}</a></li></ul><form class="d-flex"><button class="btn btn-primary" @click.prevent="changeTheme()">Toggle NavBar</button></form></div></nav><page-viewer :page="pages[activePage]"></page-viewer><script>let app = Vue.createApp({data() {return {theme: 'light',activePage: 0,pages: [{link: { text: 'Home', url: 'index.html' },pageTitle: 'Home Page',content: 'This is the home content'},{link: { text: 'About', url: 'about.html' },pageTitle: 'About Page',content: 'This is the about content'},{link: { text: 'Contact', url: 'contact.html' },pageTitle: 'Contact Page',content: 'This is the Contact content'},]};},methods: {changeTheme() {let theme = 'light';if (this.theme == 'light') {theme = 'dark';}this.theme = theme;}}});app.component('page-viewer', {props: ['page'],template: `<div id="app" class="container"><h1>{{page.pageTitle}}</h1><p>{{page.content}}</p></div> `});app.mount('body')</script>
</body></html>
通过 app.component 方法创建了一个名为 page-viewer 的组件。这个组件接受一个名为 page 的 prop,并根据传入的页面信息渲染页面的标题和内容。
- app.component(‘page-viewer’, {…}):使用 app.component 方法创建一个名为 page-viewer 的组件。
- props: [‘page’]:声明组件的属性 page,这表示 page-viewer 组件可以接受一个名为 page 的 prop。
- template:定义了组件的模板。在这里,模板包含了一个 div 元素,其中包含了页面的标题和内容,使用了动态绑定来显示传入的页面信息。
- 插值表达式:{{page.pageTitle}} 和 {{page.content}} 是插值表达式,用于将 page prop 中的数据动态地显示在组件中。
理解数据流
index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>Vue Basics</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"><script src="https://unpkg.com/vue@3"></script>
</head><body><navbar :pages="pages" :active-page="activePage" :nav-link-click="(index) => activePage = index"></navbar><page-viewer :page="pages[activePage]"></page-viewer><script>const app = Vue.createApp({data() {return {activePage: 0,pages: [{link: { text: 'Home', url: 'index.html' },pageTitle: 'Home Page',content: 'This is the home content'},{link: { text: 'About', url: 'about.html' },pageTitle: 'About Page',content: 'This is the about content'},{link: { text: 'Contact', url: 'contact.html' },pageTitle: 'Contact Page',content: 'This is the Contact content'}]};}});app.component('page-viewer', {props: ['page'],template: `<div id="app" class="container"><h1>{{page.pageTitle}}</h1><p>{{page.content}}</p></div>`});app.component('navbar', {props: ['pages', 'activePage', 'navLinkClick'],template: `<nav class="navbar navbar-expand-lg" :class="{ 'navbar-light': theme === 'light', 'navbar-dark': theme === 'dark', 'bg-light': theme === 'light', 'bg-dark': theme === 'dark' }"><div class="container-fluid"><a class="navbar-brand" href="#">My Vue</a><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li v-for="(page, index) in pages" class="nav-item"><a class="nav-link" :href="page.link.url":title="[\`this link goes to the \${page.link.text} page\`]" @click.prevent="navLinkClick(index)">{{ page.link.text }}</a></li></ul><form class="d-flex"><button class="btn btn-primary" @click.prevent="changeTheme()">Toggle NavBar</button></form></div></nav>`,data() {return {theme: 'light',};},methods: {changeTheme() {this.theme = (this.theme === 'light') ? 'dark' : 'light';}}});app.mount('body');</script>
</body></html>
- props: 定义了pages、activePage和navLinkClick作为该组件的属性,这些属性将通过父组件传递给navbar组件。
- template: 定义了组件的模板,显示一个导航栏,其中包括品牌标识、页面链接以及一个按钮来切换导航栏的主题。
- data: 定义了组件的数据属性theme,初始值为’light’,用于控制导航栏的主题。
- methods: 定义了组件的方法changeTheme,用于切换导航栏的主题。