总结vue 需要掌握的知识点
使用的开发工具是webstorm,它是默认就安装好了vuejs插件,idea要使用的话,需要安装一下该插件
一、快速搭建项目vue-cli 脚手架(Vue2.0)
1、Vue CLI使用前提 –Node、 Webpack
(1) 安装 nodejs并通过npm 安装 cnpm:
https://www.cnblogs.com/shan333/p/15726428.html
(2) 安装webpack(全局安装):
# 不写版本号,默认是安装最新的版本号
cnpm install webpack@3.6.0 -g 或 npm install webpack@3.6.0 -g
(3) 安装vue脚手架(vue-cli 版本是3.xx):
# 不写版本号,默认是安装最新的版本号
cnpm install @vue/cli -g 或 npm install @vue/cli -g
● 通过拉取模板就可以使用2.x版本(vue-cli2、vue-cli3任你选):
npm install -g @vue/cli-init 或 cnpm install -g @vue/cli-init
■ 本地安装与全局安装区别:
- 本地安装:仅将webpack安装在当前项目的node_modules目录中,仅对当前项目有效。
- 全局安装:将webpack安装在本机,对所有项目有效,全局安装会锁定一个webpack版本,该版本可能不适用某个项目。全局安装需要添加 -g 参数。
2、初始化Vue-cli2项目、Vue-cli3项目:
- 初始化Vue-cli2项目:
vue init webpack my-project
- 初始化Vue-cli3项目:
vue create my-project
runtime-compiler 和 runtime-only的选择:选 runtime-only
■ Vue-cli2项目、Vue-cli3项目区别:
仅仅只是vue-cli3会把node_modules 隐藏起来。
开发好项目,上传代码时node_modules 是不用上传上去的,只需要在readme提醒别人通过 npm install 命令即可在目录创建node_modules。
3、启动项目:
- 启动项目前先打包,再启动:
# 打包命令
npm run build
- Vue-cli2项目:
npm run dev
- Vue-cli3项目:
npm run serve
二、vue的浏览器调试插件 vue-devtools
- 像普通插件一样安装到浏览器即可
三、vue 的基本使用
■ 最简单的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.active{
color: goldenrod;
}
</style>
</head>
<body>
<div id="app" >
<!--插值表达式 {{ }}-->
{{message}}
<!--事件监听:监听点击事件@click-->
<button @click="btnActive">点击</button>
<!--属性绑定:样式绑定-->
<div :class="getClass()">样式</div>
</div>
</body>
<script type="text/javascript" src="../js/vue.min.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message:'切换颜色',
isActive: true,
active: 'active',
},
methods: {
btnActive() {
this.isActive = !this.isActive;
},
getClass () {
return this.active;
}
}
});
</script>
</body>
</html>
1、插值表达式 {{ }}
- 将值插入到我们模板的内容当中
2、双向绑定绑定 v-model
3、v-if 条件选择
-
v-else
-
v-show 适合经常切换的
4、v-for 循环
5、样式绑定
6、属性绑定
- v-bind 常用的是语法糖的冒号:
7、事件绑定
-
v-on 常用的是语法糖的@,经常使用的也是点击事件@click
-
事件修饰符
8、计算属性
- 和普通methods 属性的区别是:它具有缓存作用
9、插槽slot
在vue中看到$:代表使用但是是vue自身的属性或者是挂载到vue上的插件(比如route)的属性,目的是为了和咱自己定义的变量做一个区分
安装插件命令:npm install (若失败,可以使用cnpm install)
# npm install --save 插件名 # 安装路由 npm install vue-router --save # 安装vuex npm install vuex --save # 安装element-ui npm i element-ui -S # npm install # 安装axios npm install axios
- --save-dev 的话,安装到node_modules 目录中,并在devDependencies 节点下添加上依赖,-dev是在开发时需要用的,部署不需要,一般是一些打包压缩工具和一些格式转化工具
四、组件
1、什么是组件化
Vue的组件化设计思想借鉴了Java的面向对象思想。Java认为万物皆对象,在Vue中,万物皆组件。
也就是说,在实际的vue项目中,以及使用了Vue框架的项目中,Vue的对象都会以组件的形式出现,能被反复使用。
要想实现组件化,需要在页面中注册组件。
关于注册的方式有两种,分别是全局注册和本地注册。
2、注册
全局注册和本地注册区别:
全局注册可以在任何Vue根实例里面使用;而本地(局部)注册只能在绑定它的父组件中使用。
一般项目中只有一个Vue根实例(全局注册),其他组件都是局部注册的。
- 全局注册:
<div id="app">
<grob></grob>
</div>
<script>
// 注册
Vue.component('grob', {
template: '<h1>自定义组件!</h1>'
})
// 创建根实例Vue
new Vue({
el: '#app'
})
</script>
- 本地(局部)组件
<div id="app">
<localV></localV>
</div>
<script>
// 注册
var Child = {
template: '<h1>自定义组件!</h1>'
}
// 创建根实例
new Vue({
el: '#app',
components: {
// <localV> 将只在父模板可用
'localV': Child
}
})
</script>
3、模板占位符 template
(1) template 用于包裹元素,template 不会被渲染到页面上
template:每个组件文件中的根template,也就是最外层的template 只能有一个根元素,可以是div,也可以是其他元素。
即组件模板只能有一个根元素(通常是一个div)!
非根template没有限制,可以有多个。
template用于创建单文件组件,实际上是一种原子化的设计,可以一次定义,然后在任何地方生成dom,如果有多个子元素,就违背了这种原子设计,也就是说,一个template就只会渲染一个子组件树。
vue在动态创建dom的时候,会将template中的子元素作为入口进行创建,根据这个入口,遍历以该子元素作为根节点的整个节点树,然后创建虚拟dom。
如果template有多个子元素,那么vue就无法获取确切入口。
(2) template作用:
通过template,vue文件实现了结构的分层 html视图层、css样式层、js层
- 举例 Home.vue 文件:
<template>
<div id="home">
<el-container>
<base-header :activeIndex="activeIndex"></base-header>
<router-view class="me-container"/>
<base-footer v-show="footerShow"></base-footer>
</el-container>
</div>
</template>
<script>
import BaseFooter from '@/components/BaseFooter'
import BaseHeader from '@/views/BaseHeader'
export default {
name: 'Home',
data (){
return {
activeIndex: '/',
footerShow:true
}
},
components:{
'base-header':BaseHeader,
'base-footer':BaseFooter
},
beforeRouteEnter (to, from, next){
next(vm => {
vm.activeIndex = to.path
})
},
beforeRouteUpdate (to, from, next) {
if(to.path == '/'){
this.footerShow = true
}else{
this.footerShow = false
}
this.activeIndex = to.path
next()
}
}
</script>
<style>
.me-container{
margin: 100px auto 140px;
}
</style>
4、组件的生命周期
(1) 钩子函数
Vue中的组件是有生命周期的。每个生命阶段会有相应的生命周期钩子函数被调用。
在vue中分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后。
(2) Vue生命周期函数使用场景
- beforeCreate (使用频率低)
* 在实例创建以前调用
* 没有实例化,数据访问不到
★ created (使用频率高) 初始化数据】
此时状态:Vue里的数据在内存中已经创建完毕,但是还没有渲染到页面上。
可做操作:从服务器获取一些初始化的数据,或者通过ajax向服务器发送一些数据。
进行ajax请求异步数据的获取(发送请求,访问后端接口拿数据),初始化数据
* 实例被创建完成后调用
* 能拿到数据,能修改数据,
* 且修改数据不会触发updated beforeUpdate钩子函数
* 可以在这个钩子函数里发请求,访问后端接口拿数据
* 判断是否存在el,是否存在template,如果二者都有,以template为主优先, 如果 没有template,会选择el模板。
如果二者都没有,有$mount 也可以调用模板
-
beforeMount(载入前)
* 编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
* 真实的dom节点挂载到页面之前
* 编译模板已经结束,虚拟dom已经存在,
* 可以访问数据,也可以更改数据
* 且修改数据不会触发updated beforeUpdate钩子函数
★ mounted(载入后) 【获取dom节点、修改更新数据】
此时状态: 数据已经渲染在了浏览器的页面上。
可做操作:操作DOM节点
可以对挂载元素的dom节点进行获取,也可以访问后端接口拿数据,修改更新数据,触发更新钩子函数
* 真实的dom节点挂载到页面以后
<!--this.$refs找到ref表示的节点-->
<button id="firstBtn" @click="testClick()" ref="aa">{{testMsg}}</button>
<!--js层-->
var value = this.$refs.aa.innerText
* 可以访问和更改数据
* 且修改数据会触发更新钩子函数
- beforeUpdate(更新前)
* 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
- updated(更新后)
* 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。
* 然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
★ beforeDestroy(销毁前) 【移除定时器或者移除事件绑定】
此时状态:奄奄一息。
可做操作:移除定时器或者移除事件绑定。但是销毁的时候需要手动销毁.
- destroyed(销毁后)
* 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
(3) 总结 Vue 生命周期常用的构子函数以及其他常用函数
★ created (使用频率高) 初始化数据】
进行ajax请求异步数据的获取(发送请求,访问后端接口拿数据),初始化数据
★ mounted(载入后) 【获取dom节点、修改更新数据】
可以对挂载元素的dom节点进行获取,也可以访问后端接口拿数据,修改更新数据,触发更新钩子函数
★ updated
任何数据的更新,如果要做统一的业务逻辑处理
★ nextTick
针对单一事件更新数据后立即操作dom
- 由于Vue的异步更新策略导致我们对数据的修改不会立马体现到都没变化上,此时如果想要立即获取更新后的dom的状态,就需要使用nextTick方法
★ watch
监听数据变化,并做相应的处理
5、父组件和子组件(组件通信)
(1) 父组件向子组件传参---通过props 声明属性
在子组件(当前组件)中通过props声明属性,然后调用者(父组件)可以设置属性。
- 子组件 Header.vue
<template>
<div>
<h1>{{title}}</h1>
</div>
</template>
<script>
export default {
name:"Header",
/* 当前组件声明的属性,调用者可以设置属性 */
props:["MyTitle"],
data(){
return{
title:'header 页面头'
}
}
}
</script>
- 父组件 App.vue
<template>
<div id="app">
<!-- 在父组件调用子组件声明的属性(设置属性) -->
<Header :my-title="title"/>
</div>
</template>
<script>
//1、引入子组件
import Header from "./components/Header";
export default {
name:"App",
data(){
return{
title:'这是父组件传递给子组件的属性值'
}
}
}
</script>
(2) 子组件向父组件传参---一般是通过emit 自定义事件传参
▪ emit方式【事件传参】:是通过emit自定义了一个事件,发送事件的同时传递参数;然后父组件监听自定义事件,回调函数获取到参数
▪ props方式【回调传参】:是通过在props声明函数类型的属性,然后在子组件上监听事件回调传递参数,再在父组件设置属性,属性值是回调函数,此时回调函数获取到参数。
■ 事件传参:通过emit 自定义事件,然后在父组件监听自定义事件,然后回调函数获取参数
- 子组件 Header.vue
<template>
<div>
<button @click="btnClick">子组件</button>
</div>
</template>
<script>
export default {
name:"Header",
methods:{
btnClick(){
//子组件自定义事件bClick,并传递参数 params 给父组件
this.$emit("bClick", "params");
}
}
}
</script>
- 父组件 App.vue
<template>
<div id="app">
<!-- 在父组件监听子组件自定义的事件bClick,然后通过回调函数bbClick获取参数 -->
<Header @bClick=bbClick/>
</div>
</template>
<script>
//1、引入子组件
import Header from "./components/Header";
export default {
name:"App",
methods:{
bbClick(value){
console.log('父组件监听到子组件发出的事件和接收到子组件的数据' + value);
}
}
}
</script>
■ 通过props 声明属性是函数类型,然后子组件监听事件,回调传参;父组件设置属性,属性值是回调函数,在回调函数获取子组件传递的参数
- 子组件 Header.vue
<template>
<div>
<h1>子组件</h1>
<!-- 子组件监听事件,回调传参 -->
<button @click="changeTitle('标题')">子组件</button>
</div>
</template>
<script>
export default {
name:"Header",
/* 当前组件声明的属性(函数类型),调用者设置属性 */
props:["changeTitle"],
data(){
return{
title:'header 页面头'
}
}
}
</script>
- 父组件 App.vue
<template>
<div id="app">
<!-- 在父组件调用子组件声明的属性(设置属性),属性值是一个函数,在回调函数获取从子组件传递的参数 -->
<Header :change-title="myTitle"/>
</div>
</template>
<script>
//1、引入子组件
import Header from "./components/Header";
export default {
name:"App",
methods: {
myTitle(value){
console.log(value);
}
}
}
</script>
父子组件通信(父子组件的参数传递)是属于在同一个页面的参数传递。和路由传参不同,路由传参是通过url的参数进行传参,在不同页面的参数传递。
第三方插件:vue-route、vuex、axios、element-ui 在vue中使用思路:
1、通过npm istall 插件名 命令添加到node_modules,并添加到dependencies依赖下(在package.json 可以看到)
2、(第三方的东西一般会创建一个文件进行封装) 创建插件对象,然后导出
- 通过Vue的use方法安装插件
3、在项目的main.js 中引入插件对象,然后挂载到vue实例对象
对于element-ui 样式布局插件,不用抽离单独封装成一个文件,直接在项目的mian.js 中使用Vue的use方法安装插件,然后就可以直接使用了,不用挂载到Vue实例上。
五、vue-route
1、引入路由模块并使用
- 路由对象
// 1. 定义路由组件.
// 也可以从其他文件导入
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }
// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
// 我们后面再讨论嵌套路由。
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
]
// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = VueRouter.createRouter({
// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
history: VueRouter.createWebHashHistory(),
routes, // `routes: routes` 的缩写
})
export default router
- 在main.js 中引入路由模块并使用(挂载路由)
import Vue from 'vue'
import App from './App'
import router from './router'
new Vue({
el: '#app',
router,//使用路由模块
template: '<App/>',
components: { App }
})
- 路由体验:
<template>
<div id="app">
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
- 改变url,发现<router-view></router-view>中的内容发生改变
http://localhost:8080/#/ 显示home
http://localhost:8080/about 显示About
-
向router实例中添加mode属性:路由的两种模式
值"hash":url带#适用于调试模式
值"history":url不带#
2、路由传参
(1) 通过 params 获取参数的方式[动态路由]
① 路由path中声明参数
②
③ 在模块组件中接收参数 $route.params
// 路由path中声明参数,用于接收route-link 中传来的参数
const routes = [
// 动态字段以冒号开始
{ path: '/about/:id', component: User },
]
<!-- App.vue 父模块 -->
<!-- <route-link />的to属性传参 -->
<template>
<div id="app">
<!-- 使用 router-link 的to属性传递参数 -->
<router-link to="/about/1">Go to About</router-link>
<!-- 路由出口 -->
<router-view></router-view>
</div>
</template>
<!-- About.vue 父模块 -->
<!-- 在模块组件中接收参数 $route.params -->
<template>
<div> <!--在template中直接接收参数-->
<h2>{{$route.params.id}}</h2>
<h1>{{id}}</h>
</div>
</template>
<script>
export default {
name: 'About',
data(){
return {
id: this.$route.params.id //在js中接收参数
}
}
</script>
(2) 通过 quary 获取参数的方式
①
② 在模块组件中接收参数 $route.query
<!-- App.vue 父模块 -->
<!-- <route-link />的to属性传参 -->
<template>
<div id="app">
<!-- 使用 router-link 的to属性传递参数 -->
<router-link to="/about?id=1">Go to About</router-link>
<!-- 路由出口 -->
<router-view></router-view>
</div>
</template>
<!-- About.vue 父模块 -->
<!-- <route-link />的to属性传参 -->
<template>
<div>
<!--在template中直接接收参数-->
<h2>{{$route.query.id}}</h2>
<h1>{{id}}</h>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
id: this.$route.query.id //在js中接收参数
}
}
</script>
3、<route-link />的to属性
- to可以接收一个对象,对象的属性有parmas,也有query
<route-link to="{
path:'/aboout/123',
query:{name:'shan', age:18}
}" />
■ 补充一个常识,浏览器你看到地址url,其实是包括 path,和查询条件query
http://localhost:8080/about/123?name=shan&age=18
path:/about/123
query:是指从?开始的查看条件 ?name=shan&age=18,多个查询条件使用&隔开(除了第一个查询条件使用?)
4、总结路由传参 parmas 和 query
- 传递参数主要有两种类型: params 和 query
- 主要是写法格式不同,query是传统的传参方式,以?开始,而params(path 传参方式),其实是一种restful风格的传参方式[写法更整齐简洁]
- 两者传参方式没有好坏之分
- 需要注意的是params需要预定义声明参数,即在路由配置中定义 用冒号的形式标记
六、axios
1、axios 是什么?
Axios 是一个基于 Promise 的 HTTP 库(网络请求库),可以作用于浏览器和 node.js
2、安装(npm安装方式):
npm install axios
3、 axios网络模块过程:
(1)axios创建实例(全局配置/基本配置)
(2) 发送请求
(3) axios拦截器的使用
import axios from 'axios'
export function request(config) {
// 1.创建axios的实例(全局配置/基本配置)
const service = axios.create({
baseURL: 'http://123.207.32.32:8000',//还可以将baseURL的值抽取出去 baseURL: process.env.BASE_API,
timeout: 5000
})
// 2.axios的拦截器
// 2.1.请求拦截的作用
service.interceptors.request.use(config => {
// console.log(config);
// 1.比如config中的一些信息不符合服务器的要求
// 2.比如每次发送网络请求时, 都希望在界面中显示一个请求的图标
// 3.某些网络请求(比如登录(token)), 必须携带一些特殊的信息
return config
}, err => {
// console.log(err);
})
// 2.2.响应拦截
service.interceptors.response.use(res => {
// console.log(res);
return res.data
}, err => {
console.log(err);
})
// 3.发送真正的网络请求
return service(config)
}
- 针对模块组件封装成具体方法发送请求:
// article.js
import request from '@/request'
export function getHotArtices() {
return request({
url: '/articles/hot',
method: 'post'
})
}
export function viewArticle(id) {
return request({
url: `/articles/view/${id}`,
method: 'post'
})
}
.....
七、Vuex状态管理
- 后端对应的web是使用session管理状态
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 定义状态对象state,保存数据的仓库
const state={
//组件模块调用state中的属性:this.$store.state.userInfo
userInfo:{
id:'',
name:''
}
}
//相对于java对象的get方法
const getters={
//组件模块调用getter中的方法:this.$store.getters.getUserInfo
getUserInfo(state){
return state.userInfo;
}
}
//相当于java的set方法的mutations(同步执行)和 actions(异步执行)
const mutations ={
//组件模块调用mutations中的方法:this.$store.commit('updateUserInfo', userInfo) 通过提交commit
updateUserInfo(state, userInfo){
state.userInfo = userInfo;
}
}
const actions ={
//组件模块调用actions中的方法:this.$store.dispatch('asyncUpdateUserInfo', userInfo) 通过分发dispatch
asyncUpdateUserInfo(context, userInfo){
context.commit('updateUserInfo', userInfo);//最终还是调用同步的mutations中的方法
}
}
export default new Vuex({
state,
getters,
mutations,
actions
});
八、element-ui
- element-ui 和 bootstrap类似,都是做为样式组件的
1、引入 Element(完整引入)
- 在 main.js 中写入以下内容
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
2、Layout 布局
- 需要什么组件就直接从官网提供的布局组件那里复制
- 官网地址 组件 | Element
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!
本文来自博客园,作者:一乐乐,转载请注明原文链接:https://www.cnblogs.com/shan333/p/16483946.html