复习
- v-model 表单控件的绑定
- axios 发送http请求框架
- get axios.get(‘url’,{params:{k:v,k2:v2}}).then(response=>{ this.xxxx指向vue }).catch(error=>{…})
- post axios.post(‘url’,{k:v,k2:v2}).then(response=>{ this.xxxx指向vue }).catch(error=>{…}) 注意后端需要用@RequestBody接收
- 跨域问题 @CrossOrigin(“*”)
- 生命周期
- beforeCreate / created 初始化
- beforeMount / mounted 挂载
- beforeUpdate / updated 更新
- beforeDestroy / destroyed 销毁
- 计算属性 计算
- computed
- 过滤器 : 格式化 转换
- filters
- 事件修饰符跟按键修饰符
- 事件冒泡:嵌套标签,触发了内层标签的事件,也会触发外层标签的事件;两种处理模式,
- 冒泡 bubble: 先触发内层标签的事件,再触发外层标签的事件
- 捕获 capture:先触发外层标签的事件,再触发内层标签的事件
- 事件修饰符:行为控制
.stop
阻止事件传播.capture
使用捕获模式….prevent
阻止默认行为 - 按键修饰符:
.enter
.ctrl
.esc
- 事件冒泡:嵌套标签,触发了内层标签的事件,也会触发外层标签的事件;两种处理模式,
- 组件化编程
- 封装自定义组件/标签
- Vue.component(‘组件名’,{ }) 组件就是一个vue实例
- template 组件模板
- props 属性: 外部传入数据
- 父子组件传值
- 父->子 props
- 子->父 自定义事件 组件 this.$emit(“事件名”,事件对象) 外部 监听自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="newTodo" @keyup.enter='addTodo'>
<div>
共有{{total}}目标,已完成{{finished}}目标,还有{{unfinished}}条未完成
</div>
<div>
<input type="radio" v-model="show" value="showAll">所有目标
<input type="radio" v-model="show" value="showFinished">已完成目标
<input type="radio" v-model="show" value="showUnfinished">未完成
</div>
<ul>
<!-- (2)在组件外部监听自定义事件del,交给处理函数 -->
<todo-item v-for='t in showTodos' @del='handleDelete' :todo="t" :key='t.text'></todo-item>
</ul>
</div>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
//全局注册一个组件
Vue.component('todo-item',{
template:`<li style="list-style:none">
<input type="checkbox" name="" v-model="todo.state" id="">
<span contenteditable @keydown.esc='handleCancel' @focus="save" @blur='handleChange' >{{todo.text}}</span>
<span style='color:red;cursor:pointer' @click='del(todo)'>x</span>
</li>`,//html的内容
props:['todo'],//属性,
data:function(){
return {
prev:this.todo.text
}
},
methods:{
del(todo){
this.$emit("del",todo);//(1)在组件内触发一个自定义的事件,名为del,事件对象(事件内容)todo
},
handleChange(e){
console.log("changing:"+this.prev +" canceled:"+this.canceled)
this.todo.text=e.target.innerText;
},
handleCancel(e){
console.log("cancel:"+this.prev)
this.todo.text=this.prev;
e.target.innerText=this.prev;
e.target.blur();
},
save(){
console.log("saving:"+this.todo.text)
this.prev=this.todo.text
}
},
mounted(){
}
});
let app = new Vue({
el: "#app",
data:{
newTodo:"",
show:"showAll",
todos:[{text:"买锅",state:false},{text:"买刀",state:true},{state:false,text:"买把铁丝"}]
},
computed:{
total(){
return this.todos.length;
},
finished(){
return this.todos.filter(t=> t.state).length;
},
unfinished(){
return this.total-this.finished;
},
showTodos(){
switch(this.show){
case "showAll": return this.todos;
case "showFinished": return this.todos.filter(t=>t.state);
case "showUnfinished": return this.todos.filter(t=>!t.state);
}
return this.todos;
}
},
methods:{
handleDelete(todo){
console.log("外部")
console.log(todo);
this.todos.splice(this.todos.indexOf(todo),1);
},
addTodo(){
let todo = {text:this.newTodo,state:false};
this.todos.push(todo)
this.newTodo="";
}
}
});
</script>
</body>
</html>
一个组件对外提供了哪些接口?
- props属性
- 自定义事件
- slot插槽
插槽 slot
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue入门案例</title>
</head>
<body>
<!-- 视图 -->
<div id="container">
<submit-button>
<a href="">
<img src="http://woniuxy.com/page/img/logo-500px.png" >
</a>
</submit-button>
<base-layout>
<template v-slot:header>
一个菜单
</template>
<h2>好消息,好消息!</h2>
<template v-slot:footer>
版权所有© 麦子科技
</template>
</base-layout>
</div>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
Vue.component('submit-button',{
template:`
<button @click='handleSubmit'>
<slot>提交</slot>
</button>
`,
methods:{
handleSubmit(){
alert('提交啦');
}
}
});
Vue.component("base-layout",{
template:`
<div>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
`
})
//创建VUE对象
//{}表示构造器参数
let app = new Vue({//ViewModel
el:"#container", //挂载点,与页面的某个dom节点关联
data:{ //数据 Model
},
methods:{
}
});
</script>
</body>
</html>
ElementUI的使用
基本案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 引入样式 -->
<link
rel="stylesheet"
href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
/>
<title>Document</title>
</head>
<body>
<div id="app">
<el-button @click="visible = true">Button</el-button>
<el-dialog :visible.sync="visible" title="Hello world">
<p>Try Element</p>
</el-dialog>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
let app = new Vue({
el:'#app',
data:{
visible:false
}
});
</script>
</body>
</html>
布局
通过基础的 24 分栏,迅速简便地创建布局。通过el-row和el-col布局,总共24分栏,span表示占用的栏数,offset表示偏移量
<el-row>
<el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
</el-row>
<el-row>
<el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="12"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
<el-row>
<el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="8"><div class="grid-content bg-purple-light"></div></el-col>
<el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
</el-row>
Form
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 引入样式 -->
<link
rel="stylesheet"
href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
/>
<title>Document</title>
</head>
<body>
<div id="app">
<el-container>
<el-header>
<el-menu default-active="1" class="el-menu-demo" mode="horizontal">
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
</el-menu>
</el-header>
<el-main>
<el-row>
<el-col :span='12' :offset="6">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" format='yyyy-MM-dd' value-format="yyyy-MM-dd" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker format='HH:mm:ss' value-format='HH:mm:ss' placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-upload
class="upload-demo"
action="http://localhost:8080/upload"
name='file'
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-success="handleSuccess"
:on-exceed="handleExceed"
:file-list="form.fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</el-main>
<el-container>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
let app = new Vue({
el:'#app',
data:{
form:{
name: 'defaultName',
region: '大中国',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
},
},
methods:{
onSubmit(){
console.log(this.form);
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`);
},
handleSuccess(response, file, fileList){
console.log(file);
let fileObj = {name:file.name,url:file.response.data};
this.form.fileList.push(fileObj)
}
}
});
</script>
</body>
</html>
upload使用注意事项:
- name指定上传时的文件名
- action指定提交的目标地址
- 需要在成功回调on-success时手工添加到fileList中
作业:
- 前后端增查,按条件分页查询+查看详情+新增讲师