一、Vue-组件
组件是可复用的Vue
实例, 说白了就是一组可以重复使用的模板, 跟JSTL
的自定义标签、Thymeleal
的th:fragment
等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织
可以把网页分割成多个部分,而每个部分又可以想象成vue中的组件,而把所有的组件拼接在一起就是一个完整的网页
定义和使用组件
//定义一个组件
Vue.component('hello',{
template: '<spam>{{hello}}</span>'
});
//在页面中使用组件
<hello v-bind:hello ='url'></hello>
给组件中的属性传参
//定义一个组件
Vue.component('daidai',{ //定义组件名
props:['data'], //用于接收数据
template:'<li>我是被定义的组件{{data}}</li>' //定义一个专属的组件
});
//给组件中的属性传参
<daidai v-for="item in msg" v-bind:data='item'></daidai>
//可以看到,组件中有个props属性,里面有参数data
//我们可以在标签中使用v-bind或@来绑定这个参数进行赋值
二、Vue-插槽
插槽的理解(个人理解)
把页面中的div标签想想成一个大插板,我们插上不同的电器能实现不同的功能,也就是说,我们可以把不同的标签来放进这个div标签内,进行实现不同的界面,而通常情况下,一个页面编写完成后,每个标签的位置就已经固定了,这样就很死板,vue中的插槽就是来实现动态修改该位置上的标签,提前预留好插槽,可以进行热插拔
//定义一个组件作为一个插槽
Vue.component('chacao',{
template:'<div><slot name="titl"></slot><br></div>' //定义一个插槽,自定义命名
});
//自定义一个组件,用来放插槽里面
Vue.component('titlw',{
props:['name'], //用来接收数据的变量(形参)
template: '<div>{{name}}</div>'
});
//先把插槽放在页面中,再把要插入的组件放插槽里
<chacao>
<titlw slot="titl"></titlw> //使用组件放插槽内,并将形参绑定数据
</chacao>
//其中slot属性指的是放进哪个插槽里面,因为页面中可能有多个插槽
三、父子组件传值
**前提:**正常情况下,自定义组件和vue对象是同一等级的,也就是说,自定义变量不可以直接去调用vue对象中的函数,以及不能向vue对象中传值,但是如果在同一个挂载点下面,自定义组件是可以直接使用vue对象中的参数,通过自定义事件,我们可以直接使用vue对象中的函数
练习:把子对象中的信息给取出来,然后传给父对象
<div id="father">
<child @tmii="mis()"></child>
<child @tmii="mms('呆呆你好呀!')"></child>
</div>
<script>
//创建一个组件作为子对象
Vue.component('child',{
template:'<button @click="tmii">测试</button>',
methods:{
tmii:function () {
this.$emit('tmii') //提升作用域,指向父标签中的函数
}
}
});
//创建一个vue作为父对象
var apk = new Vue({
el:'#father',
methods:{
mis:function () {
alert("通过子标签中定义的事件触发父标签函数成功!")
},
mms:function (index) {
alert("子函数调用父函数传进来的参数为"+index);
}
}
})
</script>
父子传值思路:
- 首先在子标签里面自定义一个函数
- 然后把这个函数的作用域给提升 使用 this.$emit(‘这个函数的名字’,参数)
- 在子标签中绑定这个自定义的函数,指向所要调用的父标签种函数的名字
综合练习:使用插槽,并实现点击删除vue对象中数组中的数据
//定义一个组件作为插槽
Vue.component('chacao',{
template:'<div><slot name="titl"></slot><br></div>' //定义一个插槽,自定义命名
});
//自定义一个组件,用来放插槽里面
Vue.component('titlw',{
props:['name','xiabiao'], //用来接收数据的变量(形参)
template: '<div>{{xiabiao}}---{{name}}---<button @click="dele()">删除</button></div>', //绑定事件来触发本组件中的函数
methods:{
dele:function (xiabiao) { //自定义一个事件
console.log("删除了"+name);
this.$emit('dele',xiabiao); //提升函数的作用域(个人理解)
//通过这样去操作可以触发vue里面的函数
}
}
});
//创建一个Vue对象
var app = new Vue({
el:"#app",
data:{
msg:['java','djsakdj','4657']
},
methods:{
remove:function (start) {
this.msg.splice(start,1) //js中操作数组的语法,删除以index开始
// 第一个元素,也就是它本身
}
}
});
//html中的使用
<div id="app">
<chacao>
<!--//v-for(临时变量名,数组下标) -->
<!--//把取出来的值传给组件-->
<titlw v-for="(course,i) in msg" slot="titl" :name="course" :xiabiao="i"
@dele="remove(i)"
></titlw>
</chacao>
</div>
四、计算属性
**理解:**一些不需要实时更新的数据可以在加载出来之后作为一个属性保存起来,只要数据不发生变化,该属性值就不会变,有点类似于缓存
- methods:定义方法, 调用方法使用tim(), 需要带括号
- computed:定义计算属性, 调用属性使用tim1, 不需要带括号
<div id="app">
<button @click ='tim'>显示时间</button>
<button @click ='tim1'>显示时间</button>
</div>
<script>
var app = new Vue({
el:"#app",
methods: { //定义一个方法
tim: function () {
alert(Date.now())
}
},
computed:{ //计算属性
tim1: function () {
return Date.now()
}
}
});
</script>
五、Vue的生命周期
六、第一个Vue-cli项目
vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板,预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速
- 环境配置
---Node.js
下载地址: http://nodejs.cn/download/ 安装的时候一直下一步直到结束
确认是否安装成功:
在cmd中运行node -v命令,查看是否能够输出版本号
在cmd中运行npm -v命令,查看是否能够输出版本号
---node.js淘宝镜像加速器(cnpm)
# -g 就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题,但是每次install都需要
npm install --registry=https://registry.npm.taobao.org
---vue-cli
cnpm instal1 vue-cli-g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list
- 创建应用程序
#这里的myvue是顶日名称,可以根据自己的需求起名
vue init webpack myvue
#一路选no
#初始化并运行
cd myvue
npm install
npm run dev
#访问localhost:8080即可
补充知识:vue init webpack 卡在chromedriver上问题解决办法
#可以用这个命令先安装好chromedriver,然后再执行vue init webpack projectname
npm install --global chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
#可以通过执行下面的命令,将下载地址配置到国内的镜像上:
npm config set chromedriver_cdnurl https://npm.taobao.org/mirrors/chromedriver
七、webpack的使用
WebPack是一款模块加载器兼打包工具, 它能把各种资源, 如JS、JSX、ES 6、SASS、LESS、图片等都作为模块来处理和使用
- 安装
npm install webpack -g
npm install webpack-cli -g
#查看版本号
webpack -v
webpack-cli -v
-
配置
- entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
output:输出, 指定WebPack把处理完成的文件放置到指定路径
module:模块, 用于处理各种类型的文件
plugins:插件, 如:热更新、代码重用等
resolve:设置路径指向
watch:监听, 用于设置文件改动后直接打包
- entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
-
打包命令 webpack
-
使用
- 在src目录下创建webpack.config.js
module.exports={ entry:'./modules/main.js', //入口 output:{ filename:'./js/main.js' //输出 } };
- 在项目目录下创建HTML页面,如index.html,导入webpack打包后的JS文件
八、vue-router(可以想象成路由器,用来分发页面)
-
安装
npm install vue-router --save-dev
-
删除src中的无用目录和文件(其他目录中的文件不要动)
只保留components文件夹、main.js、App.vue
-
使用
在src下创建router目录 在该=router目录下创建index.js //router的主配置文件 然后在components创建两个组件,等下可以使用router进行分发
使用
-
index.js
//index.js用来放router的配置文件,主要是控制视图的跳转 //可以把它想象成SpringMVC中的Controller import Vue from 'vue'; //导入路由插件 import VueRouter from 'vue-router'; //打入自定义组件 import Main from '../components/Main'; //安装路由 Vue.use(VueRouter); //配置路由 export default new VueRouter({ routes:[{ //路由路径 path:'/main', //路由名称 name:'main', //可有可无 //跳转到的组件 component:Main //注意,跳转到组件的地方不要加引号 },] })
-
App.vue
//最主要的vue组件,可以把他想象成html中的index //默认调用的就是App.vue <template> <div id="app"> <!-- router-link:默认会被渲染成一个<a>标签,to属性为指定链接 router-view:用于渲染路由匹配到的组件 --> <h1>测试路由</h1> <router-link to="/main">首页</router-link> <router-view/> <!--渲染路由分发出来的效果--> </div> </template> <script> export default { name: 'App', } </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>
-
main.js
//主要的js文件,用于控制各种模块 //这里是用来将router添加到项目中 import Vue from 'vue' import App from './App' import router from './router' //自动扫描路由 Vue.config.productionTip = false; //这是一个开发提示 new Vue({ el: '#app', router, //加入路由 });
路由嵌套
说白了,路由嵌套就是给分发的组件再进行分发(添加子组件)
比如说分发一个地址到index,进行路由嵌套,就可以分发到下一级目录
如index/a、index/b
//导入vue
import Vue from 'vue';
import VueRouter from 'vue-router';
//导入组件
import Main from "../views/Main";
import Login from "../views/Login";
//导入子模块
import UserList from "../views/user/List";
import UserProfile from "../views/user/Profile";
//使用
Vue.use(VueRouter);
//导出
export default new VueRouter({
routes: [
{
//登录页
path: '/main',
component: Main,
// 写入子模块
children: [
{
path: '/user/profile/id/name/age', //可以传参
name:'UserProfile', //在视图层可以使用名字来进行跳转
component: UserProfile,
props:true
}
]
},
//首页
{
path: '/login',
component: Login
},
]
})
对应子组件
<template>
<div>
<h1>个人信息</h1>
{{id}}----{{name}}----{{age}}
</div>
</template>
<script>
export default {
name: "UserProfile",
props:['id','name','age'],
}
</script>
<style scoped>
</style>
九、参数传递和重定向
方法一:
-
index.js
{ path: '/user/profile/:id', name:'UserProfile', component: UserProfile }
-
视图层
<!--name是组件的名字 params是传的参数 如果要传参数的话就需要用v:bind:来绑定--> <router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link> //说明: 此时我们在Main.vue中的route-link位置处 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径
-
接收参数
template> <!-- 所有的元素必须在根节点下--> <div> <h1>个人信息</h1> {{$route.params.id}} </div> </template>
方法二:
使用props 减少耦合
-
index.js
{ path: '/user/profile/:id', name:'UserProfile', component: UserProfile, props: true }
-
视图层不变
-
接收参数
<template> <div> 个人信息 {{ id }} </div> </template> <script> export default { props: ['id'], name: "UserProfile" } </script> <style scoped> </style>
重定向
-
index中添加一个属性redirect
{ path: '/goHome', redirect: '/main' }
十、路由模式、404、钩子(都在index.js中配置)
-
路由模式有两种
- hash:路径带 # 符号,如 http://localhost/#/login
- history:路径不带 # 符号,如 http://localhost/login
export default new VueRouter({ mode:'history', routes: [] )}
-
404界面
import NotFound from '../views/NotFound' { path: '*', //放在最下面 component: NotFound }
-
路由钩子
- beforeRouteEnter:在进入路由前执行
- beforeRouteLeave:在离开路由前执行
<script> export default { name: "UserProfile", beforeRouteEnter: (to, from, next) => { console.log("准备进入个人信息页"); next(); }, beforeRouteLeave: (to, from, next) => { console.log("准备离开个人信息页"); next(); } } </script> 参数说明: to:路由将要跳转的路径信息 from:路径跳转前的路径信息 next:路由的控制参数 next() 跳入下一个页面 next(’/path’) 改变路由的跳转方向,使其跳到另一个路由 next(false) 返回原来的页面 next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例
十一、Vue整合ElementUI
#新建一个Vue项目
vue init webpack 项目名
#进入该项目
cd 项目名
#安装vue-router
npm install vue-router
#安装elementui
npm i element-ui -S
#安装SASS加载器
npm install sass-loader@7.3.1 node-sass --save-dev
#安装项目依赖
npm install
#启动项目
npm run dev