常用事件
input事件
<!-- 复选框 动态绑定的数据不能用v-model,因为props的数据只读不可写 -->
<!-- change 事件是用来监听**复选框的状态**-->
<input type="checkbox"
class="custom-control-input"
id="cb1"
:checked="state"
@change="stateChange"//监听复选框的状态
/>
methods:{
stateChange(e){
//监听到的复选框状态,只要复选框状态变化就会调用这个处理函数
const newState = e.target.checkd
//触发自定义事件
this.$emit('state-change',{id:this.id,value:newState})
}
}
router
1.安装路由,在src目录下,新建一个文件夹:router,专门存放路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Content from "../components/Content";
import Main from "../components/Main"
//安装路由
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes:[
{
//路由路径
path:'/content',
name:'content',
//跳转的组件
component:Content
},{
//路由路径
path:'/main',
name:'main',
//跳转的组件
component:Main
}
]
});
2.在main.js 配置路由
import Vue from 'vue'
import App from './App.vue'
import router from './router'//自动扫描里边的路由配置
Vue.config.productionTip = false
new Vue({
render: h => h(App),//创建一个vue对象,然后挂载到制定的页面节点。render是一个方法,自带一个形参createElement,这个参数也是一个方法,是用来创建vue 节点的,也就是html模板的,然后渲染(render)到指定的节点上
router
}).$mount('#app')
// new Vue({
// el:'#app',
// //配置路由
// router,
// components:{App},
// template:'<App/>'
// });
3.在App.vue中使用路由
<template>
<!-- <div id="app">-->
<!-- <img alt="Vue logo" src="./assets/logo.png">-->
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/>-->
<!-- </div>-->
<div id="app">
<h1>chen_bin</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>
;利用模板字符串拼接字符串非常的舒服 -> console.log(`用户名是:"${this.username}"`);
推荐大家安装的 VScode 中的 Vue 插件
- Vue 3 Snippets https://marketplace.visualstudio.com/items?itemName=hollowtree.vue-snippets
- Vetur https://marketplace.visualstudio.com/items?itemName=octref.vetur
什么是 vue
- 构建用户界面
- 用 vue 往 html 页面中填充数据,非常的方便
- 框架
- 框架是一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务功能!
- 要学习 vue,就是在学习 vue 框架中规定的用法!
- vue 的指令、组件(是对 UI 结构的复用)、路由、Vuex、vue 组件库
- 只有把上面老师罗列的内容掌握以后,才有开发 vue 项目的能力!
vue 的两个特性
-
数据驱动视图:
-
数据的变化会驱动视图自动更新
-
好处:程序员只管把数据维护好,那么页面结构会被 vue 自动渲染出来!
-
双向数据绑定:
在网页中,form 表单负责采集数据,Ajax 负责提交数据。
- js 数据的变化,会被自动渲染到页面上
- 页面上表单采集的数据发生变化的时候,会被 vue 自动获取到,并更新到 js 数据中
注意:数据驱动视图和双向数据绑定的底层原理是 MVVM(Mode 数据源、View 视图、ViewModel 就是 vue 的实例)
vue 指令
1. 内容渲染指令
v-text
指令的缺点:会覆盖元素内部原有的内容!{{ }}
插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容!v-html
指令的作用:可以把带有标签的字符串,渲染成真正的 HTML 内容!
2. 属性绑定指令
注意:插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中!
-
在 vue 中,可以使用
v-bind:
指令,为元素的属性动态绑定值; -
简写是英文的
:
-
在使用 v-bind 属性绑定期间,如果绑定内容需要进行动态拼接,则字符串的外面应该包裹单引号,例如:
xml
<div :title="'box' + index">这是一个 div</div>
3. 事件绑定
-
v-on:
简写是@
-
语法格式为:
```xml
[HTML_REMOVED][HTML_REMOVED]
methods: {
add() {
// 如果在方法中要修改 data 中的数据,可以通过 this 访问到
this.count += 1
}
}
```
$event
的应用场景:如果默认的事件对象 e 被覆盖了,则可以手动传递一个 $event。例如:
```xml
[HTML_REMOVED][HTML_REMOVED]
methods: {
add(n, e) {
// 如果在方法中要修改 data 中的数据,可以通过 this 访问到
this.count += 1
}
}
```
-
事件修饰符:
-
.prevent
xml <a @click.prevent="xxx">链接</a>
-
.stop
xml <button @click.stop="xxx">按钮</button>
4. v-model 指令
- input 输入框
- type=”radio”
- type=”checkbox”
- type=”xxxx”
- textarea
- select
5. 条件渲染指令
v-show
的原理是:动态为元素添加或移除display: none
样式,来实现元素的显示和隐藏- 如果要频繁的切换元素的显示状态,用 v-show 性能会更好
v-if
的原理是:每次动态创建或移除元素,实现元素的显示和隐藏- 如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if 性能更好
在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!
v-if 指令在使用的时候,有两种方式:
- 直接给定一个布尔值 true 或 false
xml
<p v-if="true">被 v-if 控制的元素</p>
- 给 v-if 提供一个判断条件,根据判断的结果是 true 或 false,来控制元素的显示和隐藏
xml
<p v-if="type === 'A'">良好</p>
function(){
里边用this就是指的是function的this而不是外边的vm实例,需要改为箭头函数
}
() =>{
这里用this. 就可以调用外边的vm的实例化的数据
}
arr数组:一行代码解决 购物车计算价格
const arr = [
{id:1,status:true,price:10,count:100},
{id:2,status:false,price:20,count:200},
{id:3,status:true,price:30,count:300},
];
//arr.filter(item => item.status).reduce((累加项,循环项) =>{return ...},初始值)
//return 的累加项为下一个循环的初始值
const res = arr.filter(item => item.status).reduce((amt,item) => amt += item.price * item.count,0);
//可以去花括号和箭头函数后边的return字母
arr.some 实例
//接收子组件传递过来的数据
//e的格式 {id:, value:}
getNewState(e){
this.list.some(item =>{
if(item.id === e.id){
item.goods_state = e.value;
//终止循环
return true;
}
})
}
arr.every 实例
//计算属性
computed: {
//动态计算全选的状态
fullState(){
// this.list.every(item => item.goods_state === true)
this.list.every(item => item.goods_state)
}
}
.foreach 全部遍历,.some 可以中断遍历
//接收Footer子组件传递过来的群选按钮状态
getFullState(val){
this.list.forEach(item => item.goods_state = val)
}
<el-dialog title="意向用户" center :width="dialogWidth='800px'" :visible.sync="insDialogTableVisible">
<el-table :data="insGridData.sdIntentions">
<el-table-column property="username" label="用户名称" width="200" show-overflow-tooltip></el-table-column>
<el-table-column property="code" label="用户身份证" width="200" show-overflow-tooltip></el-table-column>
<el-table-column property="mobile" label="手机号" width="200" show-overflow-tooltip></el-table-column>
<el-table-column property="time" label="申请时间" show-overflow-tooltip></el-table-column>
</el-table>
</el-dialog>
axios
methods:{
//封装请求列表数据的方法
async initCartList(){
//调用 axios 的get方法,请求列表数据
//解构赋值
const { data : res } = await axios.get('https://www.escook.cn/api/cart')
console.log(res);
}
}
main.js 页面
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
Vue.config.productionTip = false
// 全局配置 axios 的请求根路径
axios.defaults.baseURL = 'http://www.liulongbin.top:3006'
// 把axios 挂载到Vue.prototype 上,供每个.vue组件的实例直接使用
Vue.prototype.$http = axios
// 今后,在每个 .vue组件中发送请求,直接调用 this.$http.xxx
// 但是,把axios 挂载到Vie原型上,有一个缺点:不利于API接口的复用!!!
new Vue({
render: h => h(App)
}).$mount('#app')
DatetimePicker 和弹出层
<van-field
readonly
clickable
name="datetimePicker"
v-model="timeValue"
label="时间选择"
@click="showPickerTime = true"
/>
<van-popup v-model="showPickerTime" position="bottom">
<van-datetime-picker
v-model="currentDate"
type="date"
@change="changeFn()"
@confirm="confirmFn()"
@cancel="cancelFn()"
/>
</van-popup>
methods:{
changeFn() { // 值变化是触发
this.changeDate = this.currentDate // Tue Sep 08 2020 00:00:00 GMT+0800 (中国标准时间)
},
confirmFn() { // 确定按钮
this.timeValue = this.timeFormat(this.currentDate);
this.showPickerTime = false;
},
cancelFn(){
this.showPickerTime = true;
},
timeFormat(time) { // 时间格式化 2019-09-08
let year = time.getFullYear();
let month = time.getMonth() + 1;
let day = time.getDate();
return year + '年' + month + '月' + day + '日'
}
}
location.href
location.hash
created() {
//只要当前的App组件一被创建,就立即监听 window 对象的 onhashchange 事件
window.onhashchange = () =>{ // 不能用function,因为箭头函数的this可以和外部的this保持一致
console.log(‘监听到的hash 变化’,location.hash)
switch (location.hash) {
case ‘#/home’:
this.comName = ‘Home’
break
case ‘#/movie’:
this.comName = ‘Movie’
break
case ‘#/about’:
this.comName = ‘About’
break
}
}
},
[HTML_REMOVED]
[HTML_REMOVED]
<router-link to="/home">首页</router-link>
[HTML_REMOVED]
[HTML_REMOVED]
[HTML_REMOVED]
/movie/2?name=zs&age=20 是fullPath的值
/movie/2 是path的值
[HTML_REMOVED]电影1[HTML_REMOVED]
[HTML_REMOVED]电影2[HTML_REMOVED]
[HTML_REMOVED]电影3[HTML_REMOVED]
[HTML_REMOVED]关于[HTML_REMOVED]
[HTML_REMOVED][HTML_REMOVED]
---
9)路由传参
params参数:路由需要占位,程序就崩了,属于URL当中一部分
query参数:路由不需要占位,写法类似于ajax当中query参数
路由传递参数先关面试题
1:路由传递参数(对象写法)path是否可以结合params参数一起使用?
不可以:不能这样书写,程序会崩掉
2:如何指定params参数可传可不传?
3:params参数可以传递也可以不传递,但是如果传递是空串,如何解决?
4:如果指定name与params配置, 但params中数据是一个”“, 无法跳转,路径会出问题
5: 路由组件能不能传递props数据?
路由传参,参数的写法:
params参数:属于路径当中的一部分,需要注意,在配置路由的时候需要占位
query参数:不属于路径中的一部分,类似于ajax中的queryString, /home?k=v&kv=,不需要占位
// router.js
{
path:”/search/:keyword”,
component:Search,
meta:{show:true}
},
// search index.vue
[HTML_REMOVED]
[HTML_REMOVED]
[HTML_REMOVED]params参数:{{ $route.params.keyword }}</h1>
<h1>query参数:{{ $route.query.k }}[HTML_REMOVED]
[HTML_REMOVED]
[HTML_REMOVED]
// 非路由组件Header
export default {
name: “index”,
data () {
return {
keyword: ‘’
}
},
methods: {
// 搜索按钮的回调函数: 需要向search 路由进行跳转
goSearch () {
// 路由传参
// 第一种:字符串形式
// this.$router.push(‘/search/’+this.keyword+”?k=”+this.keyword.toUpperCase())
// 第二种:模板字符串
// this.$router.push(/search/${this.keyword}?k=${this.keyword.toUpperCase()}
)
// 第三种:对象
this.$router.push({name:”search”,params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
}
}
}
[HTML_REMOVED]