计算属性(computed):处理data数据,与data用处一致
computed与methods不同点 | computed | methods |
---|---|---|
vue对象中代码写法 | 一致 | 一致 |
HTML代码写法 | 不用写小括号 | 用写小括号 |
代码执行次数 | 一次 | 调用几次执行几次 |
属性 | get属性 | set方法+get属性 |
//HTML
和data一样
//vue
computed:{
属性名 : function(){
return 计算后的数值
}
}
过滤器(filters):拼接data数据
//HTML
{{ data数据/computed数据 | 过滤器属性名}}
//vue
filters:{
属性名 : function(){
return 计算后的数值
}
}
父子组件:传递数据 / 操作对象
父组件template的意思:父组件罗列子组件代码时的站位代码
(一)1.父组件传递子组件 v-bind
(1)基础
父组件视角:
- 将父组件data值传递给父组件template
- 在父组件template内关联父组件与子组件数据关系,插入属性v-bind
- 在子组件内设定props接收父组件data值,
- 直接将props属性值通过[基本用法]显示到子组件页面
//父组件vue
<template>
<子组件 v-bind:"子组件属性值" = "父组件属性值"></子组件>
<div></div>
</template>
<script>
import 子组件 from "子组件的位置"
export default{
name:"App11",
data(){
return{}
},
components:{
子组件 //注册子组件
}
}
</script>
//子组件vue
//v-bind后面加的变量不支持驼峰命名法,如果props内的变量值是驼峰命名,在父组件的v-bind将大写字母用 【-】 替换。
<template>
<div></div>
</template>
<script>
import 子组件 from "子组件的位置"
export default{
data(){
return{}
},
props:["子组件属性值1","子组件属性值2"]
或者
props:{ "子组件属性值1":{type:Array,default:(){return{"默认值"}},require:true} } //没传入时设置默认值 + 设置必传项
}
</script>
(一)2.父组件传递router-view(前端路由,改变url传递数据)
(1)JS文件夹:组件文件夹(页面)vue,跳转url
id参数存储位置:属于path路径里面的params
多个参数存储位置:属于path路径里面的query
//params
//父组件
<router-link v-bind:to "'跳转url' + 父组件data属性名">a标签<router-link> //更换url
<router-view></router-view> //更换的子组件站位
data(){return{"父组件data属性名":}}
//子组件直接用(子组件在data中需要加this,this.$route.params.父组件data属性名)
{{$route.params.父组件data属性名}}
//query
//父组件
<router-link v-bind:to={path:"路径",query:{key:value,key:value}}><router-link>
//子组件直接用(子组件在data中需要加this,this.$route.params.父组件data属性名)
{{$route.query.key值}}
<div @click=""></div> //手动实现router-link
methods{ "":{
this.$router.push(path: " "+ 参数名ID)//可以浏览器返回
this.$router.relpace(path: " ",query;{key:value})//不可以浏览器返回
}}
(2)配置文件:router文件夹,创建小组件与url的映射关系
(步骤4)const routes = [
{path: "/home/:userId",component: "组件名称"}, //params设置参数
{path: "/home",component: "组件名称"} //query参数不需要配置文件
]
(二)1.子组件传递父组件 v-on
子组件视角:
- 子组件文件内发生事件后,在事件内发射到父组件template,可携带参数
- 父组件template内中设置子组件方法和父组件方法的关系,用v-on链接
- 父组件函数内接收到子组件参数
//子组件vue
<template>
<div v-on 事件名称></div>
</template>
<script>
import 子组件 from "子组件的位置"
export default{
data(){
return{}
},
methods(行参){
子事件名称(){this.$emit("事件名字",参数)} //发射参数到父组件template
}
</script>
//父组件vue
<template>
<子组件 v-on:"父组件事件" = "子组件事件"></子组件>
<div></div>
</template>
<script>
import 子组件 from "子组件的位置"
export default{
name:"App11",
data(){
return{}
},
components:{
子组件 //注册子组件
}
methods(行参){
父事件名称(行参){接收到子组件参数
}
}
</script>
(二)2.子组件数据传递至父组件(插槽方式)
//子组件属性
data(){return{ "子组件数据名" }}
//子组件html插槽挖空处
<slot : "随意起名" = "子组件数据名"> html代码 </slot>
//父组件template注册时正常
//父组件html填空处
<lzy>
<template slot-scope="slot" >
自定义HTML代码
传递进来的子组件数据名:slot.随意起名
</template>
</ lzy>
(三)input双向绑定(方法1)(方法2后面补)
将v-model拆成v-bind 和v-on 做双向绑定
//父传子
(1)设置父组件属性值
(2)用v-bind设置父组件template, 子组件属性值 = 父组件属性值
(3)子组件props得到从父组件传递进来的 「子组件属性值」
(4)子组件data中,包装props内的「子组件属性值」,令 最后显示值 = this.子组件属性值
//子传父
(1)子组件监听input发生改变事件v-input
(2)子组件methods中将改变的值赋值给参数 this.参数 = this.event.target.value
(3)子组件methods中发射 this.$emit("事件名字",参数)
(4)父组件template中设置 父组件方法 = 子组件方法
(5)父组methods中 获取参数this.data 值=this.value
(四)操作父组件时,需要影响子组件的方法/属性
//(1)(不常用)父组件的methods内用点方法直接操作子组件的属性/方法
methods(行参){
this.$children[0].子组件方法() //调用方法
consolu.log(this.$children[0].子组件属性) //打印属性等
}
//(2)(常用)
//父组件template,确认唯一组件属性
<lzy ref="aaa"></lzy>
//父组件methods
methods(行参){
this.$refs.aaa.子组件方法() //调用方法
consolu.log(this.$refs.aaa.子组件属性) //打印属性等
}
(五)操作子组件时,需要影响父组件的方法/属性(不建议用)
//(1)子组件操作父组件 子组件methods中
methods(行参){
this.$parent.父组件方法() //调用方法
consolu.log(this.$parent.父组件属性) //打印属性等
}
//(2)子组件操作根组件(main.js)
methods(行参){
this.$root.父组件方法() //调用方法
consolu.log(this.$root.父组件属性) //打印属性等
}
状态管理模式工具(vueX):集中式存储管理
任意组件都可以获取vueX的属性,修改vueX的属性,调用vueX的方法
监听同步操作插件:google浏览器的插件 devtools,安装后在f12 的最后出现vue
vueX传递给组件:存储属性,计算存储属性;组件传递给vueX:同步方法,异步方法
1.创建store文件夹
2.下载vuex插件:snpm install vuex --save
2.创建index.js文件(模块化引用3/4/5)
3.创建mutations.js文件 //模块化思想抽离,此处不抽离了,分开写怕记乱,import和default
4.创建actions文件
5.创建modules文件夹-modules文件
//index.js文件
import vue from "vue" //引用vue
import vuex from "vuex" //引用vuex
Vue.use(vuex)//安装插件
const store = new Vuex.store({ //创建对象
state:{key:value} //存储属性
getters:{ 计算属性名(state,getters){return getters.其他属性名.其他操作}}//计算属性,可以在组件处传参,可以调用其他计算属性的结果
mutations:{ 方法名(state,payload){state.属性名 ++,payload.参数名}}//定义修改【存储属性的方法】,payload负载参数
action:{ 方法名(context,payload){context.commit("mutations方法名","参数")//异步promise执行完成后用这种方式调用mutations}//1.先执行异步操作,在从异步操作中调用同步操作
action:{ 方法名(context,payload){ return new Promise((resolve,reject)=>{
//写异步函数,异步处理完成后调用mutations
context.commit("mutations方法名",参数),resolve(success传递给vue组件的内容)}}}
modules :{a:变量名a,b:变量名b} 变量名a:{"state,getters,mutations,actions"}//modules里面还有state,getters,mutations,actions,分层,此处对getters,actions定义有变化用的时候调试/硬查
export default store //导出store
//任意组件文件
//如果怕mutations方法名在组件中复制粘贴错,可以新建中转文件夹p137
{{$store.state.key}}
{{$store.state.计算属性(参数)}}
{{$store.state.a.key}}//modules中,并不是从modules拿a拿state, 而是从state拿a拿key
methods:{
this.$store.comit("mutations的方法名",参数2)//1.修改vueX的【存储属性】唯一方式2.执行异步action后调用mutations
this.$store.comit({ type:mutations的方法名,payload.参数2})//mutations的写法2
state.对象名["属性名"] = "值" //响应式原理,这种方式不会变成响应式
this.$store.dispatch("action方法名",参数) //调用action方法
this.$store.dispatch("action方法名",success传递给vue组件的内容).then(随便打印什么)//调用action方法,promise方式,异步函数成功后将success传入到then,vue组件可以弹出then关键字
}
//main.js文件
import store from " 地址 " //引用store
new vue({
el:app
store //注册store
})
请求接口(axios):支持浏览器和node.js环境,自带promise,不用写回调函数,支持拦截请求和响应,转换请求和响应数据
模拟接口网站:httpbin.org
框架不是插件,不用use
安装框架:npm install axios --save
请求方式 | 代码 |
---|---|
axios(config) | |
axios.request(config) | |
axios.get(url[, config]) | |
axios.delete(url[, config]) | |
axios.head(url[, config]) | |
axios.post(url[, data[, config]]) | |
axios.put(url[, data[, config]]) | |
axios.patch(url[, data[, config]]) |
接口文档/全局配置 | 代码 |
---|---|
请求地址 | url: ‘/user’, |
请求类型 | method: ‘get’, |
请根路径 | baseURL: ‘http://www.mt.com/api’, |
请求前的数据处理 | transformRequest:[function(data){}], |
请求后的数据处理 | transformResponse: [function(data){}], |
自定义的请求头 | headers:{‘x-Requested-With’:‘XMLHttpRequest’}, |
!URL查询对象 | params:{ id: 12 },get参数 |
!request body | data: { key: ‘aa’},post存放参数 |
查询对象序列化函数 | paramsSerializer: function(params){ } |
超时设置:单位s | timeout: 1000, |
跨域是否带Token | withCredentials: false, |
自定义请求处理 | adapter: function(resolve, reject, config){}, |
身份验证信息 | auth: { uname: ‘’, pwd: ‘12’}, |
响应的数据格式 json / blob /document /arraybuffer / text / stream | responseType: ‘json’, |
(1)创建network网络文件夹
(2)创建request.js文件
import axios from "地址"
//导出模块化封装
export function lzy1(config) {
//配置
const lzy = axios.create({
url: 相同的接口参数
})
//拦截器
//拦截全局
axios.interceptors.request
//拦截请求
lzy.interceptors.request.use(config => { 成功 return config }, err => { 失败 })
//拦截响应
lzy.interceptors.response.use(res => { 成功 return res }, err => { 失败 })
//请求
return lzy(config) //在此处真正发送请求,调用上方的【配置】发送请求
}
//任意需要发送请求的位置
import lzy1 from "地址"
lzy1({ url: 不同的接口参数 }).then(res => { }).catch(err => { })
//发送并发请求,一个组件同时发送两个请求,等到两个请求都完成后,处理success
lzy1.all([axios(), axios()]).then(results => { results[0] })
lzy1.all([axios(), axios()]).then(axios.spread((res1, res2) => { }))