Vue入门
if for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-if-for</title>
<!-- 导入vue.js-->
<script src="/vue.js/vue.js"></script>
</head>
<body>
<!--view层-->
<div id="app">
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else="type==='C'">C</h1>
<li v-for="(item,index) in items">
{{item.message}}--{{index}}
</li>
</div>
<script type="text/javascript">
let vm =new Vue({
el:"#app",
//Model层
data:{
ok:true,
type:"A",
items:[
{message:"111"},
{message:"222"},
{message:"333"},
]
}
});
</script>
</body>
</html>
事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-事件</title>
</head>
<body>
<div id="app">
<button v-on:click="message+=1">click me</button>
<h1>{{message}}</h1>
<button v-on:click="say('hi')">say Hi</button>
<button v-on:click="say('hello')">say hello</button>
<button v-on:click="say()">say</button>
</div>
<script src="/vue.js/vue.js"></script>
<script type="text/javascript">
let vm =new Vue({
el:"#app",
data:{
message: 0
},
methods:{
//方法必须定义在Vue的methods对象中
say:function () {
alert(this.message)
}
// say:function (e) {
// alert(e)
// }
}
});
</script>
</body>
</html>
双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-双向绑定</title>
</head>
<body>
<div id="app">
输入的文本:<input type="text" v-model="message">
<h3>
{{message}}
</h3>
性别:
<input type="radio" name="sex" value="男" v-model="fan">男
<input type="radio" name="sex" value="女" v-model="fan">女
<h3>
选中了: {{fan}}
</h3>
下拉框:
<select v-model="select">
<option disabled value="">---请选择---</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<h3>
选中了: {{select}}
</h3>
</div>
<script src="/vue.js/vue.js"></script>
<script type="text/javascript">
let vm =new Vue({
el:"#app",
data:{
message: "",
fan: "",
select:""
}
});
</script>
</body>
</html>
component
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-component</title>
</head>
<body>
<div id="app">
<!-- 组件-->
<fan v-for="item in items" v-bind:number="item"></fan>
</div>
<script src="/vue.js/vue.js"></script>
<script type="text/javascript">
<!--定义一个vue组件-->
Vue.component("fan",{
props:['number'],
template:'<li>{{number}}</li>'
});
let vm =new Vue({
el:"#app",
data:{
items:["111","222","333"]
}
});
</script>
</body>
</html>
axios通信
什么是axios?
Axios是一个开源的可以用在浏览器端和Node JS的异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下:
- 从浏览器中创建XMLHttpRequests
- 从node.js创建http请求
- 支持Promise API[JS中链式编程]
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF(跨站请求伪造)
{
"name": "fanna",
"url": "https://www.cnblogs.com/fanyaa",
"page": 1,
"isNonProfit": true,
"address": {
"street": "含光门",
"city": "陕西西安",
"country": "中国"
},
"links": [
{
"name": "bilibili",
"url": "https://space.bilibili.com/95256449"
},
{
"name": "狂神说Java",
"url": "https://blog.kuangstudy.com"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios通信</title>
</head>
<body>
<div id="vue">
<div>{{info.name}}</div>
<div>{{info.address.street}}</div>
<a v-bind:href="info.url">点我进入我的博客</a>
</div>
<script src="/vue.js/vue.js"></script>
<script src="/axios.js/axios.js"></script>
<script type="text/javascript">
let vm =new Vue({
el:"#vue",
//接收数据
data(){
return{
// 请求的返回参数格式必须和json字符串一样
info:{
name:null,
url:null,
address:{
street:null,
city:null,
country:null
}
}
}
},
mounted(){//钩子函数 链式编程
axios.get('data.json').then(response=>(console.log(this.info=response.data)))
}
});
</script>
</body>
</html>

计算属性
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-计算属性</title>
</head>
<body>
<div id="app">
<h3>Time1:{{currentTime1()}}</h3>
<h3>Time2:{{currentTime2}}</h3>
</div>
<script src="/vue.js/vue.js"></script>
<script type="text/javascript">
let vm =new Vue({
el:"#app",
data:{
message:'hello,fan'
},
methods:{
currentTime1:function () {
return new Date().toTimeString();
}
},
computed:{//计算属性,methods 和 computed 方法不能重名
currentTime2:function () {
this.message;
return new Date().toTimeString();
}
}
});
</script>
</body>
</html>

插槽slot
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-插槽slot</title>
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="todoTitle"></todo-title>
<todo-items slot="todo-items" v-for="todoItem in todoItems" v-bind:item="todoItem"></todo-items>
</todo>
</div>
<script src="/vue.js/vue.js"></script>
<script type="text/javascript">
Vue.component("todo",{
template:
'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:['title'],
template:
'<div>{{title}}</div>'
});
Vue.component("todo-items",{
props:['item'],
template:
'<li>{{item}}</li>'
});
let vm =new Vue({
el:"#app",
data:{
todoTitle:"书籍列表",
todoItems:['java','python','c++']
},
});
</script>
</body>
</html>
自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-自定义事件</title>
</head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:title="todoTitle"></todo-title>
<todo-items slot="todo-items" v-for="(todoItem,todoIndex) in todoItems"
v-bind:item="todoItem" v-bind:index="todoIndex" v-on:remove="removeItems(todoIndex)"></todo-items>
</todo>
</div>
<script src="/vue.js/vue.js"></script>
<script type="text/javascript">
Vue.component("todo",{
template:
'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:['title'],
template:
'<div>{{title}}</div>'
});
// v-on:click简写@click
Vue.component("todo-items",{
props:['item','index'],
template://只能绑定当前组件的方法
'<li>{{index}}---{{item}}<button v-on:click="remove()">删除</button></li>',
methods:{
remove:function (index) {
//自定义事件
this.$emit('remove',index);
}
}
});
let vm =new Vue({
el:"#app",
data:{
todoTitle:"书籍列表",
todoItems:['java','python','c++']
},
methods: {
removeItems:function (index){
this.todoItems.splice(index,1,);//一次删除一个元素
}
}
});
</script>
</body>
</html>
理一下思路:
在插槽的基础上,我想达到一个效果,我点击哪一个,哪一个就被删除。
所以,就需要在组件todo-items上绑定一个删除事件,就需要在组件内写一个remove方法,但是组件只能绑定当前组件的方法,无法实现删除Vue内date数据里的
todoItems:['java','python','c++'],所以,自定义事件出现了。
<div id="app">
</div>
因为Vue获取了这个标签,所以在这个标签里,可以操作Vue的data和methods,所以
<todo-items slot="todo-items" v-for="(todoItem,todoIndex) in todoItems"
v-bind:item="todoItem" v-bind:index="todoIndex" v-on:remove="removeItems(todoIndex)"></todo-items>
通过v-for获取列表的下标值,再通过v-bind绑定index,props参数传递到组件中,v-on将自定义事件remove和Vue下的removeItems(todoIndex)方法
绑定起来,
removeItems:function (index){
this.todoItems.splice(index,1,);//一次删除一个元素
}
这个方法就是用来删除数据中的元素
remove:function (index) {
//自定义事件
this.$emit('remove',index);
}
而,remove则通过this.$emit('remove',index)方法,进行事件分发,从而实现效果。
vue-cli
需要的环境
node.js下载:http://nodejs.cn/download/
安装就是无脑的下一步就好,安装在自己的环境目录下
Git:https://git-scm.com/doenloads
镜像:https://npm.taobao.org/mirrors/git-for-windows/
确认nodejs安装成功:
- cmd下输入node -v,查看是否能够正确打印出版本号即可!
- cmd下输入npm -v,查看是否能够正确打印出版本号即可!
这个npm,就是一个软件包管理工具,就和linux下的apt软件安装差不多!安装Node.js淘宝镜像加速器(cnpm),这样的话,下载会快很多~
尽量使用管理员运行安装
# -g 就是全局安装
npm install cnpm -g
# 或使用如下语句解决npm速度慢的问题
npm install --registry=https://registry.npm.taobao.org
cnpm instal1 vue-cli-g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack vue list
创建一个基于webpack模板的vue应用程序



总结一下,配了好久一直报错,cnpm配了呀,但没啥用。最后是先配了淘宝的镜像,然后就OK了。
步骤:
- npm config set registry https://registry.npm.taobao.org
- npm config get registry
- 进入想要创建的文件夹,执行

- vue init webpack vue_cli
- cd vue_cli
- npm install
- npm install -g npm-check-updates
- npm run dev
webpack使用
安装Webpack
npm install webpack -g
npm install webpack-cli -g
测试
webpack -v
webpack-cli -v
创建一个idea项目,webpack_study
在modules下新建一个hello.js
// 暴露一个方法
exports.sayHi = function () {
document.write("<h1>扣1送地狱火</h1>");
}
再新建一个main.js
var hello = require("./hello")
hello.sayHi();
在根目录下创建webpack.config.js
module.exports = {
entry:"./modules/main.js",
output:{
filename:"./js/bundle.js"
}
}
命令行打包

最后创建一个index.html,测试一下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="./dist/js/bundle.js"></script>
</body>
</html>
vue-router路由
vue-router是一个插件包, 所以我们还是需要用npm/cnpm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。
cnpm install vue-router@3.1.3 --save-dev
基于之前创建的vue_cli进行测试,先删除src中没用的数据,最终的框架如下:

先定义一个Content.vue组件和Main.vue组件
<template>
<h1>内容页</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>
<template>
<h1>首页</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
再建一个router文件夹,index.js,用来存放路由
import Vue from 'vue'
import VueRouter from "vue-router"
import Content from "../components/Content"
import Main from "../components/Main"
//安装路由
// 显示声明使用vue-router
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes:[
{
// 路由路径
path:'/content',
name:'content',
//跳转到的组件
component:Content
},
{
path: "/main",
name: "main",
component: Main
}
]
});
再在main.js中引用路由
import Vue from 'vue'
import App from './App'
import router from "./router" //自动扫描里面的路由配置
Vue.config.productionTip = false
new Vue({
el: '#app',
router,//配置路由
components: { App },
template: '<App/>'
})
最后在App.vue下使用路由
<template>
<div id="app">
<h1>Fan</h1>
<router-link to="/main">首页</router-link>
<router-link to="/content">内容页</router-link>
<router-view></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>
运行测试:npm run dev



vue+ElementUI
创建一个新项目
vue init webpack hello_vue
#进入工程目录
cd hello_vue
#安装vue-routern
cnpm install vue-router@3.1.3 --save-dev
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
# 安装SASS加载器
cnpm install sass-loader node-sass --save-dev
#启功测试
npm run dev
先删除src中没用的框架格式,最终框架如下:

创建一个Main.vue
<template>
<h1>首页</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
写一个Login.vue组件
<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
</el-form-item>
</el-form>
<el-dialog title="温馨提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return{
form:{
username:'',
password:''
},
//表单验证,需要在 el-form-item 元素中增加prop属性
rules:{
username:[
{required:true,message:"账号不可为空",trigger:"blur"}
],
password:[
{required:true,message:"密码不可为空",trigger:"blur"}
]
},
//对话框显示和隐藏
dialogVisible:false
}
},
methods:{
onSubmit:function(formName){
//为表单绑定验证功能
this.$refs[formName].validate((valid)=>{
if(valid){
//使用vue-router路由到指定界面,该方式称为编程式导航
this.$router.push('/main');
}else{
this.dialogVisible=true;
return false;
}
});
},
handleClose:function () {
this.dialogVisible=false;
}
}
}
</script>
<style lang="scss" scoped>
.login-box{
border:1px solid #DCDFE6;
width: 350px;
margin:180px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title{
text-align:center;
margin: 0 auto 40px auto;
color: #303133;
}
</style>
router包下index.js配置路由
import Vue from 'vue'
import Router from 'vue-router'
import Main from '../views/Main'
import Login from '../views/Login'
Vue.use(Router);
export default new Router({
routes:[
{
path:'/login',
component:Login
},
{
path:'/main',
component:Main
}
]
});
main.js引用路由
import Vue from 'vue'
import App from './App'
import router from "./router"
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
render: h => h(App)//ElementUI
});
App.vue
<template>
<div id="app">
<router-link to="/main">首页</router-link>
<router-link to="/login">登录</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
最后npm run dev,可能会有问题,原因是saas-loader版本和node.js版本不匹配
node -v查看自己的版本号

在package.json文件中找到sass-loader,将后面的版本号修改为对应的版本号后,之后重新打包一下npm install,然后 npm run dev
参数传递及重定向
在hello_vue项目基础上实现

Profile.vue
<template>
<!-- 所有的元素,不能直接在根节点下-->
<div>
<h1>个人信息页</h1>
<!-- <h3>{{$route.params.id}}</h3>-->
<h3>{{id}}</h3>
</div>
</template>
<script>
export default {
props:['id'],
name: "Profile"
}
</script>
<style scoped>
</style>
List.vue
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "List"
}
</script>
<style scoped>
</style>
Main.vue
<template>
<div>
<el-container>
<el-aside width="200px">
<el-menu :default-openeds="['1']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
<el-menu-item-group>
<el-menu-item index="1-1">
<!--插入的地方-->
<!-- name:传组件名,params:传递参数,需要对象v-bind-->
<router-link v-bind:to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<!--插入的地方-->
<router-link to="/user/list">用户列表</router-link>
</el-menu-item>
<el-menu-item index="1-3">
<!--插入的地方-->
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
<el-menu-item-group>
<el-menu-item index="2-1">分类管理</el-menu-item>
<el-menu-item index="2-2">内容列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-main>
<!--在这里展示视图-->
<router-view />
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scope d lang="scss">
.el-header {
background-color: #b9cbe1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
index.js
import Vue from 'vue'
import Router 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(Router);
export default new Router({
routes:[
{
path:'/login',
component:Login
},
{
path:'/main',
component:Main,//嵌套路由
children:[
{path:'/user/profile/:id', name:"UserProfile", component:UserProfile,props:true},//设置props为true,允许参数传递以props形式接收
{path:'/user/list', component:UserList}
]
},
{
//重定向
path:'/goHome',
redirect:'/main'
}
]
});



404和路由钩子
去url中#,index.js下配置mode:'history'
404
建一个NotFound.vue
<template>
<div>
<h1>你的页面走丢了</h1>
</div>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
然后去index.js下配路由
{
path:'*',
component:NotFound
}
路由钩子与异步请求
安装axios
cnpm install --save vue-axios
main.js引入axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
准备数据,静态数据存放的位置:static/mock/data.json
Profile.vue
<template>
<!-- 所有的元素,不能直接在根节点下-->
<div>
<h1>个人信息页</h1>
<!-- <h3>{{$route.params.id}}</h3>-->
<h3>{{id}}</h3>
</div>
</template>
<script>
export default {
props:['id'],
name: "Profile",
//过滤器,拦截器
beforeRouteEnter:(to,from,next)=>{
console.log("beforeRouteEnter");
//加载数据
next(vm=>{
vm.getData();//进入路由之前执行getData()
});
},
beforeRouteLeave:(to, from, next)=>{
console.log("beforeRouteLeave");
next();
},
methods:{
getData:function () {
this.axios({
method:'get',
url:'http://localhost:8081/static/mock/data.json'
}).then(function (response) {
console.log(response);
});
}
}
}
</script>
<style scoped>
</style>
beforeRouteEnter:在进入路由前执行
beforeRouteLeave:在离开路由前执行
参数说明:
to:路由将要跳转的路径信息
from:路径跳转前的路径信息
next:路由的控制参数
next() 跳入下一个页面
next('/path') 改变路由的跳转方向,使其跳到另一个路由
next(false) 返回原来的页面
next((vm)=>{}) 仅在 beforeRouteEnter 中可用,vm 是组件实例

浙公网安备 33010602011771号