Vue全家桶:vue + vue-router + vuex
vue + vue-router 主要用来做 SPA (single page application),单页面应用
为什么要做单页面应用?
传统的路由跳转,如果后端资源过多,会导致页面出现“白屏现象”。让前端来做路由,在某个生命周期的钩子函数中发送 ajax ,然后数据驱动。即 为了用户体验。
vue-router 是vue的核心插件
vue-router 的使用:
// 1、创建匹配路由组件; // 2、配置路由信息 // 3、在 router-link 中使用
示例代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> </body> <script src="./vue.js"></script> <!-- 引入 vue-router --> <script src="./vue-router.js"></script> <script> /* // 如果是模块化编程, 下面的 Vue 和 VueRouter都是局部的,且下面的代码等价于伪代码: Vue.prototype.$VueRouter = VueRouter ,即 在Vue 的原型上挂载了 vue-router.js 提供的属性 VueRouter Vue.use(VueRouter) */ // 先定义两个组件,这两个组件要被用于路由中 const Home = { data(){ return { } }, template:`<div>我是首页</div>`, } const Course = { data(){ return { } }, template:`<div>我是课程组件</div>`, } // 创建路由 const router = new VueRouter({ // 定义路由规则;routes 对应的是一个列表,列表中是一个个对象;path 对应路由的路径, component 对应路由的组件 routes: [ { path:'/', redirect:'/home' // 重定向 }, { path: '/home', component: Home }, { path: '/course', component: Course } ] }) let App = { data(){ return { } }, /* router-link 和 router-view 是 vue-router 提供的两个全局组件; router-link 会被渲染成一个 a标签,router-link 有一个属性 to 相当于a标签的 href 属性, to 中的值要和 路由path 中的值一致; router-view 是路由组件的出口,即 path 对应的组件会渲染到 <router-view> 中 */ template:` <div> <div class='header'> <router-link to="/home">首页</router-link> <router-link to="/course">课程</router-link> </div> <router-view></router-view> </div> `, } new Vue({ el: '#app', // 挂载路由,即相当于 router:router router, data(){ return { } }, template:`<App />`, components:{ App } }) </script> </html>
浏览器效果示例:
参考文档: https://router.vuejs.org/zh/guide/#javascript
命名路由
命名路由可以动态绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> </body> <script src="./vue.js"></script> <!-- 引入 vue-router --> <script src="./vue-router.js"></script> <script> // 先定义两个组件,这两个组件要被用于路由中 const Home = { data(){ return { } }, template:`<div>我是首页</div>`, } const Course = { data(){ return { } }, template:`<div>我是课程组件</div>`, } // 创建路由 const router = new VueRouter({ routes: [ { path:'/', redirect:'/home' // 重定向 }, // 命名路由 { path: '/home', name: 'home-comp', // 给路由起个名字 component: Home }, { path: '/course', name: 'course-comp', component: Course } ] }) let App = { data(){ return { } }, // 动态绑定命名路由:<router-link> 中 :to 对应的是一个对象 template:` <div> <div class='header'> <router-link :to="{'name':'home-comp'}">首页</router-link> <router-link :to="{'name':'course-comp'}">课程</router-link> </div> <router-view></router-view> </div> `, } new Vue({ el: '#app', // 挂载路由,即相当于 router:router router, data(){ return { } }, template:`<App />`, components:{ App } }) </script> </html>
命名路由官方文档:
https://router.vuejs.org/zh/guide/essentials/named-routes.html
动态路由匹配
动态路由匹配规则 主要用于以下的 路由范式:
http:127.0.0.1:8080/user/{uid}
示例代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> </body> <script src="./vue.js"></script> <script src="./vue-router.js"></script> <script> /* 动态路由匹配规则 主要用于以下的 路由范式: http:127.0.0.1:8080/user/{uid} */ const User = { data(){ return { user_id:'' } }, template:`<div>我是用户{{ user_id }}</div>`, created(){ console.log(this.$route); // $route 是路由信息对象;$route 是挂载到vue实例对象上的,能用 this.$route 获取是因为通过 继承。 // 如果想拿地址栏上的某些参数,就去找 $route // 提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。 },
// 动态路由匹配 watch:{ $route(to, from) { // 监视路由信息对象发生改变 console.log('to:', to); console.log('from:', from); console.log('uid:', to.params.uid); // 获取到 uid 后就可以往后端发送 ajax this.user_id = to.params.uid } } } const router = new VueRouter({ routes:[ { path: '/user/:uid', // :uid 绑定动态传入的数字值 name: 'user-comp', component: User } ] }) let App = { data(){ return { } }, // params 这个对象中的 key uid 即是 路由path 中的 :uid // 该 router-link 对应的模板样式是 User 组件 template:` <div> <div class='header'> <router-link :to="{'name':'user-comp', params:{uid: 1}}">用户1</router-link> <router-link :to="{'name':'user-comp', params:{uid: 2}}">用户2</router-link> </div> <router-view></router-view> </div> `, } new Vue({ el: '#app', router, data(){ return { } }, template:`<App />`, components:{ App } }) </script> </html>
浏览器效果示例:
注: 就如 $route, 带 $ 的属性都是挂载到 vue 实例对象是的
编程式导航
$router:路由对象,即 VueRouter对象;一般用它来做编程式导航
编程式导航 vs 声明式导航
声明式导航示例:
<router-link :to="{'name':'user-comp', params:{uid: 1}}">用户1</router-link> <router-link :to="{'name':'user-comp', params:{uid: 2}}">用户2</router-link>
编程式导航示例代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> </body> <script src="./vue.js"></script> <script src="./vue-router.js"></script> <script> const Home = { data(){ return { } }, template:`<div>我是首页</div>`, } const User = { data(){ return { user_id:null } }, template:` <div> <p>我是用户{{ user_id }}</p> <button @click='clickHandler'>跳转</button> </div> `, methods:{ // 编程式导航 clickHandler(){ // push 是 $router (路由对象)的一个方法,参数是一个包含命名路由的对象 this.$router.push({ name: 'home-comp' }) } }, created(){ console.log(this.$route); }, watch:{ $route(to, from) { this.user_id = to.params.uid } } } const router = new VueRouter({ routes:[ { path: '/user/:uid', name: 'user-comp', component: User }, ] }) let App = { data(){ return { } }, template:` <div> <div class='header'> <router-link :to="{'name':'user-comp', params:{uid: 1}}">用户1</router-link> <router-link :to="{'name':'user-comp', params:{uid: 2}}">用户2</router-link> </div> <router-view></router-view> </div> `, } new Vue({ el: '#app', router, data(){ return { } }, template:`<App />`, components:{ App } }) </script> </html>
浏览器效果示例:
编程式导航文档:
https://router.vuejs.org/zh/guide/essentials/navigation.html
Vue 获取原生DOM的方式
Vue提供的获取原生DOM 的方式,是给标签或组件添加 refs 属性: 通过 this.$refs 来获取,如 <div ref='neo'></div> 如果在当前组件中想获取上述 div 标签这个DOM元素,可通过 this.$refs.neo 获取到上述 div 对象 如果是给 html 标签添加 ref ,那么 this.$refs.neo 获取到的是原始的DOM元素; 如果是给 Vue 组件添加 ref ,那么通过 this.$refs.neo 获取到的是 组件实例化对象
代码示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> </div> <script src="./vue.js"></script> <script> // 想要实现的效果: DOM加载完成后,自动获取 input 输入框的焦点 Vue.component('Test', { data(){ return { } }, template:` <div>我是测试组件</div> `, }) let App = { data(){ return { } }, template:` <div> <input type="text" ref='inputss'> <Test ref='test-compnt' /> </div> `, mounted(){ console.log(this.$refs.inputss); // 获取原始的 input 这个DOM元素; <input type="text"> this.$refs.inputss.focus(); // 自动获取input 输入框的焦点 // this.$refs 是一个对象 console.log(this.$refs); // {inputss: input, test-compnt: VueComponent} for(let key in this.$refs){ console.log('keys:', key, 'val:', this.$refs[key] ); } } } new Vue({ el: '#app', data(){ return { } }, template:`<App />`, components:{ App } }) </script> </body> </html>
浏览器效果示例:
axios 的基本使用:
1、在项目中下载 axios 组件
npm i axios -S
2、在项目中引入 axios
// main.js 中全局引入 axios // 引入 axios import Axios from 'axios' // 把 axios 挂载到 vue的原型上 Vue.prototype.$https = Axios // $https 这个名字可以自己起 // 设置公共的url;以后在利用 axios 给某个链接(如 users/edit)发送请求时, 链接会自动和这个 baseURL 拼接到一起 Axios.defaults.baseURL = 'https://api.example.com';
3、 在组件中使用 axios
// 为给定 ID 的 user 创建GET请求 this.$https.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
官方文档: