Vue实现页面导航实战
目录
一 使用技术栈
二 创建项目
三 准备资源文件
四 安装axios
五 代码
六 测试
七 源码参考
一 使用技术栈
1 组件及组件间传值
2 axios实现读取json数据:商品数据源存于json中
3 css相关技术进行布局:布局、间距等样式
4 使用views页面级组件,使用router设置页面
二 创建项目
1 创建项目
F:\vue\proj>vue create proj
2 选择必要组件
? Check the features needed for your project:
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
(*) Router
( ) Vuex
( ) CSS Pre-processors
>( ) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
3 选择history模式
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) y
4 选择使用package.json来记录
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
5 选不保存为预制项目
? Save this as a preset for future projects? (y/N) n
6 开始安装
7 运行
cd proj
npm run serve
三 准备资源文件
1 准备图片
2 准备json文件
bjb.json
[
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb1.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb2.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb3.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb4.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb5.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb6.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb7.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb8.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb9.jpg"
},
{
"goodName": "联想笔记本",
"img": "img/bjb/bjb10.jpg"
}
]
shouji.json
[
{
"goodName": "华为手机",
"img": "img/shouji/sj1.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj2.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj3.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj4.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj5.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj6.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj7.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj8.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj9.jpg"
},
{
"goodName": "华为手机",
"img": "img/shouji/sj10.jpg"
}
]
四 安装axios
cnpm i axios -S
五 代码
1 创建首页First.vue
<template>
<div class="main">
<div class="left">
<Left></Left>
</div>
<div class="right">
<div class="top">
<img src="img/title.jpg" alt="">
</div>
<div class="buttom">
<Right></Right>
</div>
</div>
</div>
</template>
<script>
/* 引用组件*/
import Left from '../components/Left.vue'
import Right from '../components/Right.vue'
export default {
name: "First",
/* 页面要用到的组件都放在这里 */
components: {
Left,
Right
}
}
</script>
<style scoped>
* {
padding: 0;
margin: 0;
}
.left {
width: 100px;
float: left;
margin-right: 10px;
}
.right {
width: 1000px;
float: left;
margin-left: 10px;
}
.main {
width: 1200px;
margin: 20px auto;
}
.top img {
height: 200px;
width: 1000px;
}
.left, .right {
background-color: #f5f5f5;
height: 660px
}
</style>
2 创建路由文件index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
// 不用系统默认主页,而是自定义主页
// import Home from '../views/Home.vue'
// 引入主页
import First from '../views/First.vue'
Vue.use(VueRouter)
// 主页路由
const routes = [
{
path: '/',
component: First
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
3 App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
4 左边导航组件left.vue
<template>
<div>
<div class="title">热门推荐</div>
<ul class="menu">
<li @click="menu1">笔记本电脑</li>
<li @click="menu2">手机</li>
<li @click="menu3">服饰</li>
<li @click="menu4">手表</li>
<li>书籍</li>
<li>玩具</li>
<li>小家电</li>
<li>学习用品</li>
<li>办公用品</li>
<li>旅游必备</li>
<li>游戏卡通</li>
</ul>
</div>
</template>
<script>
// 引入事件总线
import Msg from './Msg.js'
export default {
name: "left",
methods: {
menu1: function () {
// 通过数据总线传值给兄弟节点
Msg.$emit("val", "1");
},
menu2: function () {
// 通过数据总线传值给兄弟节点
Msg.$emit("val", "2");
},
menu3: function () {
// 通过数据总线传值给兄弟节点
Msg.$emit("val", "3");
},
menu4: function () {
// 通过数据总线传值给兄弟节点
Msg.$emit("val", "4");
}
}
}
</script>
<style scoped>
.title {
width: 100px;
color: red;
}
.menu {
padding-inline-start: 0px;
}
.menu li {
list-style: none;
height: 50px;
margin-bottom: 2px;
background-color: white;
line-height: 50px;
/* 改变鼠标指针为手形形状 */
cursor: pointer;
}
</style>
5 事件总线Msg.js,用于同级组件传值
// 事件总线文件是js文件,不是vue文件
import Vue from 'vue'
export default new Vue
6 右边内容组件Right.vue
<template>
<div>
<!-- 通过kk的值控制显示的内容 -->
<div v-if="kk==1">
<!-- 这里是属性绑定,也可以用 v-bind ,实现了组件的传值-->
<GoodList :goodId="1"></GoodList>
</div>
<div v-else-if="kk==2">
<GoodList v-bind:goodId="2"></GoodList>
</div>
<div v-else-if="kk==3">
33333333333
</div>
<div v-else-if="kk==4">
4444444444
</div>
<div v-else>
<GoodList v-bind:goodId="1"></GoodList>
</div>
</div>
</template>
<script>
// 引入事件总线
import Msg from './Msg.js'
// 引入自定义组件
import GoodList from "./GoodList"
// 下面这种写法也可以
// import GoodList from "./GoodList.vue"
export default {
name: "Right",
data() {
return {
kk: 0
}
},
mounted() {
// _this 是 this 的副本,不能用this,因为页面中不同的this含义不同,所以要用一个副本存储
var _this = this;
// 此处的 val 接收 left.vue 中兄弟节点传过来的值,然后 val 的值再传给m
Msg.$on('val', function (m) {
_this.kk = m;
// 这里不能用 this.kk ,因为它表示的是on里面的内容,这就是前面为什么用_this的原因
// this.kk = m //错误
})
},
// 组件注册放在这里
components: {
GoodList
}
}
</script>
<style scoped>
</style>
7 main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 引入 axios
import axios from 'axios'
// 全局注册 axios
Vue.prototype.$http = axios
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
8 商品列表组件GoodList.vue
<template>
<div name="show">
<ul class="goodList">
<li v-for="goods in list">
<!-- v-bind 是属性绑定,这里绑定的是src属性-->
<img v-bind:src="goods.img">
<p>{
{goods.goodName}}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "show",
data() {
// 初始化代码
var obj = this;
var url;
if (obj.goodId == 1) {
url = "json/bjb.json"
} else if (obj.goodId == 2) {
url = "json/shouji.json"
}
this.$http.get(url).then(function (res) {
obj.list = res.data;
})
return {
list: []
}
},
props: {
// 调用组件时定义了goodId
goodId: Number
},
/* 监听传递的参数 */
watch: {
goodId() {
var obj = this;
var url = "";
if (obj.goodId == 1) {
url = "json/bjb.json"
} else if (obj.goodId == 2) {
url = "json/shouji.json"
}
this.$http.get(url).then(function (res) {
obj.list = res.data;
})
return {
list: []
}
}
}
}
</script>
<style scoped>
.goodList li {
width: 190px;
height: 190px;
list-style: none;
float: left;
font-size: 9px;
color: red;
margin-bottom: 30px;
}
.goodList img {
width: 180px;
height: 180px;
}
</style>
六 测试
七 源码参考
https://gitee.com/cakin24/prog
还没有评论,来说两句吧...