鄂州市政府網(wǎng)長沙seo培訓(xùn)
Vue的配置與項目創(chuàng)建
在這之前要先安裝nodejs
安裝腳手架
官網(wǎng)
Home | Vue CLI (vuejs.org)
先運行,切換成淘寶鏡像源,安裝速度更快
npm config set registry http://registry.npm.taobao.org?
創(chuàng)建項目
用編譯器打開一個空文件,在終端輸入創(chuàng)建代碼
以下是步驟
選擇N
運行結(jié)果
配置serve
配置完以下,就可以改動代碼,效果實時更新到頁面上,對于開發(fā)來說很方便。
但只有社區(qū)版idea在這里才有npm可以選
模板語法
綁值語法
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><div id="app">{{ message }}<div><!-- {{num++}},不要這么寫,別在這里運算,否則可能出錯 -->{{num}}</div><div>{{bool}}</div><div>{{ arr.find(v => v.name === '張三')?.age }}</div></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script><script>var app = new Vue({el: '#app',//element//把vue的實例綁定到id是app的上面//data: {message: 'Hello I\'m lmm',num: 1,bool: true,arr: [{ name: '張三', age: 20 }]}})</script>
</body></html>
渲染html(v-html)
<template><div><div>{{rowHtml}}</div><div v-html="rowHtml"></div></div>
</template><script>
export default {name:'test',data(){return{rowHtml: '<a href="https://www.taobao.com/">淘寶</a>'}}
}
</script>
可以看到綁值語法是不能渲染出鏈接的
綁定屬性(v-bind)
使用場景
1.綁定 HTML 屬性
- 用于動態(tài)設(shè)置元素的屬性,例如?
href
、src
、class
、id
?等。
<a v-bind:href="linkUrl">Click here</a>
<img v-bind:src="imageUrl" alt="Dynamic Image">
2.綁定多個屬性
- 可以通過對象語法綁定多個屬性。
<div v-bind="objectProps"></div>export default {data() {return {objectProps: {id: 'my-div',class: 'my-class',title: 'This is a title'}}}
}
實例
<template><div><a :href="url">點擊這里訪問淘寶</a><br><img :src="img" alt="Demo Image"><br></div>
</template><script>
import logo from '@/assets/logo.png';
export default {name: 'test',data() {return {url: 'https://www.taobao.com/',// img: '@/asset/logo.png'//注意要先導(dǎo)入才能用img:logo}}
}
</script>
?事件綁定(v-on)
快捷綁定
直接寫在行內(nèi)
綁定方法
<template><div><div :style="{ width: '100px', height: '100px', backgroundColor: color }" @click="changeColor" id="testColor">點我</div></div>
</template><script>
export default {name: 'test',data() {return {color: 'red' // 初始化顏色為紅色}},methods: {changeColor() {// 切換顏色this.color = this.color === 'red' ? 'blue' : 'red';}}
}
</script>
判斷(v-if)
如果為真,就渲染該內(nèi)容
<template><div><div v-if="color === '紅色'">紅色</div><div v-else>黑色</div></div>
</template><script>
import logo from '@/assets/logo.png';
export default {name: 'test',data() {return {color:'黑色'}}
}
</script>
列表渲染(v-for)
每個元素都要有唯一索引,綁定key
在實際開發(fā)中,每個元素都有寫好的索引,所以用不上index。
如果沒有的話,就用index來記錄
<template><div v-for="item in fruits">{{item}}</div><div v-for="item in user" :key="item.id">用已寫好的索引:{{key}}{{item.name}}</div><div v-for="(item,index) in user" :key="index">用系統(tǒng)分配的索引:{{key}}{{item.name}}</div></template><script>
export default {name: 'test',data() {return {fruits:['蘋果','香蕉','西瓜'],user:[{id:'1001',name:'alicia'},{id:'1002',name:'fafa'},{id:'1003',name:'cami'}]}},methods: {}
}
</script>
雙向綁定(v-model)
<template><div><input type="text" v-model="str"><p>{{str}}</p></div>
</template><script>
export default {name: 'test',data() {return {str:''}},methods: {}
}
</script>
組件基礎(chǔ)
scoped:如果在style中添加此屬性,就代表著,當(dāng)前樣式,只在當(dāng)前組件中生效
使用組件步驟
組件的組織
上圖想表達的是,組件間的使用是可以嵌套的
Props組件交互
prop可以使組件之間有數(shù)據(jù)傳遞
使用案例
父組件向子組件傳遞數(shù)據(jù)。被導(dǎo)入的組件是父組件。
App.vue
?組件(父組件):
<template><div id="app"><Test :age="age" :name="name" :arr="arr"></Test></div>
</template><script>
import Test from "@/components/test";export default {name: 'App',components: {Test},data() {return {age: 18,name: 'chen',arr: [1, 2, 3]}}
}
</script><style>
#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;
}
</style>
test.vue
?組件(子組件):
<template><p>props傳遞數(shù)據(jù)</p><div>{{ age }}</div><div>{{ name }}</div><div v-for="i in arr" :key="i">{{ i }}</div>
</template><script>
export default {name: 'Test',props: {age: {type: Number,default: 0},name: {type: String,default: ''},arr: {type: Array,default: function () {return [];}}}
}
</script><style>
/* 添加樣式 */
</style>
Prop類型
?需要注意的是,傳遞數(shù)組和對象必須使用函數(shù)進行返回
自定義事件組件交互
自定義事件是 Vue 中子組件與父組件進行交互的一種靈活方式。子組件可以通過
this.$emit
觸發(fā)事件,父組件則通過事件監(jiān)聽器來處理這些事件。這樣可以讓組件之間的通信更加模塊化和清晰。自定義事件可以在組件中反向傳遞數(shù)據(jù),prp可以將數(shù)據(jù)從父組件傳遞到子組件,那么反向如何操作呢,就可以利用自定義事件實現(xiàn)
$emit
子組件向父組件傳遞數(shù)據(jù)。被導(dǎo)入的組件是父組件。
子組件
<template><button @click="sendMsg">點擊傳遞數(shù)據(jù)</button>
</template><script>
export default {name: 'Test',data(){return{msg:'子組件向父組件傳遞數(shù)據(jù)'}},methods:{sendMsg(){this.$emit('onEvent',this.msg)}}}
</script><style>
/* 添加樣式 */
</style>
父組件?
<template><div id="app"><Test @onEvent="getMsg"></Test><div>{{msg}}</div></div>
</template><script>
import Test from "@/components/test";export default {name: 'App',data(){return{msg:''}},components: {Test},methods:{getMsg(data){this.msg = data}}}
</script><style>
#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;
}
</style>
組件生命周期
生命周期概述
Vue 組件的生命周期可以分為以下幾個階段:
- 創(chuàng)建階段
- 掛載階段
- 更新階段
- 銷毀階段
每個階段都有特定的生命周期鉤子函數(shù),你可以在這些鉤子函數(shù)中執(zhí)行相應(yīng)的邏輯。
1. 創(chuàng)建階段
-
beforeCreate
: 在實例被初始化之后,數(shù)據(jù)觀測和事件配置之前調(diào)用。這時data
和methods
還不可用。 -
created
: 實例已創(chuàng)建,數(shù)據(jù)觀測和事件配置完成。這時可以訪問data
、methods
和computed
,但 DOM 還未生成。
2. 掛載階段
-
beforeMount
: 在掛載開始之前被調(diào)用,render
函數(shù)首次被調(diào)用。這時模板已經(jīng)編譯,但尚未被渲染到 DOM 中。 -
mounted
: 掛載完成后調(diào)用,此時組件已經(jīng)被渲染到 DOM 上??梢栽L問 DOM 元素和進行 DOM 操作。網(wǎng)絡(luò)請求是放在這塊。因為元素被渲染出來之后,還需要向后臺請求數(shù)據(jù)。
3. 更新階段
-
beforeUpdate
: 數(shù)據(jù)更新之前調(diào)用,render
函數(shù)將被重新調(diào)用。這時你可以在 DOM 更新之前做一些處理。 -
updated
: 數(shù)據(jù)更新之后調(diào)用,此時 DOM 也已經(jīng)更新。可以執(zhí)行一些依賴于 DOM 更新的操作。
4. 銷毀階段
-
beforeUnmount
: 卸載之前調(diào)用,此時組件仍然可以訪問其數(shù)據(jù)和 DOM。 -
unmounted
: 卸載完成后調(diào)用,此時組件及其所有的子組件都已經(jīng)被銷毀。可以在這里進行清理工作,比如清除定時器、取消網(wǎng)絡(luò)請求等。
axios
安裝與引入
常用請求方法
如果不寫的話,默認(rèn)是get
查詢參數(shù)(get)
<template><div>{{data}}</div>
</template><script>
export default {name: 'Test',data(){return{data:{}}},mounted(){this.$axios({url: 'http://hmajax.itheima.net/api/city',//查詢參數(shù)params: {pname: '福建省'}}).then(result => {this.data = result})}}
</script><style>
/* 添加樣式 */
</style>
數(shù)據(jù)提交(post)
<template><div></div>
</template><script>
export default {name: 'Test',mounted(){this.$axios({url: 'http://hmajax.itheima.net/api/register',method: 'post',data: {username: 'clmm1234567',password: '123123'}}).then(result => {console.log(result)})}}
</script><style>
/* 添加樣式 */
</style>
總結(jié)
網(wǎng)絡(luò)請求封裝
vue路由
了解
學(xué)到了路由,那么記得創(chuàng)建vue項目的時候把router選上,會自動配置路由文件
App.vue
<template><div><router-link to="/">首頁</router-link>|<router-link to="/about">關(guān)于</router-link><div>123</div><router-view></router-view><div>321</div></div>
</template><script>
// import Test from "@/components/Test.vue";export default {name: 'App',components: {// Test},
}
</script><style>
#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;
}
</style>
index.js
import { createRouter, createWebHashHistory } from 'vue-router';
import HomeView from '../views/HomeView';
import AboutView from '../views/AboutView';const routes = [{path: '/',name: 'Home',component: HomeView},{path: '/about',name: 'About',component: AboutView}
];const router = createRouter({history: createWebHashHistory(),routes
});export default router;
main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import axios from 'axios';// 創(chuàng)建 Vue 應(yīng)用實例
const app = createApp(App);// 配置 axios 實例
app.config.globalProperties.$axios = axios;// 使用路由
app.use(router);// 掛載應(yīng)用
app.mount('#app');
路由傳遞參數(shù)
router配置
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView'const routes = [{path: '/',name: 'home',component: HomeView},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path:'/news',name:'news',component: ()=>import("../views/NewsView")},{path:'/newsDetail/:name',name:'newsDetail',component: ()=>import("../views/NewsDetailView")},
]const router = createRouter({history: createWebHashHistory(),routes
})export default router
NewView
<template><div><ul><li><router-link to="/newsDetail/網(wǎng)易">網(wǎng)易新聞</router-link></li><li><router-link to="/newsDetail/百度">百度新聞</router-link></li><li><router-link to="/newsDetail/猾偽">猾偽新聞</router-link></li></ul></div>
</template><script>
export default {name: "NewsView"
}
</script><style scoped></style>
NewsDetailView
<template><div><h3>新聞</h3>{{$route.params.name}}</div>
</template><script>
export default {name: "NewsDetailView"
}
</script><style scoped></style>
嵌套路由配置
index.js
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'const routes = [{path: '/',name: 'home',component: HomeView},{path: '/about',name: 'about',component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),redirect:'/about/b',children: [{path: 'a',component: () => import('../views/AboutSub/About_a')},{path: 'b',component: () => import('../views/AboutSub/About_b')}]}]const router = createRouter({history: createWebHashHistory(),routes
})export default router
AboutView.vue
<template><div class="about"><router-link to="/about/a">a | </router-link><router-link to="/about/b">b</router-link><router-view></router-view><h1>This is an about page</h1></div>
</template>
點進about頁面默認(rèn)是about_b,因為重定向了
Vue狀態(tài)管理
可以集中管理所有組件,不像props只能在父子間傳遞數(shù)據(jù)
引入狀態(tài)管理
創(chuàng)建項目的時候勾選vuex
如果在創(chuàng)建項目的時候已勾選vuex,下面的前三步就不用了
vue狀態(tài)管理核心
案例--面經(jīng)基礎(chǔ)
配置路由
先做一個底部導(dǎo)航切換效果。
配置路由
import { createRouter, createWebHistory } from 'vue-router'const routes = [{path:'/',component:()=>import('@/views/LayOut'),children:[{path:'/collect',component:()=>import('@/views/Collect')},{path:'/like',component:()=>import('@/views/Like')},{path:'/user',component:()=>import('@/views/User')},{path:'/articleList',component:()=>import('@/views/ArticleList')},]}
]const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes
})export default router
<template><div><div style="background-color: pink; width: 500px; height: 500px;"><router-view></router-view></div><nav><router-link to="/articleList">面經(jīng) |</router-link><router-link to="/collect">收藏 |</router-link><router-link to="/like">喜歡 |</router-link><router-link to="/user">我的</router-link></nav></div>
</template><style>a.router-link-active{color: red;}
</style>
需要注意的是,Layout中需要用router-view
Layout
組件作為一個包裹組件使用,這意味著它可能需要呈現(xiàn)其子路由內(nèi)容。Layout
中的<router-view>
組件用于展示其子路由(如/article
、/like
等)。這使得每個子路由在Layout
組件內(nèi)部渲染,同時Layout
組件可以包含共同的布局或?qū)Ш綏l。簡而言之,
Layout
中的<router-view>
用于渲染Layout
的子路由組件內(nèi)容。這樣,你可以在Layout
組件中管理應(yīng)用的布局和結(jié)構(gòu),同時動態(tài)展示不同的子視圖。
<template><div><router-view></router-view></div>
</template><script>
export default {name: "Layout"
}
</script><style scoped></style>
首頁請求渲染
<template><div><div v-for="item in articles":key="item.id"><p>{{item.stem}}</p></div></div>
</template><script>
import axios from "axios";
export default {name: "ArticleList",data(){return{articles:[]}},async created(){const { data } = await axios.get('https://mock.boxuegu.com/mock/3083/articles',);this.articles = data.result.rows;}
}
</script><style scoped></style>
跳轉(zhuǎn)詳情頁傳參
查詢參數(shù)
動態(tài)路由
路由配置
{path:'/detail/:id',component:() => import('@/views/ArticleDetail')}
路由使用
@click="$router.push(`/detail/${item.id}`)"
<template><div><div v-for="item in articles":key="item.id"@click="$router.push(`/detail/${item.id}`)"><p>{{item.stem}}</p></div></div>
</template><script>
import axios from "axios";
export default {name: "ArticleList",data(){return{articles:[]}},async created(){const { data } = await axios.get('https://mock.boxuegu.com/mock/3083/articles',);this.articles = data.result.rows;}
}
</script><style scoped></style>
面經(jīng)詳情頁的路由接收
this.$route.params.id
<template><div>面經(jīng)詳情</div>
</template><script>
export default {name: "ArticleDetail",created() {console.log(this.$route.params.id)}
}
</script><style scoped></style>
詳情頁渲染
<template><div>{{article.content}}</div>
</template><script>
import axios from "axios";
export default {name: "ArticleDetails",data(){return{article:{}}},async created() {const id = this.$route.params.idconsole.log(this.$route.params.id)const {data} = await axios.get(`https://mock.boxuegu.com/mock/3083/articles/${id}`)this.article = data.result}
}
</script><style scoped></style>