【Vue】基础系列(四四)计算属性-监听器-过滤器-混入-插件-网络请求-全局组件-生命周期

发布于:2023-01-04 ⋅ 阅读:(370) ⋅ 点赞:(0)

🌕写在前面
🍊博客主页勇敢link牛牛
🎉欢迎关注:🔎点赞👍收藏⭐️留言📝
🌟本文由 勇敢link牛牛 原创,CSDN首发!
📆首发时间:🌹2022年8月31日🌹
🆕最新更新时间:🎄2022年8月31日🎄
✉️愿你熬过万丈孤独,藏下星辰大海!
📠参考书籍:📚《Vue2》
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢感谢感谢!


🍗计算属性

  1. vue使用,不推荐在模板中来写过多的逻辑
  2. 如果对于一个结果,进行计算,可以使用vue提供计算属性来完成,而且计算属性它还具有缓存功能。(只要不发生变化,他就不会再次执行)
  3. 如果你的依赖项,没有发生改变,则它会在再一次调用时,会读取缓存中的数据
  4. 只有标准的写法时,它才可以对于计算属性进行赋值操作
  5. 计算[属性],也就是说,可以直接this.属性赋值,取值
  6. 赋值只会触发标准方式中的set方法,然后你可以得到它,完成一些别的工作
  7. get操作必须要有返回值。
简写:
简写只是实现的了get
computed: {
	total() {
		console.log('computed -- total')
		// 在计算属性中,调用了 n1和n2,则n1和n2就是它的依赖项,如果这两个依赖项,有一个发生改变,则它会重新计算,如果两个都没有发生改变,则第2之后调用,读取缓存中的数据
		return this.n1 + this.n2
	}
}
标准:
computed: {    
    total: {
        get() {
            return this.n1 + this.n2
        },
        set(newVal) {
            if (newVal > 10) {
                this.msg = '值有点的大'
            }
        }
    }
}
//this.total = 101,触发计算属性

🍚监听器

监听器,它用来监听data配置中的数据的变化,一但有变化,就会自动触发,默认情况,初始化不触发
在监听器中是可以得到this对象的
监听器它的依赖项,只有一个,一对一
监听器中可以写异步

在这里插入代码片
watch: {
	immediate: true // 初始时,执行1次 --- 一般情况下,不启用  只有在标准写法下面,才有此配置
	deep: true,// 深度监听
	
	username: {	方法名或属性名 就是你要观察的data中的属性名称
		handler(newValue, oldValue) {// 变化后的值,变化前的值
		console.log(newValue, oldValue);
		if (newValue.length >= 3) this.errorUsername = '账号过长'
		else this.errorUsername = ''
	}
}
或者:
监听对象:监听对象变化,它的前后值是一样的,无法区分
'user.id'(newValue, oldValue){
	console.log(newValue, oldValue);
}

🦪过滤器

过滤器的作用就是为了对于界面中显示的数据进行处理操作
全局过滤器

  • 参数1:过滤器的名称,可以随意起名
  • 参数2:回调函数,回调函数中的参数最后要有一个,最1位参数,永远指向为要过滤的数据
Vue.filter('phoneCrypt', value => {
	return value.slice(0, 3) + '~~~~' + value.slice(7)
}) 
Vue.filter('phoneCrypt', (value, salt = '****') => {
	return value.slice(0, 3) + salt + value.slice(7)
})

局部过滤器

<h3>{{ phone | phoneCrypt('!!!!') }}</h3>
filters: {
     phoneCrypt(value, salt = '****') {
         return value.slice(0, 3) + salt + value.slice(7)
     }
 },

混入

用于公共代码复用

  • 混入的配置,它是可以把几乎所有new Vue配置中的所有配置都能混入,但是el配置它不可以混入

  • data配置,在混入方式中,只能写函数的方式,且函数一定要返回一个对象,混入可能被调用多次,如果直接是对象的话,就会有污染

  • data混入的优先级 组件 > 局部 > 全局 => 只会调用一个

  • 混入的生命周期方法,执行顺序 全局 -> 局部 --> 组件 依次执行

全局混入:

Vue.mixin({
	data() {
	    return {
	        name: '张三 -- 全局'
	    }
	},
	computed: {
	    showName() {
	        return 'abc -- 全局'
	    }
	},
	methods: {
	    run() {
	        return 'run -- 全局'
	    }
	},
	created() {
	    console.log('created -- 全局');
	}
})

局部混入
对象语法:
需要在组件里面配置项: mixins: [mix]

 const mix = {
     data() {
         return {
             name: '张三 -- 局部'
         }
     },
     computed: {
         showName() {
             return 'abc -- 局部'
         }
     },
     methods: {
         run() {
             return 'run -- 局部'
         }
     },
     created() {
         console.log('created -- 局部');
     }
 }

 const vm = new Vue({
     el: '#app',
     data: {
         // name: '张三 -- 实例'
     },
     mixins: [mix],//混入体
     methods: {
         run() {
             return 'run -- 实例'
         }
     },
     created() {
         console.log('created -- 实例');
     }
 })

给Vue原型上添加方法混入到methods:
添加成员属性

<body>
    <div id="app">
        <h3>{{name}}</h3>
        <hr>
        <h3>{{showName}}</h3>
        <hr>
        <div>{{run()}} --- {{ show() }}</div>
    </div>
    <script>
        // A模块
        const http = () => console.log('http');
        // Vue.prototype.$http = http
        
        const mix = {
            data() {
                return {
                    name: '张三 -- 局部'
                }
            },
            computed: {
                showName() {
                    return 'abc -- 局部'
                }
            },
            methods: {
                run() {
                    return 'run -- 局部'
                }
            },
            created() {
                this.$http = http
                this.title = '我是一个局部标题'
                console.log('created -- 局部');
            }
        }

        const vm = new Vue({
            el: '#app',
            data: {},
            mixins: [mix],
            methods: {
                show() {
                    this.$http()
                    return this.title
                }
            }
        })
    </script>

</body>

🍜插件

函数模块
它是就一个可以利用的Vue模块写法就是function
然后是否启用这个模块,并且可以传参;
函数式语法:
模块里面可以针对这个vue所有语法配置项的书写

function plugin(Vue, options) {/*插件模块*/
    console.log(options, ">>>>>>>>.");
    Vue.directive('red', el => {
        el.style.cssText = 'color:red'
    })
    Vue.mixin({
        data() {
            return {
                title: `() => console.log('run');`
            }
        },
        created() {
            this.title = options.title
            console.log('混入了');
        }
    })
    // 静态属性
    // Vue.run = () => console.log('run');
    // 添加成员属性
    Vue.prototype.run = () => console.log('run');
}

// 插入插件,传入参数
Vue.use(plugin, {
    title: 'abc'
})

const vm = new Vue({
    el: '#app',
    data: {},
    created() {
        // Vue.run()
        this.run()
    }
})

类模块

class Plugin {
    // 它是就一个模块
    static install(Vue, options) {
        console.log(options);
        Vue.directive('red', el => {
            el.style.cssText = 'color:red'
        })
        Vue.mixin({
            data() {
                return {
                    title: `() => console.log('run');`
                }
            },
            created() {
                this.title = options.title
                console.log('混入了');
            }
        })
        // 添加成员属性
        Vue.prototype.run = () => console.log('run');
    }
}

// 插入插件
Vue.use(Plugin, {
    title: 'abc'
})

对象模块

const Plugin = {
    install(Vue, options) {
        console.log(options);
        Vue.directive('red', el => {
            el.style.cssText = 'color:red'
        })
        Vue.mixin({
            data() {
                return {
                    title: `() => console.log('run');`
                }
            },
            created() {
                this.title = options.title
                console.log('混入了');
            }
        })
        // 添加成员属性
        Vue.prototype.run = () => console.log('run');
    }
}

// 插入插件
Vue.use(Plugin, {
    title: 'abc'
})

监听器:标准,简写:监听数据源的改变,深度监听
过滤器:局部,全局:界面的中的数据进行处理操作
混入:通过混入实现多继承,全局,局部
优先级 组件>局部>全局,只会调用一个

🍤生命周期:(暂8种)

🧈🍞🥪🍠🍠🥩🍗🍗🥖🍳🍳🌮🦪🦪🍜🍚🍚🥩🍠🦪🍘🍖🥖🌮🍜

	const vm = new Vue({
	el: '#app',
	data: {
	    username: ''
	},
	// 初始化阶段生命周期  -- 它只都只执行1次
	beforeCreate() {
	    console.log('beforeCreate');
	},
	created() {
	    console.log('created');
	},
	beforeMount() {
	    console.log('beforeMount');
	},
	mounted() {
	    console.log('mounted');
	    setTimeout(() => {
	        // 销毁
	        this.$destroy()
	    }, 2000);
	    this.timer = setInterval(() => {
	        console.log(111);
	    }, 1000);
	},
	// 更新阶段生命周期,它们会执行N次
	beforeUpdate() {
	    console.log('beforeUpdate');
	},
	updated() {
	    console.log('updated');
	},
	// 销毁阶段  只执行1次
	beforeDestroy() {
	    clearInterval(this.timer)
	    console.log('beforeDestroy');
	},
	destroyed() {
	    console.log('destroyed');
	}
	})

🦪网络请求axios

主要是对axios库的使用

npm i -S axios

🍔axios全局配置

第一步引入:

<script src="./js/axios.js"></script>
//设置服务器已经端口号
axios.defaults.baseURL = 'http://localhost:9000';
// 设置超时时间 ms
axios.defaults.timeout = 10000;
//设置请求头(可选)
axios.defaults.headers.token = 'aaaaa'

// 请求拦截器  回调函数中的config对象一定要return出去
axios.interceptors.request.use(config => {
	// console.log(config);
	if (config.method === 'get') {
		config.headers.token = 'abc'
	}
	return config
})

// 响应拦截器
axios.interceptors.response.use(res => {
	console.log(res);
	if (res.data.code == 0) return res.data
	alert('有错')
}, err => Promise.reject(err))


钩子函数:挂载后执行
mounted() {
	axios.get('/api/users', {
	    headers: {/*设置请求头*/
	        token: 'abc'
	    }
	}).then(ret => {
	    console.log(ret.data);/*响应回来的数据*/
	}).catch(() => console.log('有异常'))
}

🥪请求方法

mounted() {
	/*get请求*/
	axios.get('/api/users?id=1').then(ret => {
		console.log(ret.data);
	}, () => console.log('有异常'));
	
	/*post请求*/
	axios.post('/api/users', {name: '李四'/*第二个参数是上传数据的参数*/}, 
	{
     headers: {
        token: 'abc'
      }
     }).then(ret => {
       console.log(ret.data);/*响应回来的数据*/
     })
     
	/*put请求*/
	axios.put('/api/users', {
    name: '李四 -- put'/*参数*/
     }, {
       headers: {
         token: 'abc'
       }
     }).then(ret => {
       console.log(ret.data);
     }) 

     /*delete请求*/
     axios.delete('/api/users/100',null, {
      headers: {
         token: 'abc'
       }
     }).then(ret => {
       console.log(ret.data);
     }) 
}

🌮网络请求axios封装

index.html

<script src="./http.js"></script>

async mounted() {
    // this.users = await (await get('/api/users')).data
    let users = await get('/api/users')
    this.users = users.data
},
methods: {
    async add() {
        let users = await post(`/api/users`, {
            name: Date.now() + ''
        })
        this.users = users.data
    },
    async edit(id) {
        let users = await put(`/api/users/${id}`, {
            name: Date.now() + ''
        })
        this.users = users.data
    },
    async del(id) {
        let users = await del(`/api/users/${id}`)
        this.users = users.data
    }
}

http.js

axios.interceptors.response.use(
    res => res.data,
    err => Promise.reject(err)
)

axios.interceptors.request.use(
    config => {
        config.baseURL = 'http://localhost:9000'
        config.timeout = 10000
        return config
    },
    err => Promise.reject(err)
)
const get = url => axios.get(url)
const post = (url, data = {}) => axios.post(url, data)
const put = (url, data = {}) => axios.put(url, data)
const del = url => axios.delete(url)




最简单的这种。
import axios from "axios";
axios.interceptors.response.use(
    res => res.data,
    err => Promise.reject(err)
);
axios.interceptors.request.use(config =>config);

/**
 * 进行ajax网络通信。
 * @param {string} url  网络请求地址
 * @returns Promise对象
 */
export const get = url => axios.get(url);
export const post = (url,data={}) => axios.post(url,data);
export const put = (url,data={})=>axios.put(url,data);
export const del = (url) =>axios.delete(url);

网络请求🥪fetch🧈

基础的fetch

fetch('url', {
	method: 'post',
	body: JSON.stringify({ id: 1 }),
	headers:{
		'content-type':'application/json'
	}
})

三种基础用法

mounted() {
	fetch('/mock/users.json')
		.then(ret => ret.json())/*解析*/
		.then(json => this.users = json)/*收集*/
}	
async mounted() {
	let ret = await fetch('/mock/users.json')
	this.users = await ret.json()/*收集*/
}
async mounted() {
	this.users  = await (await fetch('/mock/users.json')).json
}

全局组件

自定义的标签,在vue项目中,称为组件
全局组件 一但声明完成,就可以在所有的组件中直接使用,无需引入和注册
定义的组件,它的元素必须要有一个顶层元素进行包裹,否则报错
组件里面也可以使用组件

<mytitle></mytitle>

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Vue.component('mytitle', {
	data() {
	    return {
	        title: '我是一个标题'
	    }
	},       
	template: `<div>
			<h3 name='abc' @click="setTitle">{{title}}</h3><div>aaaa</div>
			<hr />
			<subtitle></subtitle>
			</div>`,
	methods: {
		setTitle() {
			this.title = Date.now()
		}
	}
})
Vue.component('subtitle', {
	template: `<div>
		<h3>我是一个子标题</h3>
		</div>`
})

也可以这样写:
直接生成 虚拟dom方法
在工程化中,render中可以直接写jsx,在引入一个babel可以写jsx语法(js的增强版本)
作用和template一样

render(h) {
	// console.log(h);h就是自定义的标签
	// let vnode = h('h3', null, '我是一个标签')
	let vnode = h('h3', { attrs: { name: 'abc', style: 'color:red' } }, '我是一个标签')
	return vnode
}

通过插件来使用组件:
函数式

<body>
    <!-- 第2步:挂载点 -->
    <div id="app">
        <!-- 自定义的标签,在vue项目中,称为组件 -->
        <mytitle></mytitle>
        <mytitle></mytitle>
        <mytitle></mytitle>
        <mytitle></mytitle>
    </div>

    <!-- 第3步:实例化vue -->
    <script>
    <script>
        const myTitleCmp = Vue => {
            Vue.component('mytitle', {
                data() {
                    return {
                        title: '我是一个标题'
                    }
                },
                template: `<div>
                    <h3 name='abc' @click="setTitle">{{title}}</h3><div>aaaa</div>
                    <hr />
                    <subtitle></subtitle>
                </div>`,
                methods: {
                    setTitle() {
                        this.title = Date.now()
                    }
                }
            })

            Vue.component('subtitle', {
                    template: `<div>
                        <h3>我是一个子标题</h3>
                        </div>`
            })
        }


        Vue.use(myTitleCmp)


        const vm = new Vue({
            el: '#app',
            data: {}
        })
    </script>

</body>

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到