Vue.js 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是 Vue 被设计为可以自底向上逐层应用。
Vue.js 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一 方面,当与 现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
自底向上逐层应用:作为渐进式框架要实现的目标就是方便项目增量开发(即插即用)。
官方网站: https://cn.vuejs.org/v2/guide/
在 html 页面使用 script 引入 vue.js 的库即可使用:
Vue-CLI 脚手架:使用 vue.js 官方提供的 CLI 脚本架可以方便地去创建 vue.js 工程雏形。
创建一个 vue_test 目录,并且在目录下创建 01_vue入门程序.html 文件。
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=<device-width>, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <!-- 引入 vue.js --> <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> --> <script src="js/vue.min.js"></script> </head> <body> <!-- 创建 id 为 app 的 div --> <div id="app">{{name}}</div> </body> <script> // 创建 vue 实例 var VM = new Vue({ el: "#app", data: { name: "Hello Vue", }, }); </script></html>
{{}} 插值表达式:通常用来获取 Vue.js 实例中定义的数据(data);属性节点中不能够使用插值表达式。
el 挂载点:定义 Vue.js 实例挂载的元素节点,表示 vue.js 接管该区域。
Vue 的作用范围 :Vue 会管理 el 选项中的元素及其内部元素。
选择挂载点时,可以使用其他选择器,但是建议使用 ID 选择器。
挂载点可以设置其他的 DOM 元素进行关联,但是建议选择 DIV,不能使用 HTML 和 Body 标签。
data 数据对象:Vue 中用到的数据定义在 data 中;data 中可以写复杂类型;渲染复杂类型数据的时候遵守 js 语法。
<body> <!-- 创建 id 为 app 的 div --> <div id="app"> {{name}} <br> {{school.name}} {{school.number}} <br> <ul> <li>{{names[0]}}</li> <li>{{names[1]}}</li> <li>{{names[2]}}</li> </ul> </div></body><script> // 创建 vue 实例 var VM = new Vue({ el: "#app", data: { name: "Hello Vue", // 对象类型 school: { name: "学校名称", number: "100000" }, // 数组类型 names: ["张人大", "刘小明", "赵小红"] }, });</script>
Vue 中的声明式渲染,简单理解就是 Vue 将声明的数据渲染到 HTML。
<body> <div id="app"> <h2>{{name}}</h2> </div></body><!-- <script src="js/jquery-1.8.3.min.js"></script><script>$(document).ready(function() {$("#app").append("<h2>Hello World</h2>")});</script> --><script src="js/vue.min.js"></script><script> var VM = new new Vue({ el: "#app", data: { name: "Hello World!!", }, });</script>
Vue 指令是带有 v- 前缀的特殊属性;通过指令来操作 DOM 元素 。
作用:获取 data 数据,设置标签的内容。 注意:默认写法会替换全部内容,使用插值表达式 {{}} 可以替换指定内容。
<body> <div id="app"> <h2>{{message}}高级</h2> <!-- v-text 获取 data 数据,设置标签的内容,会覆盖标签里的内容体--> <h2 v-text="message">高级</h2> <!-- 拼接字符串 --> <h2 v-text="message+1"></h2> <h2 v-text="message+'abc'"></h2> </div></body><script src="js/vue.min.js"></script><script> var VM = new new Vue({ el: "#app", data: { message: "Java程序员" } });</script>
作用: 设置元素的 innerHTML (可以向元素中写入新的标签)
<body> <div id="app"> <!-- 获取普通文本 --> <h2>{{message}}</h2> <h2 v-text="message"></h2> <h2 v-html="message"></h2> <!-- 设置元素的 innerHTML --> <h2 v-html="url"></h2> <h2 v-text="url"></h2> </div></body><script src="js/vue.min.js"></script><script> var VM = new new Vue({ el: "#app", data: { message: "Java程序员", url: "<a href='https://www.baidu.com'>百度一下</a>" } });</script>
作用:为元素绑定事件, 比如: v-on:click 可以简写为 @click="方法"
绑定的方法定义在 VUE 实例的 method 属性中
<body> <div id="app"> <!-- 使用 v-on 绑定 click 点击事件 --> <input type="button" value="Button" v-on:click="methodName"> <!-- 使用 @ 符号也可以绑定--> <input type="button" value="Button" @click="methodName"> <!-- 双击事件 --> <input type="button" value="双击击按钮" @dblclick="show"> <!-- 绑定点击事件 --> <h2 @click="changeName">{{food}}</h2> </div></body><script src="js/vue.min.js"></script><script> var VM = new new Vue({ el: "#app", data: { food: "Turkey" }, // 通过 methods,专门存放 Vue 中的方法 methods: { methodName: function() { alert("提醒!"); }, show: function() { alert("Double Click"); }, changeName: function() { console.log(this.food); // 在 VUE 中不需要考虑如何更改 DOM 元素, // 重点放在数据更新之后,使用数据的那个元素会同步更新 this.food+=" Delicious!"; } } });</script>
传递自定义参数:函数调用传参
事件修饰符:对事件触发的方式进行限制
<body> <div id="app"> <!-- 函数传参 --> <input type="button" value="礼物刷起来" @click="showTime(111, 'test111')" /> <!-- 事件修饰符指定哪些方式可以触发事件 --> <input type="text" @keyup.enter="hiFunction" /> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: {}, methods: { showTime: function (p1, p2) { console.log(p1); console.log(p2); }, hiFunction: function () { alert("How are you"); }, }, });</script>
<body> <body> <div id="app"> <!-- 计算功能区域 --> <div> <input type="button" value="+" v-on:click="add"/> <span>{{num}}</span> <input type="button" value="-" @click="sub"/> </div> </div> </body> <script src="js/vue.min.js"></script> <script> //创建 VUE 实例 var VM = new Vue({ el: "#app", data: { num: 1 }, methods: { add: function() { if(this.num < 10) { this.num++; } else { alert("Number is at Maximum"); } }, sub: function() { if(this.num > 0) { this.num--; } else { alert("Number is Minimum"); } } } }); </script></body>
总结:
作用:v-show 指令,根据真假值切换元素的显示状态
<body> <div id="app"> <input type="button" value="切换状态" @click="changeShow" /> <img v-show="isShow" src="img/car.gif" alt="" /> <img v-show="age > 18" src="img/car.gif" /> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { isShow: true, age: 19 }, methods: { changeShow: function() { // 触发方法,对 isShow 进行取反 this.isShow = !this.isShow; } } });</script>
根据表达式的真假,切换元素的显示和隐藏(操作是 dom)
<body> <div id="app"> <input type="button" value="切换状态" @click="changeShow" /> <img v-if="isShow" src="img/car.gif" /> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { isShow: false, }, methods: { changeShow: function () { this.isShow = !this.isShow; }, }, });</script>
作用:设置元素的属性(比如:src,title,class)
<body> <div id="app"> <img src="img/buddha.jpg" alt="" /> <!-- 使用 v-bind 设置 src 属性 --> <img v-bind:src="imgSrc" /> <!-- v-bind 简写为冒号--> <img :src="imgSrc" :title="imgTitle" /> <!-- 设置 class --> <div :style="{ fontSize: size+'px' }">v-bind 指令</div> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { imgSrc: "img/buddha.jpg", imgTitle: "Buddha", size: 50, }, });</script>
作用:根据数据生成列表结构
<body> <div id="app"> <input type="button" value="添加数据" @click="add" /> <input type="button" value="移除数据" @click="remove" /> <ul> <!-- 在 li 标签中获取数组的元素 --> <li v-for="(item, index) in arr"> {{index+1}}城市:{{item}} </li> </ul> <!-- 使用h2标签显示 --> <h2 v-for="p in persons"> {{p.name}} </h2> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { // 数组 arr: ["上海", "北京", "广东", "深圳"], // 对象数组 persons: [ { name: "张人大" }, { name: "刘小明" }, { name: "赵小红" }, ], }, methods: { add: function() { // 向数组添加元素 this.persons.push({name: "小郑"}); }, remove: function() { // 移除数据 this.persons.shift(); } } });</script>
MVVM 是 Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式 MVVM 模式将页面分层了 M、V、和 VM,解释为: Model:负责数据存储 View:负责页面展示 View Model:负责业务逻辑处理(比如 Ajax 请求等),对数据进行加工后交给视图展示
<body> <div id="app"> <!-- View 视图部分 --> <h2>{{name}}</h2> </div></body><script src="js/vue.min.js"></script><script> // 创建的 vue 实例就是 ViewModel var VM = new Vue({ el: "#app", // data 就是 MVVM 模式中的 model data: { name: "hello", }, });</script>
首先,我们将 View Model 的 DOM Listeners 和 Data Bindings 看作两个工具,它们是实现双向绑定的关键:
MVVM 的思想主要是为了让开发更加方便,因为 MVVM 提供了数据的双向绑定。
作用:获取和设置表单元素的值,实现双向数据绑定。
填写表单:当用户填写表单时,View 的状态就被更新了,此时 MVVM 框架可以自动更新 Model 的状态,就相当于把 Model 和 View 做了双向绑定。绑定的数据会和表单元素值相关联。
<body> <div id="app"> <input type="button" value="update message" @click="update" /> <!-- View 视图演示自动单向数据绑定 --> <input type="text" v-bind:value="message" /> <br> <!-- v-model 实现自动双向数据绑定 --> <input type="text" v-model="message" /> <input type="text" v-model="password" /> <h2>{{message}}</h2> <h2>{{password}}</h2> </div></body><script src="js/vue.min.js"></script><script> // VM 业务逻辑控制 var VM = new Vue({ el: "#app", // Model 数据存储 data: { message: "Where are you from?", password: 123456, }, methods: { update: function () { this.message = "China"; }, }, });</script>
<html><head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <title>记事本</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="robots" content="noindex, nofollow" /> <meta name="googlebot" content="noindex, nofollow" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" type="text/css" href="vue_text/css/index.css" /></head><body> <!-- VUE 示例接管区域 --> <section id="app"> <!-- 输入框 --> <header class="header"> <h1>VUE 记事本</h1> <input autofocus="autofocus" autocomplete="off" placeholder="输入日程" class="new-todo" v-model="inputValue" @keyup.enter="add" /> </header> <!-- 列表区域 --> <section class="main"> <ul class="listview"> <!-- 使用 v-for 指令生成列表结构 --> <li class="todo" v-for="(item, index) in list"> <div class="view"> <span class="index">{{index+1}}</span> <label>{{item}}</label> <!-- 删除操作传递 index --> <button class="destroys" @click="remove(index)"></button> </div> </li> </ul> </section> <!-- 统计和清空 --> <footer class="footer"> <span class="todo-count"> <strong>{{list.length}}</strong> items left </span> <button class="clear-completed" @click="clear()"> Clear </button> </footer> </section> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var VM = new Vue({ el: "#app", data: { list: ["Coding", "Sleep", "Eat"], inputValue: "996 or 997" }, methods: { add: function () { this.list.push(this.inputValue); }, remove: function (index) { this.list.splice(index, 1); }, clear: function () { this.list = []; } } }); </script></body></html>
Ajax 是指一种创建交互式网页应用的开发技术
Ajax = 异步 JavaScript + XML
Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新(局部更新)。传统的网页如果需要更新内容,必须重载整个网页页面。 简单记:Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术,维护用户体验性,进行网页的局部刷新.。
同步访问:客户端必须等待服务器端的响应,在等待过程中不能进行其他操作 异步访问:客户端不需要等待服务的响应,在等待期间浏览器可以进行其他操作
AjaxServlet
@WebServlet("/ajax")public class AjaxServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求参数 String username = req.getParameter("name"); // 模拟业务操作的延时 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } // 打印 username System.out.println(username); resp.getWriter().write("Hello Ajax"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); }}
ajax.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Ajax</title></head><body> <input type="text"> <input type="button" value="JQuery is sending Asynchronous request" onclick="run1()"></body><script src="jquery-1.8.3.min.js"></script><script> function run1() { $.ajax({ url: "/hello_maven/ajax", async: true, data: { name: "Renda" }, type: "post", dataType: "text", success: function (res) { console.log(res); alert("sucess: " + res); }, error: function () { alert("error"); } }); }</script></html>
VUE 中结合网络数据进行应用的开发:
Vue 2.0 之后推荐用 axios 替换 JQuery ajax。
导包:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
GET:axios.get(地址?key=value&key2=value2).then(function(response){},function(error){});
POST:axios.post(地址,{key:value,key2:value2}).then(function(response){},function(error){});
请求地址:https://autumnfish.cn/api/joke/list 请求方法:get 请求参数:num(笑话条数,数字) 响应内容:随机笑话
请求地址:https://autumnfish.cn/api/user/reg 请求方法:post 请求参数:username(用户名,字符串) 响应内容:注册成功或失败
请求地址:http://wthrcdn.etouch.cn/weather_mini 请求方法:get 请求参数:city(要查询的城市名称) 响应内容:天气信息
<body> <div id="app"> <input type="button" value="点击获取一个笑话" @click="getJoke" /> <input type="button" value="Post请求" @click="postRegister"> <p>{{joke}}</p> </div></body><script src="vue_text/js/vue.min.js"></script><script src="vue_text/js/axios.min.js"></script><script> var VM = new Vue({ el: "#app", data: { joke: "This is a Joke", }, methods: { getJoke: function () { var jokeThis = this; // 异步访问 axios.get("https://autumnfish.cn/api/joke").then( // 在回调函数内部,this 无法正常使用,需要提前保存起来 function (resp) { console.log(jokeThis.joke); jokeThis.joke = resp.data; }, function (error) { alert("error: " + error); } ); }, postRegister: function () { axios.post("https://autumnfish.cn/api/user/reg", { username: "张人大" }).then( function (resp) { console.log(resp); alert(resp.data); }, function (error) { console.log(error); alert("error: " + error.data); } ); } } });</script>
axios 回调函数中 this 指向已经改变,无法访问 data 中的数据。
解决方案:将 this 进行保存,回调函数中直接使用保存的 this 即可。
js/main.js
var VM = new Vue({ el: "#app", data: { city: "", // 定义数组保存天气信息 weatherList: [], }, // 编写查询天气的方法 methods: { searchWeather: function () { console.log("天气查询"); console.log(this.city); var savedThis = this; // 调用接口 axios.get("http://wthrcdn.etouch.cn/weather_mini?city=" + this.city).then( function (resp) { console.log(resp) // 获取天气信息保存到 weatherList savedThis.weatherList = resp.data.data.forecast; }, function (error) { console.log(error); } ); }, },});
HTML 代码
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>天气查询</title> <link rel="stylesheet" href="css/reset.css" /> <link rel="stylesheet" href="css/index.css" /> </head> <body> <div class="wrap" id="app"> <div class="search_form"> <div class="logo">天气查询</div> <div class="form_group"> <input type="text" class="input_txt" placeholder="请输入要查询的城市" v-model="city" @keyup.enter="searchWeather"/> <button class="input_sub" @click="searchWeather">回车查询</button> </div> </div> <ul class="weather_list"> <li v-for="item in weatherList"> <div class="info_type"> <span class="iconfont">{{item.type}}</span> </div> <div class="info_temp"> <b>{{item.low}}</b> ~ <b>{{item.high}}</b> </div> <div class="info_date"><span>{{item.date}}</span></div> </li> </div> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 官网提供的 axios 在线地址 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <!-- 自定义 main.js --> <script src="js/main.js"></script> </body></html>
当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码,可以使用 v-cloak 指令来解决这一问题。
v-cloak 指令:解决插值表达式闪烁问题。
<!-- 添加样式 --><style> /* 通过属性选择器,设置添加了 v-cloak */ [v-cloak] { display: none; }</style><!-- 在 id 为 app 的 div 中添加 v-cloak --><div class="wrap" id="app" v-cloak> ...</div>
computed 的作用:减少运算次数,缓存运算结果,运用于重复相同的计算。
<body> <div id="app"> <h1>{{res()}}</h1> <h2>{{res()}}</h2> <h1>{{resComputed}}</h1> <h2>{{resComputed}}</h2> </div></body><script src="js/vue.min.js"></script><script> var VM = new new Vue({ el: "#app", data: { a: 10, b: 20, }, methods: { res: function() { console.log("res method had been executed"); return this.a * this.b; }, }, computed: { resComputed: function() { console.log("resComputed method had been executed.") return this.a * this.b; } } });</script>
定义函数也可以实现与 计算属性相同的效果,都可以简化运算;
不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
过滤器是对即将显示的数据做进一步的筛选处理,然后进行显示;值得注意的是过滤器并没有改变原 来的数据,只是在原数据的基础上产生新的数据。
数据加工车间,对值进行筛选加工。
过滤器使用位置:
<!-- 局部过滤器 --><body> <div id="app"> <!-- 使用插值表达式,调用过滤器 --> <p>Computer Price: {{price | addIcon}}</p> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { price: 200, }, methods: { }, computed: { }, // 局部过滤器 在 vue 实例的内部创建 filter filters: { addIcon(value) { return "$" + value; } } })</script><!-- 全局过滤器 --><body> <div id="app"> <p>{{user.name | changeName}}</p> </div></body><script src="js/vue.min.js"></script><script> // 在创建 vue 实例之前创建全局过滤器 Vue.filter("changeName", function(value) { // Change the first letter of the name to uppercase return value.charAt(0).toUpperCase() + value.slice(1); }); var VM = new Vue({ el: "#app", data: { user: { name: "renda" } } })</script>
作用:当有一些数据需要随着其它数据变动而变动时,可以使用侦听属性;它用于观察 Vue 实例上的数据变动。
<!-- 监听数字变化 --><body> <div id="app"> <h2>计数器:{{count}}</h2> <input type="button" @click="count++" value="CLICK"> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { count: 1, }, watch: { count: function(nval, oval) { alert("Counter Change from " + oval + " to " + nval); } } });</script><!-- 监听姓名变化并实时显示 --><body> <div id="app"> <label>First Name: <input type="text" v-model="firstName"></label> <label>Last Name: <input type="text" v-model="lastName"></label> {{fullName}} </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { firstName: "", lastName: "", fullName: "" }, watch: { firstName: function(nval, oval) { this.fullName = nval + " " + this.lastName; }, lastName: function(nval, oval) { this.fullName = this.firstName + " " + nval; } } })</script>
组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。
将相同的功能进行抽取,封装为组件;这样前端人员就可以在组件化开发时,只需要书写一次代码,随处引入即可使用。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树。
Vue 的组件有两种:全局组件和局部组件 。
注意:
相比起全局组件,局部组件只能在同一个实例内才能被调用。
局部组件的写法和全局组件差不多,唯一不同就是:局部组件要写在 Vue 实例里面。
<!-- 全局组件 --><body> <div id="app"> <!-- 使用组件 --> <renda-header></renda-header> </div></body><script src="js/vue.min.js"></script><script> // 定义全局组件 // 组件的命名规则:一般用短横线进行连接,左边是公司名,右边组件的作用名称 Vue.component("renda-header", { // template 模板中只能有一个根元素 template: "<div>TEST <h1 @click='hello'>{{msg}}</h1> </div>", data() { // 组件中的 data 是一个函数 return { msg: "This is the data part of the renda-header", }; }, methods: { hello() { alert("Hello !"); }, }, }); var VM = new Vue({ el: "#app", data: {}, methods: {}, });</script><!-- 局部组件 --><body> <div id="app"> <web-msg></web-msg> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", components: { "web-msg": { template: "<div><h1>{{msg1}}</h1><h1>{{msg2}}</h1></div>", data() { return { msg1: "Developing...", msg2: "Development finished" } }, } } });</script><!-- 组件与模板分离 --><!-- 由于把 html 语言写在组件里面很不方便且不好看,所以将它们分开写 --><body> <div id="app"> <!-- 使用组件 --> <web-msg></web-msg> </div> <!-- 将模板写在 HTML 中,给模板一个 id --> <template id="t1"> <div> <button @click="show">{{msg}}</button> </div> </template></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", components: { "web-msg": { template: "#t1", data() { return { msg: "Search" } }, methods: { show() { alert("Please wait..."); } }, } } });</script>
每个 Vue 实例在被创建之前都要经过一系列的初始化过程,这个过程就是 Vue 的生命周期。
生命周期中的钩子函数:钩子函数是在一个事件触发的时候,在系统级捕获到了他,然后做一些操作。
<body> <div id="app"> <h2 id="msg">{{message}}</h2> <button @click="next">Next</button> </div></body><script src="js/vue.min.js"></script><script> var VM = new Vue({ el: "#app", data: { message: "I am Renda Zhang", }, methods: { show() { alert("show method is executed"); }, next() { this.message = "Who are you?"; } }, // 在 Vue 对象实例化之前执行 beforeCreate() { alert("Before Create"); console.log(this.message); // undefined this.show(); // error }, // 组件的实例化完成,但是 DOM 页面还未生成 created() { alert("Created"); console.log(this.message); this.show(); }, // 模板已经在内存中编辑完成了,但是还没有被渲染到页面中 beforeMount() { alert("Before Mount"); console.log("Page content: " + document.getElementById("msg").innerText); console.log("data: " + this.message); }, // 模板已经被渲染到页面,执行完就会显示页面 mounted() { alert("Mounted"); console.log("Page content: " + document.getElementById("msg").innerText); }, // 内存中的数据已经更新,但是还没有渲染到页面 beforeUpdate() { alert("Before Update"); console.log("Page content: " + document.getElementById("msg").innerText); console.log("data: " + this.message); }, // 内存中的数据已经更新,此方法执行完显示页面 updated() { alert("Updated"); console.log("Page content: " + document.getElementById("msg").innerText); console.log("data: " + this.message); }, });</script>
在 Web 开发中,路由是指根据 URL 分配到对应的处理程序。
路由允许我们通过不同的 URL 访问不同的内容。
通过 Vue.js 可以实现多视图单页面 web 应用。
单页面 Web 应用(single page web application,SPA),就是只有一张 Web 页面的应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的 Web 应用程序。
单页应用不存在页面跳转,它本身只有一个 HTML 页面;传统意义上的页面跳转在单页应用的概念下转变为了 body 内某些元素的替换和更新。
整个 body 的内容从登录组件变成了欢迎页组件,从视觉上感受页面已经进行了跳转。但实际上,页面只是随着用户操作,实现了局部内容更新,依然还是在 index.html 页面中。
单页面应用的好处:
Vue.js 路由需要载入 vue-router 库:
// 方式 1: 本地导入<script src="vue-router.min.js"></script>// 方式 2: CDN<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
使用步骤:
Vue 的 $mount() 为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作、判断等),之后要手动挂载上。新建 Vue 时,el 和 $mount 并没有本质上的不同。
<body> <div id="app"> <h1>renda.com</h1> <p> <!-- 添加超链接,router-link 组件来进行导航,to 属性指定链接 --> <router-link to="/home">Go to Home</router-link> <router-link to="/news">Go to News</router-link> </p> <!-- 路由的出口,路由匹配到组件之后,要渲染到这里 --> <router-view></router-view> </div></body><script src="js/vue.min.js"></script><script src="js/vue-router.min.js"></script><script> // 定义路由所需的组件 const home = { template: "<div>首页</div>" }; const news = { template: "<div>新闻</div>" }; // 定义路由,每个路由有两部分 path(路径),component(组件) const routes = [ { path: "/home", component: home }, { path: "/news", component: news }, ]; // 创建路由管理器实例 const router = new VueRouter({ routes: routes, }); // 创建 Vue 实例,将 router 注入到 vue 实例中,让整个应用都拥有路由的功能 var VM = new Vue({ router, // 代替 el }).$mount("#app");</script>