Vue-cli項目開發
環境
1)安裝node:官網下載安裝包,傻瓜式安裝:https://nodejs.org/zh-cn/
2)安裝cnpm
>:npm install -g cnpm --registry=https://registry.npm.taobao.org
3)安裝腳手架
>:cnpm install -g @vue/cli
4)清空緩存處理(如果第2、3補出問題可以執行該條命令)
>:npm cache clean --force
創建項目
>: cd 項目目錄
>: vue create 項目名
#第一次出現的選項
default (babel, eslint)
Manually select features #選擇該項
#第二次出現
#空格勾選,回車下一步
(*) Babel #我們在VUe中一般都用ES6語法寫的,這個插件功能很強大一般都選的把ES5語法解析成ES6
( ) TypeScript #也是種語法js的升級版,臉書蠻推薦這個語法的,學這個蠻貴的
( ) Progressive Web App (PWA) Support #前台優化的一個功能集合,提高前台項目效率
(*) Router #前后端交互中ajax交互來達成前后端分離,這個就是前台的路由
(*) Vuex #Vue中父組件與子子組件傳遞消息,設置成全局的單例來方便消息傳遞
( ) CSS Pre-processors #如果選了后面他會讓你選你用less或者sass中其中某個做預處理
(*) Linter / Formatter #規范編碼格式
( ) Unit Testing #測試相關
( ) E2E Testing #測試相關
#一般勾選這四個,其它具體情況具體分析

pycharm運行Vue項目
1)pycharm索引到vue項目的根目錄,打開
2)安裝vue.js插件來高亮 .vue 文件代碼(見插圖)
3)配置npm啟動服務啟動vue項目(見插圖)


項目目錄介紹
|vue-proj
| |node_modules 項目依賴
| |public
| | | 圖標、單頁面.html
| |src
| | |assets 靜態文件(img、css、js)
| | |components 小組件
| | |views 頁面組件
| | |App.vue 根組件
| | |main.js 主腳本文件
| | |router.js 安裝vue-router插件的腳本文件 - 配置路由的
| | |store.js 安裝vuex插件的腳本文件 - 全局倉庫 - 數據共享
| |配置文件們
| |README.md 關鍵命令說明
main.js
// import 別名 from '文件(后綴可以省略)'
import Vue from 'vue'
// import App from './App.vue'
import App from './App' // 導入時可以省略后綴
import router from './router' // .代表相對路徑的當前路徑
import store from '@/store.js' // @表示src絕對路徑
Vue.config.productionTip = false;
// new Vue({
// router,
// store,
// render: h => h(App)
// }).$mount('#app');
new Vue({
el: '#app',
router: router,
store,
// render: (fn) => {
// return fn(App)
// }
render (fn) { // 讀取組件渲染給掛載點el
return fn(App)
}
});
組件 .vue 文件:模板(template) + 腳本(scpirt) + 樣式(style)
<template>
<!--組件有且只有一個根標簽-->
<div id="app">
<h1 @click="btnClick">{{ title }}</h1>
</div>
</template>
<script>
// 組件內部導出,其它文件才能import導入該組件
export default {
name: "App",
data() {
return {
title: '主頁'
}
},
methods: {
btnClick() {
console.log(this.title)
}
}
}
</script>
<!--scoped樣式組件局部化-->
<style scoped>
h1 {
color: red;
}
</style>
前台路由的基本工作流程
目錄結構
|vue-proj
| |src
| | |components
| | | |Nav.vue
| | |views
| | | |PageFirst.vue
| | | |PageSecond.vue
| | |App.vue
| | |router.js
App.vue:根組件
<template>
<div id="app">
<!--根組件只需要書寫router-view-->
<!--router-view就是vue-router插件路由占位標簽-->
<router-view></router-view>
</div>
</template>
Nav.vue:小組件
<template>
<div class="nav">
<!--router-link就是vue-router插件路由頁面轉跳的標簽,頁面加載后會被解析為a標簽-->
<!--router-link不同於a標簽,路由轉跳之后更換組件,不會發送頁面轉跳,用to屬性設置轉跳路徑-->
<router-link to="/page-first">first</router-link>
<router-link :to="{name: 'page-second'}">second</router-link>
<router-link to="/course">課程</router-link>
<!-- to后跟路由路徑 | :to后可以用name設置路由別名 -->
</div>
</template>
<script>
export default {
name: "Nav"
}
</script>
<style scoped>
.nav {
height: 100px;
background-color: rgba(0, 0, 0, 0.4);
}
.nav a {
margin: 0 20px;
font: normal 20px/100px '微軟雅黑';
}
.nav a:hover {
color: red;
}
</style>
PageFirst.vue:頁面組件
<template>
<div class="page-first">
<Nav></Nav>
<h1>page-first</h1>
</div>
</template>
<script>
// 使用
import Nav from '@/components/Nav'
export default {
name: "PageFirst",
components: {
Nav
}
}
</script>
<style scoped>
.page-first {
width: 100%;
height: 800px;
background: orange;
}
h1 {
text-align: center;
}
</style>
PageSecond.vue:頁面組件
<template>
<div class="page-second">
<Nav></Nav>
<h1 @click="printTitle">{{ title }}</h1>
<input type="text" v-model="title">
</div>
</template>
<script>
import Nav from '@/components/Nav'
export default {
name: "PageSecond",
data() {
return {
title: 'page-second'
}
},
methods: {
printTitle() {
console.log(this.title)
}
},
components: {
Nav
},
}
</script>
<style scoped>
.page-second {
width: 100%;
height: 800px;
background: pink;
}
h1 {
text-align: center;
}
</style>
router.js:路由配置
import Vue from 'vue'
import Router from 'vue-router'
import PageFirst from './views/PageFirst'
import PageSecond from './views/PageSecond'
Vue.use(Router);
export default new Router({
mode: 'history', // 組件更換模擬頁面轉跳形成瀏覽器歷史記錄
base: process.env.BASE_URL,
routes: [
// 路由就是 url路徑 與 vue組件 的映射關系
// 映射出的組件會替換 根組件 中的 router-view 標簽
// 通過 router-link 標簽完成 url路徑 的切換
{
path: '/page-first',
name: 'page-first',
component: PageFirst
},
{
path: '/page-second',
name: 'page-second',
component: PageSecond
},
]
})
配置全局樣式文件
目錄結構
|vue-proj
| |src
| | |assets
| | | |css
| | | | |global.css
| | |main.js
global.css
html, body, h1, ul {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
a {
text-decoration: none;
color: black;
}
/* router-link標簽激活狀態擁有的類名 */
.router-link-exact-active.router-link-active {
color: greenyellow;
border-bottom: 2px solid greenyellow;
}
main.js
// 新增內容
// 配置全局css
import '@/assets/css/global.css'
組件生命周期鈎子
概念
一個組件從創建到銷毀,整個過程中的特殊的時間節點回調的方法,稱之為生命周期鈎子
如:一個組件創建成功就會回調 created方法,內部數據要更新和更新完畢分別調用 beforeUpdate方法與updated方法
案例
<template>
<div class="page-second">
<Nav></Nav>
<h1 @click="printTitle">{{ title }}</h1>
<input type="text" v-model="title">
</div>
</template>
<script>
import Nav from '@/components/Nav'
export default {
name: "PageSecond",
data() {
return {
title: 'page-second'
}
},
methods: {
printTitle() {
console.log(this.title)
}
},
components: {
Nav
},
beforeCreate() {
console.log('開始創建組件');
console.log(this.title);
console.log(this.printTitle);
this.title = '呵呵';
},
created() { // 重點
console.log('組件創建成功');
console.log(this.title);
console.log(this.printTitle);
// 請求后台數據,完成數據的更新
this.title = '嘿嘿';
},
beforeMount() {
console.log('組件開始渲染');
},
mounted() {
console.log('組件渲染成功');
this.title = '嘻嘻';
},
beforeUpdate() {
console.log('數據開始更新');
},
updated() {
console.log('數據更新完畢');
},
activated() {
console.log('組件激活');
},
deactivated() {
console.log('組件停用');
},
destroyed() {
console.log('組件銷毀成功');
}
}
</script>
<style scoped>
.page-second {
width: 100%;
height: 800px;
background: pink;
}
h1 {
text-align: center;
}
</style>
路由重定向
router.js
import Vue from 'vue'
import Router from 'vue-router'
import PageFirst from './views/PageFirst'
import PageSecond from './views/PageSecond'
import Course from './views/Course'
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/page-first',
name: 'page-first',
component: PageFirst
},
{ // 重定向路由的兩種方式
path: '/page/first',
// redirect: {'name': 'page-first'},
redirect: '/page-first'
},
]
})
頁面組件小組件綜合案例:課程頁
目錄結構
|vue-proj
| |src
| | |components 小組件
| | | |CourseCard.vue
| | |views 頁面組件
| | | |Course.vue
| | |router.js
CourseCard.vue
<template>
<div class="course-card">
<div class="left" :style="{background: card.bgColor}"></div>
<div class="right">{{ card.title }}</div>
</div>
</template>
<script>
export default {
name: "CourseCard",
props: ['card']
}
</script>
<style scoped>
.course-card {
margin: 10px 0 10px;
}
.course-card div {
float: left;
}
.course-card:after {
content: '';
display: block;
clear: both;
}
.left {
width: 50%;
height: 120px;
background-color: blue;
}
.right {
width: 50%;
height: 120px;
background-color: tan;
font: bold 30px/120px 'STSong';
text-align: center;
}
</style>
Course.vue
<template>
<div class="course">
<Nav></Nav>
<h1>課程主頁</h1>
<CourseCard :card="card" v-for="card in card_list" :key="card"></CourseCard>
</div>
</template>
<script>
import Nav from '@/components/Nav'
import CourseCard from '@/components/CourseCard'
export default {
name: "Course",
data() {
return {
card_list: []
}
},
components: {
Nav,
CourseCard
},
created() {
let cards = [
{
id: 1,
bgColor: 'red',
title: 'Python基礎'
},
{
id: 3,
bgColor: 'blue',
title: 'Django入土'
},
{
id: 8,
bgColor: 'yellow',
title: 'MySQL刪庫高級'
},
];
this.card_list = cards;
}
}
</script>
<style scoped>
h1 {
text-align: center;
background-color: brown;
}
</style>
router.js
import Vue from 'vue'
import Router from 'vue-router'
import PageFirst from './views/PageFirst'
import PageSecond from './views/PageSecond'
import Course from './views/Course'
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/page-first',
name: 'page-first',
component: PageFirst
},
{
path: '/page/first',
// redirect: {'name': 'page-first'},
redirect: '/page-first'
},
{
path: '/page-second',
name: 'page-second',
component: PageSecond
},
{
path: '/course',
name: 'course',
component: Course
},
]
})