vue+elementUI+vue router+vuex综合demo

1.初始化工作
安装node.js
一路next
安装node.js会一并安装npm
验证方式,cmd观察版本号能否正常显示

node -v
npm -v

安装vue脚手架vue-cli

npm install vue-cli -g --registry=https://registry.npm.taobao.org

显示所有模板,正常显示则说明安装依赖成功,一般使用webpack模板

vue list

命令行 vue-cli的webpack模板,初始化工程
vue init webpack hello-vue-element3
全部回车,并选择no,因为要自己使用国内淘宝源加速,以及自己手动npm run dev

cd hello-vue-element3

安装依赖

npm install --registry=https://registry.npm.taobao.org

验证初始化的工程是否ok

npm run dev

访问localhost:8080

IDEA安装 Vue插件

导入IDEA
注意:如果IDEA的命令行不能使用npm run dev,使用管理员启动IDEA试试

删除脚手架工程中的Hello World Component相关代码

2.构建登录页面和主页面的路由,从登录页跳转到主页面。

手动安装路由,使用淘宝源

npm install vue-router --save-dev --registry=https://registry.npm.taobao.org

新建src/router/index.js集中配置所有路由

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router);
export default new Router({
	routes: [
	   {
		  name: 'Login',
		  path: '/login',
		  component: Login
	   },
	   {
	     name: 'Main',
	     path: '/main',
	     component: Main
	   }
	]
})

新建src/views/Login.vue

main.js中使用router目录

import router from './router'
new Vue({
	router,
})

App.vue中使用router-link,router-view标签验证路由是否成功。
最后要删除两个标签,
因为要通过浏览器访问http://localhost:8080/#/login 以及 http://localhost:8080/#/main

<router-link to="/login">登录</router-link>
<router-link to="/main">主页</router-link>
<router-view />

引入elementUI

安装 element-ui

npm i element-ui -S --registry=https://registry.npm.taobao.org

安装 SASS 加载器,这个下载很慢,安装失败貌似也没影响

npm install sass-loader node-sass --save-dev --registry=https://registry.npm.taobao.org

main.js中引入js库和css库

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 显式调用插件
Vue.use(ElementUI);

// 添加render
new Vue({
render: h => h(App),
})

结合ElementUI官网示例代码,带有验证的表单,填充Login.vue

注意一定要使用函数对象的方式来申明表单中的字段

  export default {
        name: "Login",
        data() {
          return {
            form: {
              username: '',
              password: ''
            }

          }
        }
    }

用methods申明表单提交方法:

methods: {
        onSubmit: function () {
          alert(this.form.username + '>>>' + this.form.password);
		  this.$router.push('/main');
        }
      }

// js实现从Login跳转到main
this.$router.push('main')

表单验证,有elementUI的html代码以及js校验逻辑

主页Main,参考elementUI的Container布局

新建src/views/user/List.vue 和Add.vue

在src/router/index.js配置Main的子路由

import Vue from 'vue'
import Router from 'vue-router'
import UserList from '@/views/user/List'
import UserAdd from '@/views/user/Add'

Vue.use(Router);
export default new Router({
	routes: [
	   {
		  name: 'Login',
		  path: '/login',
		  component: Login
	   },
	   {
	     name: 'Main',
	     path: '/main',
	     component: Main,
	     children: [
	       {name: 'UserList', path: '/user/list', component: UserList},
	       {name: 'UserAdd', path: '/user/add', component: UserAdd}
         ]
	   }
	]
})

Main中配置router-link, router-view

<router-link to="/user/list">用户列表</router-link>
<router-link to="/user/add">新增用户</router-link>
<router-view/>

使用vuex做状态管理

在项目根目录执行如下命令来安装 Vuex

npm install vuex --save --registry=https://registry.npm.taobao.org

修改 main.js 文件,导入 Vuex

import Vuex from 'vuex'
Vue.use(Vuex);

利用路由钩子 beforeEach 来判断用户是否登录,期间会用到 sessionStorage 存储功能。
在main.js捕获所有的路由事件,
根据isLogin标注位判断是否已经登录

router.beforeEach((to,from,next)=>{
  // debugger
  let isLogin = sessionStorage.getItem("isLogin");

  // next()表示放行,安装原先的跳转逻辑放行
  // next({path:"/xxx"}),表示自定义跳转逻辑
  // 一般来说,二者选其一
  if (to.path=="/logout")
  {
    sessionStorage.clear();
    next({path:"/login"})
  }
  else if(to.path=="/login")
  {
    if(isLogin=="true")
    {
      next({path:"/main"})
    }
    else
    {
      next()
    }
  }
  else if (isLogin==null)
  {
    next({path:"/login"})
  }
  else
   {
     next();
   }
  console.log("into beforeEach,from.path="+from.path+",to.path="+to.path+",next.path="+next.path);
})

新建 src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
// 分别定义4个const
constant state = {
  user: {
    username: '',
  }
};
constant getters = {
  getUser(state) {
    return state.user;
  }
};
// mutations可以改变state的值,但是它是同步的,性能低
constant mutations = {
  updateUser(state, user) {
    state.user = user;
  }
};
// actions是异步的,性能高,一般通过actions调用mutations方法
constant actions = {
  asyncUpdateUser(context, user) {
    context.commit('updateUser', user);
  }
}
export default new Store({
	state,
	getters,
	mutations,
	actions
});

main.js中使用store

import store from './store'
new Vue({
el: '#app',
store,
});

在Login.vue中调用vuex,通过actions异步调用

this.$store.dispatch('asyncUpdateUser', this.form);

在Main.vue中读取已登录的用户名

{{this.$store.getters.getUser.username}}

解决vuex里的保存的用户名,F5后消失问题
在App.vue中,捕捉页面刷新事件

mounted() {
    window.addEventListener('unload', this.saveState);
  },

  methods: {
    saveState: function () {
      // 页面刷新unload事件,只能通过console.log,控制台一闪而过。alert是看不出效果的。
      // 刷新则存储state json串到sessionStorage
      sessionStorage.setItem("state", JSON.stringify(this.$store.state));

    }

修改store/index.js

const state = sessionStorage.getItem("state") != "undefined" ? JSON.parse(sessionStorage.getItem("state")) : {
  user: {
    username: ''
  }
};

Vuex.Store还支持模块化
新建src/store/user/user.js

const user = {
  state: {
	user: {
	  username: ''
	}
  },
  getters: {
    getUser(state, user) {
	  return state.user;
	}
  },
  mutations: {
    updateUser(state, user) {
	  state.user = user;
	}
  },
  actions: {
    asyncUpdateUser(context, user) {
		context.commit('updateUser', user);
	}
  }
  export default user;
}

修改store/index.js

import user from './modules/user'
export new Vuex.Store({
	modules: {
	  user,
	}
});

Login.vue,登录成功后,调用vuex

this.$store.dispatch('asyncUpdateUser', this.form);

Main.vue展示登录的用户名

{{this.$store.getters.getUser.username}}

App.vue捕获刷新事件,把vuex state存入sessionStorage

sessionStorage.setItem('state', JSON.stringify(this.$store.state.user));

src/store/user/user.js修改为

state = sessionStorage.getItem("state")!="undefined"?JSON.parse(sessionStorage.getItem("state")):{
  user: {
    username: ''
  }
}

小总结:
1.使用sessionStorage保存了是否登录的标志位isLogin true/false
2.使用vuex(state,getters,mutations,actions)保存,获取,同步修改,异步修改 当前登录的用户名
3.页面刷新vuex的state会重置,所以捕获unload事件,把当前用户名存入sessionStorage。
state优先从sessionStorage中读,如果有则JSON.parse。如果没有,则重新初始化

代码路径:

https://gitee.com/Orz6/Vue_practice/tree/master/src/hello-vue-element

<think>好的,用户想用VueElementUI实现牛客网首页的模拟。首先,我需要回忆牛客网首页的结构和功能。通常,首页会有导航栏、轮播图、热门职位、最新动态等模块。然后,考虑如何用VueElementUI组件来实现这些部分。 导航栏可以用ElementUI的Menu组件,可能需要调整样式来匹配牛客的风格。轮播图部分,ElementUI有Carousel组件,直接使用应该没问题,但需要自定义指示器和箭头样式。内容区域可能需要栅格系统来布局,比如使用Row和Col组件来排列热门职位和最新动态的卡片。 接下来是数据获取,用户可能需要通过axios发送请求,这里需要指导如何在Vue中集成axios,并在created或mounted生命周期钩子中获取数据。动态渲染部分,使用v-for指令循环展示数据,比如职位列表和文章列表。 样式方面,用户可能需要覆盖ElementUI的默认样式,比如导航栏的背景色、菜单项的悬停效果。需要提醒使用scoped CSS或者深度选择器来修改组件样式。 另外,响应式设计很重要,ElementUI的栅格系统支持响应式,但要确保在不同屏幕尺寸下布局合理。可能需要使用媒体查询或Flex布局来调整。 用户可能遇到的问题包括组件间的通信,比如登录状态的维护,可以使用Vuex进行状态管理。路由方面,需要配置Vue Router来实现页面跳转,但首页可能主要是静态内容,所以路由部分可能比较简单。 还需要考虑代码结构,比如组件的拆分,将导航栏、轮播图、职位列表等拆分成子组件,提高可维护性。同时,示例代码需要清晰,展示关键部分的实现,比如模板结构、数据绑定和方法处理。 最后,测试和优化,比如图片懒加载、性能优化等,可以建议用户后续考虑。总结步骤应该是环境搭建、组件选择与集成、数据处理、样式调整、功能实现和优化。</think>### 使用VueElementUI实现牛客网首页的步骤分解 #### 一、环境搭建 1. 创建Vue项目并安装依赖 ```bash vue create niuke-demo cd niuke-demo vue add element npm install axios --save ``` #### 二、核心组件选择 1. 布局组件 - 使用`el-container`实现页面整体布局 - `el-header`用于顶部导航栏 - `el-main`用于主体内容区 2. 功能组件 - `el-carousel`实现轮播图 - `el-row/el-col`构建栅格布局 - `el-card`展示职位/文章卡片 - `el-pagination`实现分页 #### 三、关键代码实现 1. 导航栏实现(添加企业级样式覆盖) ```vue <el-header class="custom-header"> <el-menu mode="horizontal" background-color="#1a1a1a" text-color="#fff" active-text-color="#ffd04b"> <el-menu-item index="1">首页</el-menu-item> <el-menu-item index="2">题库</el-menu-item> <el-submenu index="3"> <template #title>求职</template> <el-menu-item index="3-1">职位搜索</el-menu-item> <el-menu-item index="3-2">面经分享</el-menu-item> </el-submenu> </el-menu> </el-header> <style scoped> .custom-header { background: #1a1a1a; box-shadow: 0 2px 8px rgba(0,0,0,0.1); ::v-deep .el-menu-item { font-weight: 500; &:hover { background-color: rgba(255,255,255,0.1)!important; } } } </style> ``` 2. 轮播图组件(带自定义指示器) ```vue <el-carousel height="360px" indicator-position="outside" arrow="always"> <el-carousel-item v-for="(item, index) in banners" :key="index"> <img :src="item.image" class="banner-image" /> </el-carousel-item> </el-carousel> <style> .banner-image { width: 100%; height: 100%; object-fit: cover; } .el-carousel__indicator { padding: 12px 4px; button { width: 24px; height: 4px; border-radius: 2px; } } </style> ``` #### 四、数据交互实现 1. 接口请求配置 ```javascript // src/api/index.js import axios from 'axios' export const getJobs = (params) => axios.get('/api/jobs', { params }) export const getArticles = (page = 1) => axios.get(`/api/articles?page=${page}`) ``` 2. Vue组件数据绑定 ```vue <script> import { getJobs, getArticles } from '@/api' export default { data() { return { jobs: [], articles: [], currentPage: 1 } }, async created() { try { const [jobsRes, articlesRes] = await Promise.all([ getJobs({ limit: 6 }), getArticles() ]) this.jobs = jobsRes.data this.articles = articlesRes.data } catch (error) { this.$message.error('数据加载失败') } } } </script> ``` #### 五、响应式布局方案 1. 使用ElementUI的响应式栅格 ```vue <el-row :gutter="20"> <el-col v-for="job in jobs" :key="job.id" :xs="24" :sm="12" :md="8" :lg="6"> <el-card class="job-card"> <template #header> <h3>{{ job.title }}</h3> <div class="company">{{ job.company }}</div> </template> <div class="salary">{{ job.salary }}</div> <div class="tags"> <el-tag v-for="tag in job.tags" :key="tag" size="mini"> {{ tag }} </el-tag> </div> </el-card> </el-col> </el-row> ``` #### 六、性能优化建议 1. 图片懒加载 ```vue <img v-lazy="item.image" class="banner-image"> ``` 2. 组件按需加载 ```javascript // 在vue.config.js中配置 module.exports = { chainWebpack: config => { config.plugin('component').use(require('unplugin-vue-components/webpack')({ resolvers: [ ElementPlusResolver({ importStyle: 'sass' }) ] })) } } ``` 3. 路由懒加载 ```javascript const Home = () => import('./views/Home.vue') ``` #### 七、典型问题解决方案 1. 样式冲突问题 - 使用scoped属性限定样式作用域 - 深度选择器处理子组件样式 ```css ::v-deep .el-menu-item { /* 覆盖样式 */ } ``` 2. 跨域问题处理 ```javascript // vue.config.js module.exports = { devServer: { proxy: { '/api': { target: 'https://api.niuke.com', changeOrigin: true, pathRewrite: { '^/api': '' } } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值