能夠跳過下面步驟直接下載使用:
https://github.com/MVPVP/ypt201
使用步驟:
下載代碼=》安裝依賴 npm install
=》運行程序 npm run dev
=》瀏覽器中打開 http://localhost:8080css
1、安裝vue-cli;vue
一、npm install -g vue-cli
全局安裝vue-cli;
node
二、npm install -g vue-cli
生成ypt201項目名項目文件,默認回車,會安裝vue-router路由和EsLint幫助咱們檢查Javascript編程時的語法格式等;webpack
三、cd ypt201
進入ypt201文件目錄下ios
四、npm install
安裝依賴,ypt201文件目錄下生產node_modules文件;git
五、npm run dev
vue-cli項目跑起來,並在瀏覽器打開(注意端口是否被佔用)github
2、補全vuex+scss+element-ui+axios須要的依賴;web
一、npm install --save-dev sass-loader node-sass
用於編譯scss文件
二、npm install --save vuex axios element-ui
vue-router
3、編輯文件目錄,項目中簡單使用scss,vuex,element-ui,axios,slot,props練手
文件目錄以下:vuex
//src文件夾頁面本身編輯的,其餘頁面vue-cli生成的;
關於src文件說明:
//assets資源文件jsondata.js放靜態數據,樣式文件scss和imgs圖片文件;
//commponents目錄裏面放了公共組件header,dialogs,menus,pages等文件;
//routes.js文件放路由配置文件;
//views放詳情頁面文件;
//vuex放狀態管理文件;
//App.vue是項目入口文件。
//main.js這是項目的核心文件。全局的配置都在這個文件裏面配置。
從vue-cli手腳架搭建到這個項目搭建,全部改動有src裏面文件和webpack.base.config文件:
如下按照截圖順序粘貼出全部改動過的代碼:
在webpack.base.config中屏蔽這段代碼避免報錯,eslint用於代碼檢測的;
webpack.base.config
{ { test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', include: [resolve('src'), resolve('test')], options: { formatter: require('eslint-friendly-formatter') } },
jsondata.js
const menuDatas={ home:{ to: '/',text:'首頁' }, about:{ to: 'about',text:'關於' }, yysxx:{ to: 'showui',text:'組件庫' } }; export {menuDatas}
_header.scss
$headerH: 48px; .m-header{ height: $headerH; }
_menus.scss
.m-menus{ width: 200px; top: 200px; position: absolute; bottom: 0; li{ line-height:50px; } } .router-link-exact-active{ color: #ff0000; }
reset.scss
//淘寶初始化css代碼 body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; } body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; } h1, h2, h3, h4, h5, h6{ font-size:100%; font-weight:normal; } address, cite, dfn, em, var { font-style:normal; } code, kbd, pre, samp { font-family:couriernew, courier, monospace; } small{ font-size:12px; } ul, ol { list-style:none; } a { text-decoration:none; } a:hover { text-decoration:underline; } sup { vertical-align:text-top; } sub{ vertical-align:text-bottom; } legend { color:#000; } fieldset, img { border:0; } button, input, select, textarea { font-size:100%; } table { border-collapse:collapse; border-spacing:0; }
_dialogs.vue
<!--標題、關閉按鈕是統一的,可是中間正文的內容(包括樣式)是想自定義的,這時候就會用到Vue組件的slot來分發內容。好比子組件的template的內容爲:--> <template> <div class="m-dialog-wrapper"> <div class="box"> <h1>彈窗標題</h1> <slot name="dialogsContain"></slot> <div> <span class="m-btn">肯定</span> <span class="m-btn" @click="dialogCancel()">取消</span> </div> </div> </div> </template> <style lang="scss" scoped> .f-arctileBox,.m-mask { position: absolute; right: 0; top: 0; bottom: 0; left: 0; } .m-dialog-wrapper{ @extend .f-arctileBox; .boxBg{ background: #fff; opacity: 1; position: absolute; left: 0; right: 0; bottom: 0; padding: 20px 0 50px 0; } .box{ background: #fff; margin: auto; box-shadow: 3px 3px 5px #ccc; border: 1px solid #cdcdcd; padding: 20px; width: 300px; position: relative; } } </style> <script> import {store} from '../vuex/store.js' export default{ data(){ return { count:0, dialogBool:store.state.dialogBool, title:'0' } }, methods:{ dialogCancel(){ store.commit('dialogBoolFalse'); console.log(store.state.dialogBool) } } } </script>
header.vue
<template> <div class="m-header"> {{adminName}} </div> </template> <style lang="scss" src="../assets/scss/_header.scss" scoped></style> <script> import {store} from '../vuex/store.js' export default{ data () { return { adminNameName:store.state.adminName, } }, //computed至關於屬性的一個實時計算,若是實時計算裏關聯了對象,那麼當對象的某個值改變的時候,同事會出發實時計算。 computed:{ adminName(){ return '實時計算'+store.state.adminName; } } } </script>
menus.vue
<template> <div class="m-menus"> <ul> <li v-for="(childMenu,key,childIndex) in menuList" class="childMenu"> <router-link :to="childMenu.to" :from="childMenu.to">{{childMenu.text}}</router-link> </li> </ul> </div> </template> <style lang="scss" src="../assets/scss/_menus.scss" scoped></style> <script> import {menuDatas} from '../assets/datas/jsondata.js' import {store} from '../vuex/store.js' export default { name: 'menus', data () { return { menuList:menuDatas } }, methods:{ } } </script>
pages.vue
<template> <ul class="mo-paging"> <!-- prev --> <li :class="['paging-item', 'paging-item--prev', {'paging-item--disabled' : index === 1}]" @click="prev">prev</li> <!-- first --> <li :class="['paging-item', 'paging-item--first', {'paging-item--disabled' : index === 1}]" @click="first">first</li> <li :class="['paging-item', 'paging-item--more']" v-if="showPrevMore">...</li> <li :class="['paging-item', {'paging-item--current' : index === pager}]" v-for="pager in pagers" @click="go(pager)">{{ pager }}</li> <li :class="['paging-item', 'paging-item--more']" v-if="showNextMore">...</li> <!-- last --> <li :class="['paging-item', 'paging-item--last', {'paging-item--disabled' : index === pages}]" @click="last">last</li> <!-- next --> <li :class="['paging-item', 'paging-item--next', {'paging-item--disabled' : index === pages}]" @click="next">next</li> </ul> </template> <script> export default { name : 'MoPaging', //經過props來接受從父組件傳遞過來的值 props : { //頁面中的可見頁碼,其餘的以...替代, 必須是奇數 perPages : { type : Number, default : 5 }, //當前頁碼 pageIndex : { type : Number, default : 1 }, //每頁顯示條數 pageSize : { type : Number, default : 10 }, //總記錄數 total : { type : Number, default : 1 }, }, data () { return { index : this.pageIndex, //當前頁碼 limit : this.pageSize, //每頁顯示條數 size : this.total || 1, //總記錄數 showPrevMore : false, showNextMore : false } }, methods : { prev(){ if (this.index > 1) { this.go(this.index - 1) } }, next(){ if (this.index < this.pages) { this.go(this.index + 1) } }, first(){ if (this.index !== 1) { this.go(1) } }, last(){ if (this.index != this.pages) { this.go(this.pages) } }, go (page) { if (this.index !== page) { this.index = page //父組件經過change方法來接受當前的頁碼 //this.$emit('change', this.index) } } }, computed : { //計算總頁碼 pages(){ return Math.ceil(this.size / this.limit) }, //計算頁碼,當count等變化時自動計算 pagers () { const array = [] const perPages = this.perPages const pageCount = this.pages let current = this.index const _offset = (perPages - 1) / 2 const offset = { start : current - _offset, end : current + _offset } //-1, 3 if (offset.start < 1) { offset.end = offset.end + (1 - offset.start) offset.start = 1 } if (offset.end > pageCount) { offset.start = offset.start - (offset.end - pageCount) offset.end = pageCount } if (offset.start < 1) offset.start = 1 this.showPrevMore = (offset.start > 1) this.showNextMore = (offset.end < pageCount) for (let i = offset.start; i <= offset.end; i++) { array.push(i) } console.log('arraypage'); return array } } , watch : { pageIndex(val) { this.index = val || 1 }, pageSize(val) { this.limit = val || 10 }, total(val) { this.size = val || 1 } } } </script> <style lang="scss" scoped> .mo-paging { display: inline-block; padding: 0; margin: 1rem 0; font-size: 0; list-style: none; user-select: none; > .paging-item { display: inline; font-size: 14px; position: relative; padding: 6px 12px; line-height: 1.42857143; text-decoration: none; border: 1px solid #ccc; background-color: #fff; margin-left: -1px; cursor: pointer; color: #0275d8; &:first-child { margin-left: 0; } &:hover { background-color: #f0f0f0; color: #0275d8; } &.paging-item--disabled, &.paging-item--more{ background-color: #fff; color: #505050; } //禁用 &.paging-item--disabled { cursor: not-allowed; opacity: .75; } &.paging-item--more, &.paging-item--current { cursor: default; } //選中 &.paging-item--current { background-color: #0275d8; color:#fff; position: relative; z-index: 1; border-color: #0275d8; } } } </style>
index.js
import Vue from 'vue' import Router from 'vue-router' import Hello from '@/views/Hello' import aboutPage from '@/views/about' import showuiPage from '@/views/showui' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Hello', component: Hello }, { path: '/about', name: 'about', component: aboutPage }, { path: '/showui', name: 'showui', component: showuiPage } ] })
about.vue
<template> <div> <h2>關於指令v-for</h2> <ol> <li v-for="todo in todos"> {{ todo.text }} </li> </ol> <h2>關於事件click</h2> <button @click="eClick()">操做狀態</button> <h2>關於狀態管理vuex</h2> <div>{{number}}</div> <h2>關於slot</h2> <button class="icon right" @click="areaClick()">彈窗案例</button> <h2>關於props</h2> <div class="m-page"> <pages-tab :page-index="currentPage" :total="count" :page-size="pageSize" :per-pages="perPages"> </pages-tab> </div> <dialogs-tab v-show="dialogBool"> <div slot="dialogsHeader"><span v-text="dialogsTitle"></span></div> <div slot="dialogsContain"> <p>這裏是彈窗具體內容-房產信息</p> <p>這裏是彈窗具體內容-房產信息</p> </div> </dialogs-tab> </div> </template> <script> import {store} from '../vuex/store.js' import dialogsTab from '../components/dialogs.vue' import pagesTab from '../components/pages.vue' export default { name: 'indexP', data () { return { todos: [ { text: 'Learn JavaScript' }, { text: 'Learn Vue' }, { text: 'Build something awesome' } ], dialogsTitle:'', perPages:7, pageSize : 20 , //每頁顯示20條數據 currentPage : 1, //當前頁碼 count : 200, //總記錄數 items : [] } }, methods:{ eClick(){ console.log(9999); store.commit('inc'); }, areaClick(){ console.log('areaClick'); store.commit('dialogBoolTrue'); console.log(store.state.dialogBool); } }, computed: { number(){ return store.state.count }, dialogBool(){ return store.state.dialogBool; } }, components:{ dialogsTab, pagesTab } }; </script> <style lang="scss"> h2{ background: #417ccc; margin: 15px 0 5px; color: #fff; } </style>
Hello.vue文件放本來vue-cli的內容,注意本來是在components目錄下,如今是剪切到views目錄下
略;
showui.vue
<template> <div> <div class="block"> <span class="demonstration">hover 顯示顏色</span> <span class="wrapper"> <el-button :plain="true" type="success">成功按鈕</el-button> <el-button :plain="true" type="warning">警告按鈕</el-button> <el-button :plain="true" type="danger">危險按鈕</el-button> <el-button :plain="true" type="info">信息按鈕</el-button> </span> </div> <div class="block"> <span class="demonstration">消息提示</span> <el-button :plain="true" @click="open2">成功</el-button> <el-button :plain="true" @click="open3">警告</el-button> <el-button :plain="true" @click="open">消息</el-button> <el-button :plain="true" @click="open4">錯誤</el-button> </div> </div> </template> <style lang="scss" scoped> .block{ margin:10px 0; } </style> <script> export default { methods: { open() { this.$message('這是一條消息提示'); }, open2() { this.$message({ message: '恭喜你,這是一條成功消息', type: 'success' }); }, open3() { this.$message({ message: '警告哦,這是一條警告消息', type: 'warning' }); }, open4() { this.$message.error('錯了哦,這是一條錯誤消息'); } } } </script>
store.js
//考慮如何更好地在組件外部管理狀態(把組件的共享狀態抽取出來,以一個全局單例模式管理呢) import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) //建立Store實例 const store = new Vuex.Store({ // 建立一個對象來保存應用啓動時的初始狀態 state: { count: 0, adminName:'系統管理員Admin系統管理員', dialogBool:false }, mutations: { inc: state => state.count++, dec: state => state.count--, dialogBoolTrue(state){ state.dialogBool=true; }, dialogBoolFalse(state){ state.dialogBool=false; } } }) export {store}
App.vue
<template> <div id="app"> <header-tab></header-tab> <img src="./assets/logo.png"> <menu-list></menu-list> <router-view class="article"></router-view> </div> </template> <script> import HeaderTab from './components/header.vue' import menuList from './components/menus.vue' export default { name: 'app', components:{ HeaderTab, menuList } } </script> <style lang="scss" scoped> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .article{ margin-left:210px; } </style>
main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false import './assets/scss/reset.scss' import ElementUI from 'element-ui' import 'element-ui/lib/theme-default/index.css' Vue.use(ElementUI) /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '<App/>', components: { App } })
4、項目跑起來,深入學習案例;
一、npm run dev
在瀏覽器打開項目連接查看頁面內容,實例學習案例;
二、npm run bulid
打包生成dist文件;
5、部署服務端;
一、直接在iis上部署打包生成的dist文件;
6、遇到的問題;
一、IE瀏覽器下報錯:[vuex] vuex requires a Promise polyfill in this browser.
解決:
第一步: 安裝 babel-polyfill 。 babel-polyfill能夠模擬ES6使用的環境,能夠使用ES6的全部新方法npm install --save babel-polyfill
第二步: 在webpack.config.js文件中,使用
entry: { app: ["babel-polyfill", "./src/main.js"] }
替換:
entry: { app: './src/main.js' }
7、代碼連接:
https://github.com/MVPVP/ypt201
使用步驟:
下載代碼=》安裝依賴 npm install
=》運行程序 npm run dev
=》瀏覽器中打開 http://localhost:8080