一、webpack(前端中工做,項目上線以前對整個前端項目優化)javascript
- entry:整個項目的程序入口(main.js或index.js);css
- output:輸出的出口;html
- loader:加載器,對es6代碼的解析,babel-loader(官網:https://www.babeljs.cn/)是瀏覽器支持es6, css-loader解析css文件,style-loader 將css代碼添加一個style標籤插入header標籤中,url-loader等等;前端
- plugins:有不少,好比html-webpack-plugin,醜陋等等;vue
咱們已經學過如何使用腳手架建立一個vue項目,接下來咱們介紹一下vue項目中的常見問題。java
1
2
3
|
vue init webpack luffy-project
// 建立項目(使用單頁面應用就安裝vue-router,其餘選no)
cd luffy-project
// 進入項目所在目錄
npm run dev
// 啓動項目
|
出現這個的警告信息,通常是由於你在template中使用了某些數據屬性或者方法,但js中沒有定義。node
出現這個信息表示模塊找不到,通常咱們使用的模塊有兩種,一種是npm社區下載的模塊(如vue),使用時直接導入(如import Vue from 'vue')便可,這種通常不會出錯;另外一種是咱們本身寫的模塊,錯誤每每容易出如今這裏,不是名字寫錯,就是路徑不對。jquery
注意:還有就是出現了不是本身寫的某個模塊出現錯誤,這時能夠嘗試把node_modules文件夾刪除,再使用下面命令下載項目依賴的包:webpack
npm install // 下載項目依賴的包,生成node_modules文件夾
axios至關於jquery的ajax,官網:https://www.kancloud.cn/yunye/axios/234845ios
將axios掛載到vue的原型上,那麼在各個組件中都能使用,由於面向對象(繼承),以下:
Axios 是一個基於 promise(es6的語法,參考網址:http://es6.ruanyifeng.com/#docs/promise) 的 HTTP 庫,能夠用在瀏覽器和 node.js 中。
// 下載到項目中
1
|
npm install axios -S
|
// 使用方式以下:
// 執行GET請求:
// 爲給定 ID 的 user 建立請求 axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); // 可選地,上面的請求能夠這樣作 axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
// 執行post請求
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
由於不少模塊都要用axios(與後端交互的一項技術),因此咱們能夠將axios掛載在Vue的原型上,這樣,由於面向對象的繼承特色,各個子組件均可以使用。掛載方式以下:
// main.js中 import Axios from 'axios' // npm下載的直接引入axios Vue.prototype.$https = Axios // 將axios對象掛載到Vue原型上
注意:必定不要使用Vue.use(),基於Vue的才須要Vue.use(),axios是一個基於es6的知識點,與vue沒有關係,不依賴vue,只是vue開發者不想使用jquery庫,因此使用axios向後臺發請求。
咱們能夠指定將被用在各個請求的配置默認值,全局的axios默認值有以下幾個:
axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www.form-urlencoded';
// main.js import Vue from 'vue' import App from './App' import router from './router' import Axios from 'axios' Vue.prototype.$https = Axios; // 設置公共的url Axios.defaults.baseURL = 'https://www.luffycity.com/api/v1/'; Vue.config.productionTip = false; /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
// course.vue <template> <div> <div class="categoryList"> <span @click="clickHandler(index, item.id)" :class="{active:index===currentIndex}" v-for="(item,index) in categoryList" :key="item.id"> {{ item.name }} </span> </div> <div class="course"> <ul> <li v-for="(course) in courseList" :key="course.id"> <h3>{{ course.name }}</h3> </li> </ul> </div> </div> </template> <script> export default { name:'Course', data(){ return { categoryList:[], // 分類列表 currentIndex:0, courseList:[], // 課程列表 categoryId:0 // 默認所有課程id } }, methods:{ // 先在methods中聲明函數-獲取課程分類列表的函數 getCategoryList(){ this.$https.get('course_sub/category/list/') .then((res) => { console.log(res); let data = res.data; if (data.error_no === 0){ this.categoryList = data.data; let obj = { id:0, name:'所有', category:0 }; this.categoryList.unshift(obj) } }) .catch((err) => { console.log(err); }) }, // 獲取課程列表 getCourseList(){ this.$https.get(`courses/?sub_category=${this.categoryId}`) .then((res)=>{ var data = res.data; this.courseList = data.data; }) .catch((err)=>{ console.log(err) }) }, clickHandler(index, categoryId){ this.currentIndex = index; // 分類列表點擊對應分類變色 this.categoryId = categoryId; this.getCourseList(); // 發送請求 } }, created(){ // 組件建立完成調用函數-使用axios向接口請求課程列表數據 this.getCategoryList() } } </script> <style scoped> .active{ color: red; } </style>
單向數據流概念的簡單表示,以下圖:
vuex(至關於一個store)有五大將:state、mutations、actions、getters、modules,前三個重要。
各個組件能夠經過computed監聽vuex中的state中的數據屬性,修改state中屬性的惟一方法是提交mutations(同步)中的方法,actions中的方法都是異步的。
1
|
>>> npm install vuex -S
|
1)使用Vuex的Store方法建立一個store實例對象
import Vuex from 'vuex' Vue.use(Vuex); // 模塊化開發要Vue.use() const store = new Vuex.Store({ state:{ num: 1 }, mutations:{ // 同步方法 }, actions:{ // 異步方法 } })
2)將store掛載到Vue實例下
new Vue({ el: '#app', router, store, // store實例掛載到Vue實例,各個組件都能經過this.$store使用 components: { App }, template: '<App/>' })
3)在各組件中經過computed使用store的state中定義的數據屬性
// Home組件中使用 <template> <div> <h1>我是首頁{{ myNum }}</h1> <Son></Son> </div> </template> <script> import Son from './Son' export default { name: 'Home', components:{Son}, computed:{ myNum:function () { return this.$store.state.num; } } } </script> <style scoped></style>
// Son組件(是Home組件的子組件)中使用 <template> <div> <h1>我是Son組件的{{ mySonNum }}</h1> </div> </template> <script> export default { name: 'Son', computed:{ mySonNum:function () { return this.$store.state.num; } } } </script> <style scoped></style>
1)建立store實例對象,並掛在store到Vue實例
import Vuex from 'vuex' Vue.use(Vuex); // 模塊化開發要Vue.use() const store = new Vuex.Store({ state:{ num: 1 }, // mutations中定義同步方法,默認傳遞一個state mutations:{ setMutaNum(state, val){ state.num += val; }, setMutaAsyncNum(state, val){ state.num += val; } }, // actions中定義異步方法 actions:{ // 方法都默認傳遞一個context,就是store setActionNum(context, val){ context.commit('setMutaNum', val); }, setActionAsyncNum(context, val){ setTimeout(()=>{ context.commit('setMutaAsyncNum', val) },1000) } } }) new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
2)在Son組件中觸發actions方法修改store中的值(同步和異步)
<template> <div> <h1>我是Son組件的{{ mySonNum }}</h1> <button @click="addNum">同步修改</button> <button @click="addAsyncNum">異步修改</button> </div> </template> <script> export default { name: 'Son', methods:{ addNum(){ // 不要直接修改state中的狀態,要經過commit方法提交 // commit()第一個參數是觸發store的mutations中的方法名 // 第二個參數給觸發的方法傳遞的值 this.$store.dispatch('setActionNum', 2) }, addAsyncNum(){ this.$store.dispatch('setActionAsyncNum', 3) } }, computed:{ mySonNum:function () { return this.$store.state.num; } } } </script> <style scoped></style>
1)課程詳情組件CourseDetail.vue代碼以下:
<template> <div> <div class=""> <h2>我是課程詳情組件</h2> <p v-for="value in courseDesc">{{ value }}</p> </div> </div> </template> <script> export default { name:'CourseDetail', created(){ // https://www.luffycity.com/api/v1/course/3 console.log(this.$route.params.courseid); // 組件建立則向觸發發送axios請求 this.$store.dispatch('course_top', this.$route.params.courseid) }, computed:{ // 獲取store中的數據,數據是由axios請求而來的 courseDesc(){ return this.$store.state.courseDesc } } } </script> <style scoped> .active{ color: red; } </style>
2)建立store實例對象,代碼以下:
import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ state:{ num: 1, courseDesc:null }, mutations:{ course_top(state, data){ state.courseDesc = data } }, actions:{ course_top(context, courseId){ // 異步:發送axios請求 Axios.get(`course/${courseId}/top/`) .then((res)=>{ let data = res.data.data; context.commit('course_top', data) }) .catch((err)=>{ console.log(err) }) } } })
演示以下代碼(分別在有key和沒有key的狀況下點擊按鈕):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-for中的key</title> <style> .userList { border: 1px solid red; margin: 20px 0; padding: 10px 10px; } </style> </head> <body> <div id="app"></div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript" src="lodash.js"></script> <script type="text/javascript"> Vue.component('my-com', { template: ` <div class = 'userList'> <div class = 'content'> <h3>{{obj.name}}</h3> <p>{{obj.content}}</p> </div> <div class="control"> <input placeholder="請輸入你的名字" /> </div> </div> `, props: { obj: Object } }); var App = { data() { return { datas: [ {id: 1, name: '張三', content: '我是張三'}, {id: 2, name: '李四', content: '我是李四'}, {id: 3, name: '王五', content: '我是王五'}, ] } }, template: ` <div> <button @click = 'shuffle1'>shuffle</button> <my-com v-for = '(obj,index) in datas' :obj = 'obj' :key = 'obj.id'></my-com> </div> `, methods: { shuffle1() { console.log(_.shuffle()); this.datas = _.shuffle(this.datas); } } } new Vue({ el: '#app', data: {}, components: { App }, template: `<App />` }); </script> </body> </html> Code
var arr = ['alex', 'wusir', 'egon', 'sylar']
// arr.splice(開始位置索引, 刪除個數, 插入元素)
arr.splice(1, 2)
// 索引從1開始,刪除2個,返回刪除元素列表,即['wusir', 'egon']
// 原數組arr爲 ['alex', 'sylar']
arr.splice(0, 0, '張三', '李四')
// 索引從0開始,刪除0個元素,即不刪除任何元素,返回[]數組,
// arr變爲['張三', '李四', 'alex', 'sylar']
總結:能夠作增刪改操做。
假設已經定義了一個組件Header.vue並拋出,在全局的main.js下按以下方式寫:
import Header from '@/components/Header/Header' Vue.component(Header.name, Header);
這樣,Header組件就是全局組件了,在任意組件中直接使用便可。