摘要:提交是更改狀態(tài)的唯一方法,并且這個(gè)過(guò)程是同步的。對(duì)于大型應(yīng)用,我們會(huì)希望把相關(guān)代碼分割到模塊中。
vue-cli 腳手架工具的使用
vue-cli 的依賴(lài)
vue-cli 的使用流程
node 的安裝
node 是通過(guò)js 操作系統(tǒng)接口的語(yǔ)言; npm 是node的包管理工具;所以,安裝了node 就可以直接使用npm 下載我們需要的包;
node 可以直接去node官網(wǎng)下載對(duì)應(yīng)系統(tǒng)的安裝包,安裝提示完成;
然后在 命令行中 通過(guò) npm -v 查看npm 版本,如果有出來(lái)代表安裝成功;
npm 代理 到cnpm
你直接通過(guò)添加 npm 參數(shù) alias 一個(gè)新命令:
alias cnpm="npm --registry=https://registry.npm.taobao.org --cache=$HOME/.npm/.cache/cnpm --disturl=https://npm.taobao.org/dist --userconfig=$HOME/.cnpmrc"
然后運(yùn)行
cnpm install xx -g //全局安裝xx
使用 vue-cli
vue init webpack demoName //生成 webpack 為模板的vue項(xiàng)目
運(yùn)行熱更新頁(yè)面
npm run dev
生成項(xiàng)目可以直接通過(guò) http://localhost:8080/?#/ 訪問(wèn)
如果你是拉別人的項(xiàng)目運(yùn)行的,要先運(yùn)行下面的命令,安裝依賴(lài)包
npm install //或者 npm i
生成一個(gè) 靜態(tài)項(xiàng)目文件(直接打開(kāi)的靜態(tài)頁(yè)面)
npm run build
大多數(shù)情況 ,生成的頁(yè)面是不可以直接打開(kāi)的;提示只能部署到 服務(wù)器上才能正常訪問(wèn);
如果需要直接本地打開(kāi);到項(xiàng)目目錄下的config文件夾里的index.js文件中,將build對(duì)象下的assetsPublicPath中的“/”,改為“./”即可
生成的文件都是經(jīng)過(guò)壓縮的,帶md5的文件
export default{} , module.exports = {}, exports { }
在node 的模塊中,exports 是 module.exports 的引用;但是在vue 中 不能寫(xiě)成
exports = { porps:["text"] } // 提示 text 未定義;
exports default {} 定義的輸出;可以通過(guò) import xx 直接使用(標(biāo)準(zhǔn)ES6);寫(xiě)法是:
exports default {a:123} import a;
module.exports = {} 與 exports default 是等價(jià)的
但是如果 同一個(gè)js 同時(shí)出現(xiàn) module.exports ={} 和 import 就會(huì)報(bào)錯(cuò)
module.exports = {a:123} //定義和導(dǎo)出 import a; //引入 //上面兩個(gè)關(guān)鍵詞 不能同時(shí)出現(xiàn)在同一個(gè)js 中
報(bào)錯(cuò)原因如下:
webpack可以使用require和export ,但是不能混合使用import 和module.exports ,不然會(huì)報(bào)錯(cuò)Cannotvue-router 路由插件安裝
assign to read only property "exports" of object "#
安裝
cnpm install vue-router
引入為全局插件
配置路由表可以通過(guò)router-link 組件 鏈接到 對(duì)應(yīng)組件;它會(huì)解析成類(lèi)似a 標(biāo)簽
forms //注意書(shū)寫(xiě)格式一定要正確father
注意到 生成的url 中前面自動(dòng)加了個(gè) “#”;可以通過(guò)添加 mode:"history", 去掉
原理:https://router.vuejs.org/zh-c...
路由配置中,path 可以設(shè)置 url 帶參;
帶參path定義
表示 apple 后面跟的是參數(shù),不是路徑;
帶參路徑
獲取參數(shù)
所有的路由都是定義在 routes 生成的頁(yè)面中的;不能在子組件中重新定義;例子如下:
var router = new VueRouter() import browseMode from "./components/browse-mode.vue" import blogList from "./components/blog-list.vue" import blogArticle from "./components/blog-article.vue" import writePanel from "./components/write-panel.vue" router.map({ "/": { component: browseMode, subRoutes: { "/": { component: blogList }, "/details/:artId": { component: blogArticle } } }, "/edit/:mode": { component: writePanel }, "/search/tag/:tag": { component: browseMode, subRoutes: { "/": { component: blogList } } }, "/search/time/:time": { component: browseMode, subRoutes: { "/": { component: blogList } } }, "/search/title/:title": { component: browseMode, subRoutes: { "/": { component: blogList } } }, }) router.start(App, "app")
路由不是最適合做tab切換的;最適合做tab的是 components 內(nèi)置組件 ;通過(guò)is 控制切換;
var vm = new Vue({ el: "#example", data: { currentView: "home" //改變這個(gè)值就會(huì)切換內(nèi)容; }, components: { home: { /* ... */ }, posts: { /* ... */ }, archive: { /* ... */ } } })
定義帶參路由 的時(shí)候 注意格式是 path:"/box1/:text", 不是path:"/box1:text",(可以理解為/: 后面是參數(shù) ,/后面是路徑;)
定義好路由后, router-link 是可以放在任何地方的;它就是一個(gè)a標(biāo)簽;點(diǎn)擊會(huì)切換第一個(gè)父級(jí)的router-view 中的頁(yè)面;還要注意格式和傳參
獲取參數(shù)的時(shí)候,直接去到參數(shù)的值是 this.$route.params.text (text是你定義路由時(shí)的 :text )
因?yàn)?route 是一個(gè)全局變量,你還可以直接在html 中使用它的url參數(shù)
{{$route.params.text}}
定義一個(gè)多參數(shù) 路由的 url
使用時(shí)的url可能是這樣:
http://localhost:8080/#/apple/red/detail/fool //后面的detail 是固定的。
獲取的方法是一樣的;
var a = $route.params; //結(jié)果 a={ color:red, type:fool }子路由的定義
{ path:"/box1", component:box1, children:[ { // 當(dāng) /box1/box1a匹配成功, // box1a會(huì)被渲染在 box1的中 path:"box1a", //這里不加 “ / ” component:box1a }, { path:"box1b", component:box1b } ] }, // 要注意,以 / 開(kāi)頭的嵌套路徑會(huì)被當(dāng)作根路徑。 這讓你充分的使用嵌套組件而無(wú)須設(shè)置嵌套的路徑。 //在box1 中定義一行 //子組件 box1a 會(huì)自動(dòng)渲染 到頁(yè)面中; //如果添加兩個(gè) router-link 組件 就可以做tab切換(不建議用路由做tab) //router-link 只會(huì)切換 第一個(gè)父級(jí)的 router-view 中的內(nèi)容,所以不會(huì)刷新整個(gè) box1 ; //path 寫(xiě)成 /box1/box1a 是用了根路徑(絕對(duì)路徑)的形式; //如果寫(xiě)成 {path:"box1a"} 則是相對(duì)路徑;這樣寫(xiě)點(diǎn)擊 瀏覽器的url會(huì)寫(xiě)成 http://localhost:8080/box1a //因?yàn)轫敿?jí)路由中是沒(méi)有定義 box1a 組件的;所以頁(yè)面空白;
box1a box1b
帶參子路由
//路由定義 { path:"/box1/:text", component:box1, children:[ { path:"box1a", component:box1a }, { path:"box1b", component:box1b } ] }, //跳轉(zhuǎn)到 box1 的寫(xiě)法
router-link 中的to 屬性,如果只是簡(jiǎn)單的跳轉(zhuǎn)可以直接寫(xiě)成 to=“box1”;
如果加上:綁定屬性;后面的屬性可以是簡(jiǎn)短的 表達(dá)式,因此上面的例子可以簡(jiǎn)化為:
//路由定義 { path:"/box1/:text", component:box1, children:[ { path:"box1a", component:box1a }, { path:"box1b", component:box1b } ] }, //跳轉(zhuǎn)到 box1 的寫(xiě)法
具名路由
router-link 還可以通過(guò) name 指定跳轉(zhuǎn)(具名路由);通過(guò)例如 tag="li" 指定包裹標(biāo)簽為a以為的tag;
children:[ { path:"box1a", name:"nameBox", component:box1a } ]用具名路由布局(代替iframe的方式)nameBox //結(jié)果:會(huì)生成li, 點(diǎn)擊router-view 會(huì)渲染出 box1a ;注意,path是不可缺少的
export default new Router({ mode:"history", routes: [ { path:"/index", components:{ //注意這里是有 “ s ” 的 default:vuexIndex, //對(duì)應(yīng)在某個(gè)頁(yè)面中定義具名路由left:vuexLeft, // 對(duì)應(yīng) right:vuexRight //對(duì)應(yīng) } } ] }) //注意訪問(wèn)的路徑 是在components 中定義的path ;
{ path:"/layout", name:"layout", component:layout, children: [ { path: "/", components:{ default:main, leftView:leftView, topBar:topBar }, } ] }
路由的重定向
routes: [ { path:"/", redirect:"/box" //路徑不存在就跳轉(zhuǎn)到box }, { path: "/a", redirect: "/b" } //訪問(wèn)a的路徑,都跳轉(zhuǎn)到b ]vuex 狀態(tài)管理插件安裝
當(dāng)vue項(xiàng)目中 組件過(guò)多并設(shè)計(jì)到功能某些數(shù)據(jù)的時(shí)候,管理數(shù)據(jù)變得復(fù)雜,VUEX 就是通過(guò)自身的一套數(shù)據(jù)管理流程幫助你管理 項(xiàng)目數(shù)據(jù)(狀態(tài));
安裝
cnpm install vuex --save
實(shí)例化
//在main.js 中 import Vuex from "vuex" Vue.use(Vuex); let store = new Vuex.Store({ //Store 是vuex 方法 state:{ //存放變量的地方 total:0, appleTotal:0, bananaTotal:0, }, mutations:{ //定義同步變量的方法 aSetValue(state,value){ state.appleTotal = value state.total = state.appleTotal + state.bananaTotal; }, bSetValue(state,value){ state.bananaTotal = value state.total = state.appleTotal + state.bananaTotal; } } }) new Vue({ el: "#app", store, //在實(shí)例中 引入 router, components: { App }, template: "" })
獲取值
vuex 的變量store 全局以后可以通過(guò)以下語(yǔ)句獲取
this.$Store.state.total //組件中總價(jià):{{$store.state.total}}
還可以通過(guò)設(shè)置getter函數(shù) 暴露對(duì)應(yīng)的值
getters:{ getTotal(state){ return state.total } }, //組件中改變vuex變量的值總價(jià):{{$store.getters.getTotal}}
通過(guò)在組件中調(diào)用以下特定語(yǔ)句改變
methods:{ add(){ this.cnt += 1; //bSetValue 是在vuex實(shí)例的mutations中定義的方法 //通過(guò) bSetValue方法 去改變實(shí)例的值 this.$store.commit("bSetValue",this.cnt*5) }, minus(){ this.cnt-=1; this.$store.commit("bSetValue",this.cnt*5) } }, // 在vuex 中只有 commit 方法可以改變數(shù)據(jù);這里是不建議直接在組件中調(diào)用 cmmit 的 // 因?yàn)閏mmit中只能是同步操作;但是交互往往需要同步數(shù)據(jù)庫(kù) // 更加好的方法是在 actions的方法 中觸發(fā) commit;actions 方法支持異步操作; // 所有涉及 后端API 的接口都是放在actions 中進(jìn)行
actions 屬性
mutations:{ aSetValue(state,value){ state.appleTotal = value state.total = state.appleTotal + state.bananaTotal; }, bSetValue(state,value){ state.bananaTotal = value state.total = state.appleTotal + state.bananaTotal; } }, actions:{ // 定義doAfn 方法,間接觸發(fā) aSetValue; // 在doAfn 方法是可以用ajax 的 doAfn(context,price){ context.commit("aSetValue",price) }, doBfn(context,price){ context.commit("bSetValue",price) } }
組件中的觸發(fā)方式 通過(guò) dispatch 觸發(fā)doAfn;
this.$store.dispatch("doAfn",val*10)vuex 的 modules
Vuex 允許我們將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割:
官方文檔代碼
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的狀態(tài) store.state.b // -> moduleB 的狀態(tài)
官方的文檔組織建議:
應(yīng)用層級(jí)的狀態(tài)應(yīng)該集中到單個(gè) store 對(duì)象中。
提交 mutation 是更改狀態(tài)的唯一方法,并且這個(gè)過(guò)程是同步的。
異步邏輯都應(yīng)該封裝到 action 里面。
對(duì)于大型應(yīng)用,我們會(huì)希望把 Vuex 相關(guān)代碼分割到模塊中。下面是項(xiàng)目結(jié)構(gòu)示例:
├── index.html ├── main.js ├── api │ └── ... # 抽取出API請(qǐng)求 ├── components │ ├── App.vue │ └── ... └── store ├── index.js # 我們組裝模塊并導(dǎo)出 store 的地方 ├── actions.js # 根級(jí)別的 action ├── mutations.js # 根級(jí)別的 mutation └── modules ├── cart.js # 購(gòu)物車(chē)模塊 └── products.js # 產(chǎn)品模塊
https://vuex.vuejs.org/zh-cn/...
一個(gè) vuex 小例子父組件
我是left
(我是{{text?text:"路由的方式"}}來(lái)的)總價(jià):{{$store.getters.getTotal}}
apple 組件
蘋(píng)果 庫(kù)存不夠
banana 組件
香蕉 庫(kù)存不夠
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 Vuex from "vuex" import App from "./App" import router from "./router" Vue.config.productionTip = false Vue.use(Vuex); let store = new Vuex.Store({ state:{ total:0, appleTotal:0, bananaTotal:0, }, getters:{ getTotal(state){ return state.total } }, mutations:{ aSetValue(state,value){ state.appleTotal = value state.total = state.appleTotal + state.bananaTotal; }, bSetValue(state,value){ state.bananaTotal = value state.total = state.appleTotal + state.bananaTotal; } }, actions:{ doAfn(context,price){ context.commit("aSetValue",price) }, doBfn(context,price){ context.commit("bSetValue",price) } } }) /* eslint-disable no-new */ new Vue({ el: "#app", store, router, components: { App }, template: "" })
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92520.html
摘要:靜態(tài)圖片怎么引入對(duì)重復(fù)元素的遍歷產(chǎn)品數(shù)據(jù)統(tǒng)計(jì)數(shù)據(jù)預(yù)測(cè)流量分析廣告發(fā)布在重復(fù)的部分用如果某個(gè)重復(fù)的部分比較分散可用循環(huán),循環(huán)是從標(biāo)簽本身就開(kāi)始的既是的載體,也是與同一個(gè)標(biāo)簽的靈活使用遍歷的時(shí)候可以接受幾種賦值方式直接綁定的屬性 靜態(tài)logo圖片怎么引入 showImg(https://segmentfault.com/img/bV2iRj?w=350&h=163); 對(duì)重復(fù)元素...
摘要:重構(gòu)總共耗時(shí)個(gè)工作日。第一個(gè)重構(gòu)原因就是沒(méi)有引入靜態(tài)類(lèi)型,導(dǎo)致查看一個(gè)對(duì)象結(jié)構(gòu)需要翻來(lái)覆去在多個(gè)文件中查找。第三是各個(gè)狀態(tài)模塊耦合度高,加大了代碼維護(hù)難度。但如果耦合度過(guò)高,往往是因?yàn)槟K沒(méi)有細(xì)分到位。這個(gè)項(xiàng)目也不列外。 showImg(https://segmentfault.com/img/remote/1460000019660483); 不知不覺(jué)已是2019年的7月,恍惚之間已...
摘要:下滾動(dòng)到頁(yè)面底部無(wú)限加載數(shù)據(jù)看到一篇覺(jué)得挺實(shí)用的就看了下順便簡(jiǎn)單翻譯了一下給需要的人參考從這個(gè)項(xiàng)目中可以加深對(duì)的生命周期的理解何時(shí)開(kāi)始請(qǐng)求如何結(jié)合使用原生來(lái)寫(xiě)事件等等我這里主要是對(duì)原文的重點(diǎn)提取和補(bǔ)充本文技術(shù)要點(diǎn)生命周期簡(jiǎn)單用法格式化日期圖 Vue下滾動(dòng)到頁(yè)面底部無(wú)限加載數(shù)據(jù)Demo 看到一篇Implementing an Infinite Scroll with Vue.js, 覺(jué)得...
摘要:筆記說(shuō)明重學(xué)前端是程劭非前手機(jī)淘寶前端負(fù)責(zé)人在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以加入的專(zhuān)欄學(xué)習(xí)原文有的語(yǔ)音,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以...
摘要:筆記說(shuō)明重學(xué)前端是程劭非前手機(jī)淘寶前端負(fù)責(zé)人在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以加入的專(zhuān)欄學(xué)習(xí)原文有的語(yǔ)音,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開(kāi)的一個(gè)專(zhuān)欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以...
閱讀 1583·2021-09-24 10:38
閱讀 1518·2021-09-22 15:15
閱讀 3066·2021-09-09 09:33
閱讀 910·2019-08-30 11:08
閱讀 645·2019-08-30 10:52
閱讀 1258·2019-08-30 10:52
閱讀 2351·2019-08-28 18:01
閱讀 529·2019-08-28 17:55