//计算属性,有缓存
// 这儿的缓存可以理解为页面多次用到,但计算函数只执行了一次
执行时间: 初始化和相关属性发生变化时会再次触发
直接在computed里面定义变量,然后就可以在页面上进行双向数据;
computed比较适合对多个变量或者对象进行处理后返回一个结果值;
优点
简化tempalte里面{{}}计算和处理props或$emit的传值
应用场景
表单校验,这个应用场景应该是比较常见的,利用正则表达式对每个表单项的实时监控,判断表单是否可以提交;
从Vuex Store中收集相关信息,对Vuex中的数据做计算的时候要特别注意computed的缓存属性,在对Vuex中的对象值进行属性修改的时候,并不会触发computed的中值的变化,这时需要Object.assign({},obj)对依赖对象进行跟新返回一个新对象触发依赖跟新。
computed: {
computedTest() {
return this.message + '现在我用的是computed'
}
} // computedTest就可以通过{{computedTest}}shiyongle
// 使用get 和 set
computed:{
username:{
// 访问当前属性时调用
get(){
return this.firstname+" "+this.lastname
},
// 当前属性变化时调用 val就是变化后的值 在选择框(checkbox)中 val传入的值是选中的状态 true/false
set(val){
let newnamearr=val.split(" ")
this.firstname=newnamearr[0]
this.lastname=newnamearr[1]
}
}
}
1. 不支持缓存,数据变,直接会触发相应的操作;
2.watch支持异步;
//父组件向子组件传递参数,异步监控
props: ["oneList"],
watch: {
"oneList": {
handler(newName, oldName) {
console.log(newName); //null
console.log(oldName) //undefined
// return newName
},
deep: true, // 主要是深度监听对象,数组
immediate: true, // 值最初时候watch就执行
},
},
3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4. 当一个属性发生变化时,需要执行对应的操作;一对多;
5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数.
可以获取属性的新值和旧值。
watch擅长处理的场景:一个数据影响多个数据 ;
应用:监听props,$emit或本组件的值执行异步操作,当执行异步操作时必须用watch而不是computed
查看对象的属性
dir(对象)
// 计算属性计算出的全部姓名
const fullname = computed({
get() {
return user.firstname + "_" + user.lastname;
},
set(val: string) {
const valarr = val.split("_");
user.firstname = valarr[0];
user.lastname = valarr[1];
},
});
// 如果不对新的值修饰,可以采用下面的写法
const newCount = computed(() => {
return "新的count" + count1.value;
});
// ref
watch(
user, // ref
() => {
fullname1.value = user.firstname + "---" + user.lastname;
},
{ immediate: true,deep: true}
);
// reactive 对象数据
watch(
() => {
// ref对象可以直接使用值,reactive的对象,需要写成函数形式,并返回
return userdata.username;
},
() => {
},
{ immediate: true,deep: true }
);
// watch 的第二种用法,自带第一次的显示
// watch监听获取到的全部姓名
watchEffect(() => {
fullname1.value = user.firstname + "---" + user.lastname;
});
监听多个
就需要以数组的形式监听,watchEffect不能监听
watch([
()=>state.name1
,
()=>state.name2
,
],([new1,new2],[old1,old2])=>{
console.log("new1",new1)
console.log("old1",old1)
console.log("new2",new2)
console.log("old2",old2)
})
直接调用的使用方式略
在分模块时,采用map相关语法示例:
// state getters 在计算属性中解构 当页面属性使
// mutations actions 在methods 中解构 当页面方法使
import {mapMutations} from "vuex" // mutation
import { mapActions, mapGetters, mapState } from "vuex"; // action getters state
computed: {
...mapState("user", ["userdata"]),
...mapGetters("user",["gettersUsername","gettersHomeData"])
},
methods:{
...mapActions("user",["asyncGetUserdata"]),
...mapMutations("user",["setuserdata"]), //等同于直接操作 this.$store.commit(""user/setuserdata"")
asyncUserdata(){
this.asyncGetUserdata()
},
loginHandle(){
this.setuserdata(this.user)
this.$router.push("/")
}
}
建议封装通用的hooks再处理(后续处理)
const vuex_name = computed(() => store.state.name); // 主模块state
const vuex_user_userName = computed(() => store.state.user.userName); // user模块state
const vuex_getters_username = computed(() => store.getters.userName);
const vuex_user_getters_username = computed(
() => store.getters["user/user_getters_name"]
);
// 推荐一
store.commit("user/setUserInfo", {
userName: "设置的新名字",
userId: 789,
});
// 方式二
const setUserInfo = store._mutations["user/setUserInfo"][0];
// 方式三 目前有问题 this有问题 找不到 $store
const { setUserInfo } = mapMutations("user", ["setUserInfo"]);
// 推荐一
store.dispatch("user/setUserInfo", {
userName: "异步设置的新名字",
userId: 111,
});
// 方式二
const asyncSetUserInfo = store._actions["user/setUserInfo"][0];
// 方式三 目前有问题 this有问题 找不到 $store
const storeActions = mapActions("user", ["setUserInfo"]);
/ 自定义插件
import * as filters from "./filters"
import * as directives from "./directives"
import wxjButton from "./components/wxjButton/index.vue"
let show = () => console.log("show")
export default {
install(Vue) {
// 原型绑定 属性或方法
Vue.prototype.$show = show
// 注册全局过滤器
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
// 注册全局指令
Object.keys(directives).forEach(k => Vue.directive(k, directives[k]))
// 注册全局组件
Vue.component("wxjButton", wxjButton)
// 混入一个function 专门用来处理每页的 headers信息
Vue.mixin({
methods: {
$seo(title, content, payload = []) {
return {
title,
meta: [
{
hid: 'descrition',
name: "keywords",
content
},
...payload
]
}
}
}
})
}
}
// 导入自己的插件
import myPlugins from "./mixins"
Vue.use(myPlugins)```
// 自定义插件
import * as directives from "./directives"
import wxjButton from "./components/wxjButton/index.vue"
let show = () => console.log("show")
export default {
install(app) {
// 原型绑定 属性或方法
app.config.globalProperties=show
// 注册全局指令
Object.keys(directives).forEach(k => app.directive(k, directives[k]))
// 注册全局组件
app.component("wxjButton", wxjButton)
}
}
// 导入自定义 plugins
import myPlugins from "./mixins"
app.use(myPlugins).use(element).use(store).use(router).mount('#app')
import { getCurrentInstance } from "vue";
const currentInstance = getCurrentInstance();
const message = currentInstance?.appContext.config.globalProperties.$message;
<script setup>
const props = defineProps({
modelValue: {
type: String,
required: true,
}
});
// const emits = defineEmits(["update:modelValue"]); // 简单写法
const emits = defineEmits<{ (e: "handleImg", id: number): void }>();
</script>
其他
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
import {defineComponent} from "vue"
defineComponent({
name:'ceshi'
})
js
const moveTime = ref<string>();
css
animation-duration: v-bind(moveTime);
api参考文档
var 对象 = {
方法名:function(){
// …
return this; // 实现链式编程的核心this
}
}
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left: 100px;
}
.box1 {
top: 100px;
}
.box2 {
top: 300px
}
.box3 {
top: 500px
}
style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js">script>
head>
<body>
<div class="box box1">div>
<div class="box box2">div>
<div class="box box3">div>
body>
<script>
$(function () {
class drag {
constructor(doc) {
this.doc = doc,
this.offsetX = 0, // 鼠标相对当前节点x的定位
this.offsetY = 0, // 鼠标相对当前节点y的定位
this.init()
}
init() {
let that = this
//第一步:鼠标点下时获取鼠标落下的位置
$(this.doc).mousedown(function (ev) {
// ev.clientX 鼠标X的位置
// $(this).offset().left 当前节点和左侧的距离
that.offsetX = ev.clientX - $(this).offset().left;
that.offsetY = ev.clientY - $(this).offset().top;
//第二步:在document下div跟随鼠标移动
$(document).mousemove(that.throttle(function (ev) {
let left = ev.clientX - that.offsetX
let top = ev.clientY - that.offsetY
$(that.doc).css({
left,
top
})
},30))
})
//第三步:在document下 鼠标抬起,取消跟随事件
$(document).mouseup(function () {
$(document).off("mousemove");
})
}
throttle(fn, delay) {
let time1 = 0
return function () {
let time2 = Date.now()
if (time2 - time1 >= delay) {
fn.apply(this, arguments)
time1 = time2
}
}
}
}
let arr = [".box1", ".box2", ".box3"]
arr.forEach(item => {
new drag(item)
})
})
script>