Vue入门(三)
这一节我们开始编写自己的程序。
首先,我们看一下完成程序后的src目录中都有哪些东西:
除了一些图片外(1张LOGO,3张手机图片、3张平板图片、3张电脑图片),src根目录下仍然有main.js和App.vue,router目录下有一个路由文件router.js,components目录下有几个组件文件,基本上每个链接都是一个组件(一级菜单home、about、user,二级菜单phone、tablet、computer)。
我们挨个看一下:
一、main.js
- import Vue from "vue";
- import App from "./App";
- import router from "./router/router";
- new Vue({
- el: '#app',
- router,
- render: h => h(App)
- });
本节的main.js与上一节比有一些变化,上一节是:
- new Vue({
- el: '#app',
- router,
- components: { App },
- template: '<App/>'
- })
从Vue2.0开始,改用render()函数来渲染组件,h是createElement的别名。
h=>h(App)是箭头函数,相当于:
render: function(createElement) {
createElement(App); // 我们要提供render函数,它的主要代码就是创建出组件元素,App是组件名称
}
二、App.vue
- <template>
- <div id="app">
- <img src="./assets/img/logo.jpg">
- <header>
- <router-link to="/home">Home</router-link>
- <router-link to="/about">About</router-link>
- <router-link to="/user/123">User123</router-link>
- <router-link to="/user/456">User456</router-link>
- </header>
- <router-view></router-view>
- </div>
- </template>
- <script>
- export default {};
- </script>
- <style>
- html {
- max-width: 640px;
- margin: 0 auto;
- }
- article,
- aside,
- dialog,
- footer,
- header,
- section,
- footer,
- nav,
- figure,
- menu {
- display: block;
- }
- body,
- div,
- dl,
- dt,
- dd,
- ul,
- ol,
- li,
- h1,
- h2,
- h3,
- h4,
- h5,
- h6,
- pre,
- code,
- form,
- fieldset,
- figure,
- section,
- legend,
- textarea,
- p,
- blockquote,
- th,
- td,
- input,
- select,
- textarea,
- button {
- margin: 0;
- padding: 0;
- }
- body {
- font: 14px/1.4 'Microsoft Yahei', Arial, Helvetica, sans-serif;
- max-width: 640px;
- margin: 0 auto;
- color: #424242;
- background-color: #fff;
- }
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- font-size: 100%;
- font-weight: normal;
- }
- table {
- border-spacing: 0;
- border-collapse: collapse;
- }
- ul,
- ol,
- dd,
- dt,
- dl {
- list-style-type: none;
- }
- a {
- text-decoration: none;
- color: blue;
- }
- a:hover {
- text-decoration: underline;
- }
- input,
- img {
- font-size: 14px;
- padding: 0;
- border: none;
- }
- i,
- em {
- font-style: normal;
- }
- :focus {
- outline: none;
- }
- @media (min-device-width: 375px) and(max-device-width: 667px) and(-webkit-min-device-pixel-ratio: 2) {
- body {
- font-size: 14.5px;
- }
- }
- @media (min-device-width: 414px) and (max-device-width: 736px) and (-webkit-min-device-pixel-ratio: 3) {
- body {
- font-size: 15.5px;
- }
- }
- .clear {
- clear: both;
- }
- .clear:after {
- display: block;
- visibility: hidden;
- clear: both;
- overflow: hidden;
- height: 0;
- content: '.';
- }
- .fl {
- float: left;
- }
- .fr {
- float: right;
- }
- .mb10 {
- margin-bottom: 10px;
- }
- .mt10 {
- margin-top: 10px;
- }
- </style>
这个文件的样式表部分比较长,因为要定义App的全部通用样式。
我们重点来看<template>部分:
<router-link to="/home">Home</router-link>定义了一个路由链接,它会被渲染为<a>标签,to属性指向路由表中的一个路径。
<router-view></router-view>用于显示路由链接所指向的组件的内容。
不管点页面上的哪个<router-link>,都会查找路由表,找到相应的组件,并显示在<router-view></router-view>标签处。
三、router/router.js
- import Vue from "vue";
- import VueRouter from "vue-router";
- import Home from "@/components/home.vue"; // 导入所有组件
- import About from "@/components/about.vue";
- import User from "@/components/user.vue";
- import Phone from "@/components/phone.vue";
- import Tablet from "@/components/tablet.vue";
- import Computer from "@/components/computer.vue";
- Vue.use(VueRouter); // 使用路由器
- const routes = [
- {
- path: '/home', // 路由1,路径为“/home”
- component: Home, // 组件为“Home”
- children: [ // 子路由,子路由的路径为“/home/phone”
- { path: 'phone', component: Phone },
- { path: 'tablet', component: Tablet },
- { path: 'computer', component: Computer }
- ]
- },
- { path: '/about', component: About },
- { path: '/', redirect: '/home' }, // 如果想第一次访问首页时,也能显示Home组件,可以使用redirect重定向到“/home”路径
- { path: '/user/:id', component: User }
- ];
- var router = new VueRouter({ // 创建路由对象
- mode: 'history', // 路由模式为history,这种模式的URL比较自然:/home/user/123,另一种模式是hash
- routes
- });
- export default router;
四、components/home.vue
- <template>
- <div>
- <h1>Home</h1>
- <p>
- <router-link to="/home/phone">手机</router-link>
- <router-link to="/home/tablet">平板</router-link>
- <router-link to="/home/computer">电脑</router-link>
- </p>
- <router-view></router-view>
- </div>
- </template>
- <script>
- export default {};
- </script>
这个文件比较简单。
五、components/about.vue
- <template>
- <div>
- <h1>About</h1>
- <p>{{ aboutMsg }}</p>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- aboutMsg: "我是About组件"
- };
- }
- };
- </script>
这个文件比较简单。
六、components/user.vue
- <template>
- <div>
- <h1>User</h1>
- <p>我是User组件,动态部分是:{{ userId }}</p>
- </div>
- </template>
- <script>
- export default {
- computed: {
- userId() {
- return this.$route.params.id;
- }
- }
- };
- </script>
这个组件和其它组件不同的是,该组件的路由是带参数的,路由文件中的路径是:“{ path: '/user/:id', component: User }”,那么id就是路由的参数名,实际使用时,我们给了两个链接“/user/123”和“/user/456”,在代码中使用“this.$route.params.[参数名]”的方式可以获得参数值。this.$route表示当前路由,params是路由的参数集合。
这里用计算属性的方式,返回了参数值。
七、components/phone.vue
- <template>
- <div>
- <h1>Phones</h1>
- <div v-for="phone in phones" class="item">
- <img :src="phone.img">
- <p>{{ phone.name }}</p>
- </div>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- phones: [
- { name: "手机1", img: require("@/assets/img/phone1.jpg") },
- { name: "手机2", img: require("@/assets/img/phone2.jpg") },
- { name: "手机3", img: require("@/assets/img/phone3.jpg") }
- ]
- };
- }
- };
- </script>
- <style scoped>
- .item {
- width: 200px;
- float: left;
- }
- .item img {
- width: 200px;
- height: 200px;
- }
- .item p {
- width: 200px;
- text-align: center;
- }
- </style>
这个文件的样式表部分,我们给<style>加了一个scoped,这表示该样式表只能用在本组件内,不作用于全局。
再来看一下<template>部分的代码:
- <div v-for="phone in phones" class="item">
- <img :src="phone.img">
- <p>{{ phone.name }}</p>
- </div>
我们在<script>部分定义了一个phones数组,保存了所有手机的信息,所以可以使用Vue的v-for来遍历数组,例如:“v-for='phone in phones'”。v-for会生成多个<div>。
然后使用“:src”将动态数据绑定到src属性上,在<p></p>中使用{{phone.name}}输出手机的名称。
可以参照这个文件,类似地编写平板、电脑的组件。
八、运行
完成上述代码后,用“CTRL+`”调出控制台,输入“npm run dev”运行,并在浏览器的地址栏中输入“http://localhost:8080”即可看到运行结果。