Vue在线使用?
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
简单实例? ? 取值和绑定
注意事项:vue代码需要放在body下,否则报错
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p id="app">{{msg}}</p>
<span v-bind:title="msg" id="app2">鼠标停留</span>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
var app = new Vue({
el : "#app",
data:{
msg: "hello vue"
}
});
var app2 = new Vue({
el : "#app2",
data:{
msg: new Date().toLocaleString()
}
});
</script>
</html>
v-if 判断
因为?v-if ?是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个?<template> ?元素当做不可见的包裹元素,并在上面使用?v-if 。最终的渲染结果将不包含?<template> ?元素。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
?你可以使用?v-else ?指令来表示?v-if ?的“else 块”。v-else ?元素必须紧跟在带?v-if ?或者?v-else-if ?的元素的后面,否则它将不会被识别。v-else-if ,顾名思义,充当?v-if ?的“else-if 块”,可以连续使用,类似于?v-else ,v-else-if ?也必须紧跟在带?v-if ?或者?v-else-if ?的元素之后。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-if</title>
</head>
<body>
<div id="app">
<li v-if="msg==='A'">msg为A</li>
<li v-else-if="msg==='B'">B</li>
<li v-else-if="msg==='C'">C</li>
<li v-else>不是A/B/C</li>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
msg: 'A'
}
});
</script>
</html>
v-for 遍历
遍历一个对象数组时,in前面的第一个参数表示一个对象,第二个参数表示下标
遍历一个对象时,in前面的第一个参数表示属性值,第二个参数表示属性名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for</title>
</head>
<body>
<div class="app">
<ul>
<li v-for="(m,index) in msg">{{index}}-{{m.people}}</li>
</ul>
</div>
<div id="app">
<ul>
<li v-for="m in msg">{{m}}</li>
</ul>
<hr style="color: yellow;">
<ul>
<li v-for="(m,index) in msg">{{index}}-{{m}}</li>
</ul>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
//我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,
// 而 item 则是被迭代的数组元素的别名。
var app = new Vue({
el: ".app",
data: {
msg: [
{people: "man"},
{people: "woman"}
]
}
});
// 遍历一个对象的 property 第二个的参数为 property 名称 (也就是键名):
var app2 = new Vue({
el: "#app",
data: {
msg: {
name: "lisi",
sex: "man"
}
}
});
</script>
</html>
v-on? 添加事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="app">
<button v-on:click="sayHi" style="height: 50px;width: 50px">sayHi</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
var app = new Vue({
el: ".app",
data: {
msg: "hello"
},
methods:{
sayHi: function () {
alert(this.msg);
}
}
});
</script>
</html>
v-model 双向绑定
你可以用?v-model ?指令在表单?<input> 、<textarea> ?及?<select> ?元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但?v-model ?本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model ?会忽略所有表单元素的?value 、checked 、selected ?attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的?data ?选项中声明初始值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model</title>
</head>
<body>
<div class="app">
<input type="radio" value="男" name="sex" v-model="msg">男
<input type="radio" value="女" name="sex" v-model="msg">女
<span>选中的性别:{{msg}}</span>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
var app = new Vue({
el: ".app",
data:{
msg: "男"
}
});
</script>
</html>
组件
一个可重复利用的自定义标签 与h1 、h2 类似
这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue ) 的模板中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.component</title>
</head>
<body>
<div class="app">
<!-- 通过v-bind将item传递到blog-post里的props里的一个属性-->
<blog-post v-for="item in msg" v-bind:title="item"></blog-post>
<!-- <blog-post></blog-post> 必须存在定义的div里面-->
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
Vue.component("blog-post",{
props: ['title'],
// template: '<h1>hello</h1>'
template: '<div><h1>{{title}}</h1><h2>hello</h2></div>'
});
var app = new Vue({
el: ".app",
data: {
msg: ["语文","数学"]
}
});
</script>
</html>
异步通信
类似ajax,实现通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios</title>
</head>
<body>
<div id="app">
<div>{{info.name}}</div>
<div>{{info}}--{{info.address.city}}</div>
<hr>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<!--异步通信-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var app = new Vue({
el: "#app",
// date()方法接受mounted返回值
//注意:这里data(){}应该没有意义,直接data:{}就可以,但里面一定有一个原始参数info,然后axios获取到的数据绑定到info上
// data(){
// return{
// info:{
// name : null,
// address: {
// city: null,
// country: null
// }
// }
// }
// },
data:{
info:{
}
},
mounted(){
axios.get("date.json").then(response=>(console.log(response.data)));
axios.get('date.json').then(response=>(this.info=response.data));
}
});
</script>
</html>
date.json
{
"name":"狂神说java",
"url": "http://baidu.com",
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
}
}
计算属性
他是一个属性,通过属性方式调用,这个属性有计算的能力,这里的计算就是函数,将函数的结果缓存起来通过属性调用,可以看出缓存
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
</head>
<body>
<div class="app">
<span>方法区方法:{{nowDate1()}}</span><br>
<span>计算属性:{{nowDate}}</span>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
var app = new Vue({
el: ".app",
methods:{
nowDate1: function(){
return new Date();
}
},
computed: {
nowDate: function () {
return new Date();
}
}
});
</script>
</html>
插槽slot
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>slot</title>
</head>
<body>
<div class="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title"></todo-title>
<todo-items slot="todo-items" v-for="items in todoItem" v-bind:item="items"></todo-items>
</todo>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
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: '<h1>{{title}}</h1>'
});
Vue.component('todo-items',{
props: ['item'],
template: '<li>{{item}}</li>'
});
var app = new Vue({
el: ".app",
data: {
title: "目录",
todoItem: ['java','python'],
}
});
</script>
</html>
自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>slot</title>
</head>
<body>
<div class="app">
<todo>
<todo-title slot="todo-title" v-bind:title="title"></todo-title>
<todo-items slot="todo-items" v-for="(items,index) in todoItem"
v-bind:item="items" v-bind:index="index" v-on:abc="removeItem(index)"></todo-items>
<!-- 当v-on: 后面加的是自定义事件时,需要在自定义组件里面 this.$emit('abc'); 定义-->
</todo>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
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: '<h1>{{title}}</h1>'
});
Vue.component('todo-items',{
props: ['item','index'],
//点击事件和 remove方法绑定
template: '<li>{{index}}--{{item}} <button v-on:click="remove">删除</button></li>',
methods:{
remove: function () {
alert("删除"+this.index);
//远程调用vue app里面的方法
this.$emit('abc');
}
}
});
var app = new Vue({
el: ".app",
data: {
title: "目录",
todoItem: ['c','java','python'],
},
methods: {
removeItem: function (index) {
this.todoItem.splice(index,1)
}
}
});
</script>
</html>
1和2有联系? , 3和4有联系

?webpack
用管理员身份打开命令行,安装webpack. 安装3版本,可以不用配置dev,prop两种环境,网络上缺少4或者5版本的教程。如果是降级的需要重新打开命令行窗口查看版本
全局安装
npm install webpack@3.5.5 -g
npm install webpack-cli@3.3.9 -g
检测版本
webpack -v
webpack-cli -v
js
hello.js
exports.sayhi = function () {
document.write("<h1>hello</h1>")
}
main.js
var hello = require("./hello");
hello.sayhi();
webpack.config.js 在根目录
module.exports = {
//入口
entry: './modules/main.js',
//输出
output: {
filename: './js/bundle.js'
},
};
以下命令在idea项目中操作
在使用 webpack命令打包前初始化package.json
初始化 package.json
npm init -y
打包
webpack
?创建html验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 导入压缩后的js-->
<script src="js/bundle.js"></script>
</head>
<body>
</body>
</html>
vue-router

两个内容组件
Content.vue
<template>
<h1>内容页</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>
HelloWorld.vue
<template>
<h1>内容页</h1>
</template>
<script>
export default {
name: "HelloWorld"
}
</script>
<style scoped>
</style>
?index.js? ?路由配置
import Vue from 'vue'
import VueRouter from 'vue-router'
import Content from "../components/Content";
import HelloWorld from "../components/HelloWorld";
//安装路由 路径
Vue.use(VueRouter);
// 导出路由
export default new VueRouter({
routes: [
{
path: "/content",
component: Content
},
{
path: "/helloworld",
component: HelloWorld
}
]
});
main.js? 主页配置
import Vue from 'vue'
import App from './App'
import router from './router' //自动扫描里面的路由配置
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router, // 配置路由
components: { App },
template: '<App/>'
})
主页
App.vue
<template>
<div id="app">
<!-- <img src="./assets/logo.png">-->
<!-- <HelloWorld/>-->
<h1>hello</h1>
<router-link to="/helloworld">HelloWorld</router-link>
<router-link to="/content">内容</router-link>
<router-view></router-view>
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld'
//import Content from "./components/Content";
export default {
name: 'App',
// components: {
// // HelloWorld
// //Content
//
// }
}
</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>
Element
Element组件与vue快速搭建页面
layer弹窗组件
根据之前创建vue-cli项目一样再来一遍 创建项目 1. 创建一个名为 hello-vue 的工程 vue init webpack hello-vue 2. 安装依赖,我们需要安装 vue-router、element-ui、sass-loader 和 node-sass 四个插件 ?
# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装依赖
npm install
# 安装 SASS 加载器 安装两个低版本,高版本错误多
cnpm install sass-loader@7.3.1 node-sass@4.14.1 --save-dev
# 启动测试
npm run dev

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(formName) {
// 为表单绑定验证功能
this.$refs[formName].validate((valid) => {
if (valid) {
// 使用 vue-router 路由到指定页面,该方式称之为编程式导航
this.$router.push("/main");
} else {
this.dialogVisible = true;
return 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>
index.js 配置路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from "../view/Main";
import Login from "../view/Login";
Vue.use(VueRouter);
export default new VueRouter({
routes:[
{
path: '/main',
component: Main
},
{
path: '/login',
component: Login
}
]
});
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(router);
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App) //ElementUI
})
App.vue
<template>
<div id="app">
<h1>hello</h1>
<router-link to="/login">登录</router-link>
<router-link to="/main">首页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
使用谷歌浏览器,火狐会报错
路由嵌套
因为通过组件的动态拔插,可以很轻松做到部分页面的更新
view下建user目录下UserList.vue
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "UserList"
}
</script>
<style scoped>
</style>
view下建user目录下UserProfile.vue
<template>
<h1>用户信息</h1>
</template>
<script>
export default {
name: "Profile"
}
</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">
<!--插入的地方-->
<router-link to="/user/userProfile">个人信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">
<!--插入的地方-->
<router-link to="/user/userList">用户列表</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 scoped lang="scss">
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
路由嵌套 children
import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from "../view/Main";
import Login from "../view/Login";
import UserList from "../view/user/UserList";
import UserProfile from "../view/user/UserProfile";
Vue.use(VueRouter);
export default new VueRouter({
routes:[
{
path: '/main',
component: Main,
children:[
{
path: '/user/userList',
component: UserList
},{
path: '/user/userProfile',
component: UserProfile
}
]
},
{
path: '/login',
component: Login
}
]
});
参数传递
这里演示如果请求带有参数该怎么传递 demo ?用的还是上述例子的代码 修改一些代码 这里不放重复的代码了
第一种取值方式
1、 修改路由配置, 主要是router下的index.js中的 path 属性中增加了 :id 这样的占位符
{
path: '/user/userProfile/:id',
name: 'UserProfile',
component: UserProfile,
}
2、传递参数 ?此时我们在Main.vue中的route-link位置处 to 改为了 :to,是为了将这一属性当成对象使用,注意 router-link 中的 name 属性名称 一定要和 路由中的 name 属性名称 匹配,因为这样 Vue 才能找到对应的路由路径;
<router-link :to="{name:'UserProfile', params: {id: 1}}">个人信息</router-link>
3.在要展示的组件Profile.vue中接收参数 使用 {{$route.params.id}}来接收
<template>
<div>
<h1>用户信息</h1>
{{$route.params.id}}
</div>
</template>
第二种方式
添加可传参属性为true
{
path: '/user/userProfile/:id',
name: 'UserProfile',
component: UserProfile,
props: true
}
<router-link :to="{name:'UserProfile', params: {id: 1}}">个人信息</router-link>
<template>
<div>
<h1>用户信息</h1>
<!-- {{$route.params.id}}-->
{{id}}
</div>
</template>
<script>
export default {
props: ['id'],
name: "Profile"
}
</script>
<style scoped>
</style>
?重定向
{
path: '/main',
name: 'Main',
component: Main
},
{
path: '/goHome',
redirect: '/main'
}
说明:这里定义了两个路径,一个是 /main ,一个是 /goHome,其中 /goHome 重定向到了 /main 路径,由此可以看出重定向不需要定义组件;
?使用的话,只需要在Main.vue设置对应路径即可;
<el-menu-item index="1-3">
<router-link to="/goHome">回到首页</router-link>
</el-menu-item>
404和路由模式
路由模式
- hash:路径带 # 符号,如 http://localhost/#/login
- history:路径不带 # 符号,如 http://localhost/login
默认是hash,将index.js中加入mode:‘history’,更改成history模式
export default new VueRouter({
mode: 'history', //路径不带#
routes:[
]
});
404
NotFound.vue
<template>
<h1>404,页面未找到</h1>
</template>
<script>
export default {
name: "NotFound"
}
</script>
<style scoped>
</style>
{
path: '*',
component: NotFound
}
路由配置
路由钩子与异步请求
路由钩子
beforeRouteEnter:在进入路由前执行 beforeRouteLeave:在离开路由前执行
在UserList.vue
<script>
export default {
name: "UserList",
// 类似管理器
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 是组件实例 ?
在钩子函数中使用异步请求
安装Axios
cnpm install axios -s
cnpm install --save vue-axios
在main.js中导入
import VueAxios from 'vue-axios'
import axios from 'axios'
Vue.use(VueAxios,axios)
在UserList.vue中加入
<template>
<h1>用户列表</h1>
</template>
<script>
export default {
name: "UserList",
// 类似管理器
beforeRouteEnter: (to, from, next) => {
console.log("进入路由前");
next(vm => {
vm.getDate();
});
},
beforeRouteLeave: (to, from, next) => {
console.log("离开列表页面");
next();
},
methods:{
getDate: function () {
this.axios({
method: "get",
url: "http://localhost:8080/static/mock/date.json"
}).then(function (response) {
console.log(response);
})
}
}
}
</script>
<style scoped>
</style>
date.json
{
"name":"狂神说java",
"url": "http://baidu.com",
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
}
}
这样前端就可以接受json数据
完结撒花!!!! 后面的代码借鉴https://blog.csdn.net/okForrest27/article/details/106849246/
|