父双表树型grid组件javascript源码, 拿走不谢~
先看pc端demo(下载后获得组件源码和使用API)
http://kgo-js.com/htmls/twintreegridsample.html
vue搭建项目的时候,会有父组件和子组件,你有没有思考一下当我想要得到父组件或者子组件的数据时,该怎么实现父组件和子组件之间的通讯呢?如果知道的话,那太nice啦,不太清楚的话那就往下看吧~ 正文 我们通过实现下面的小demo来介绍父组件和子组件之间的通讯吧~
添加图片注释,不超过 140 字(可选)
两种方式:
添加图片注释,不超过 140 字(可选)
<Child :list="list"></Child>
子组件通过defineProps接收父组件传入的list:
defineProps({
list: {
type: Array,
default: ()=> [] // 默认值
}
});
App.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
<Child :list="list"></Child>
</template>
<script setup>
import Child from '@/components/child.vue';
import { ref } from 'vue';
const list=ref(['html', 'css', 'js']);
const value=ref('');
const add=()=> {
list.value.push(value.value);
value.value='';
}
</script>
<style lang="css" scoped>
</style>
child.vue
<template>
<div class="child">
<ul>
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
defineProps({
list: {
type: Array,
default: ()=> [] // 默认值
}
});
</script>
<style lang="css" scoped>
</style>
<Child :msg="toChild"></Child>
子组件通过 defineProps接收msg
const props=defineProps({
msg:''
});
通过watch来监听msg,对列表数据进行更新
watch(
()=> props.msg,
(newValue, oldValue)=> {
list.value.push(newValue);
}
);
App.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
<Child :msg="toChild"></Child>
</template>
<script setup>
import Child from '@/components/child.vue';
import { ref } from 'vue';
const list=ref(['html', 'css', 'js']);
const value=ref('');
const toChild=ref('');
const add=()=> {
toChild.value=value.value;
}
</script>
<style lang="css" scoped>
</style>
child.vue
<template>
<div class="child">
<ul>
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import {ref, watch} from 'vue';
const list=ref(['html', 'css', 'js']);
const props=defineProps({
msg:''
});
watch(
()=> props.msg,
(newValue, oldValue)=> {
list.value.push(newValue);
}
);
</script>
<style lang="css" scoped>
</style>
添加图片注释,不超过 140 字(可选)
const emits=defineEmits(['add1']); // 创建一个add事件
子组件在add函数中发布事件,并传入数据value
const add=()=> {
// 将value给到父组件
emits('add1', value.value);// 发布事件
}
在父组件中订阅事件add1
<Child @add1="handle"></Child>
当触发add1事件时,也就是点击增加时触发handle函数
const handle=(event)=> {
list.value.push(event);
}
App.vue
<template>
<!-- 订阅add1事件 -->
<Child @add1="handle"></Child>
<div class="child">
<ul>
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import Child from '@/components/child2.vue';
import { ref } from 'vue';
const list=ref(['html', 'css', 'js']);
const handle=(event)=> {
list.value.push(event);
}
</script>
<style lang="css" scoped>
</style>
child.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const value=ref('');
const emits=defineEmits(['add1']); // 创建一个add事件
const add=()=> {
// 将value给到父组件
emits('add1', value.value);// 发布事件
}
</script>
<style lang="css" scoped>
</style>
<Child v-model:list="list"></Child>
子组件通过props接收list
const props=defineProps({
list:{
type: Array,
default: ()=> []
}
});
子组件可以直接在add函数通过props.list.push(value.value);来实现对列表数据的更新,但是不太建议这种方法,不太建议直接操作父组件给过来的数据,这样的话代码的可维护性比较差 子组件通过使用defineEmits来新建一个emits函数,该函数用于告知父组件,子组件希望更新一个名为 list 的数据,再新建一个变量arr来接收list,来更新arr,再通过emits('update:list', arr);来实现对list的更新
const emits=defineEmits(['update:list']);
const add=()=> {
const arr=props.list;
arr.push(value.value);
emits('update:list', arr);
}
App.vue
<template>
<Child v-model:list="list"></Child>
<div class="child">
<ul>
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import Child from '@/components/child3.vue';
import { ref } from 'vue';
const list=ref(['html', 'css', 'js']);
</script>
<style lang="css" scoped>
</style>
child.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const value=ref('');
const props=defineProps({
list:{
type: Array,
default: ()=> []
}
});
const emits=defineEmits(['update:list']);
const add=()=> {
// props.list.push(value.value);// 不建议直接操作父组件给过来的数据
const arr=props.list;
arr.push(value.value);
emits('update:list', arr);
}
</script>
<style lang="css" scoped>
</style>
将列表数据存放在子组件中:
<Child ref="childRef"></Child>
<div class="child">
<ul>
<li v-for="(item, index) in childRef?.list" :key="index">{{ item }}</li>
</ul>
</div>
-childRef?.list 这是一种安全访问属性的方式,避免了尝试访问undefined或null对象的属性时抛出错误,也就是只有当childRef不为null或undefined时,才会尝试访问其list属性,因为此时子组件可能尚未被创建或挂载,直接访问childRef.list会导致错误,因为null或undefined没有list属性 App.vue
<template>
<Child ref="childRef"></Child>
<div class="child">
<ul>
<li v-for="(item, index) in childRef?.list" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import Child from '@/components/child4.vue';
import { ref } from 'vue';
const childRef=ref(null);
</script>
<style lang="css" scoped>
</style>
child.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const value=ref('');
const list=ref(['html', 'css', 'js']);
const add=()=> {
list.value.push(value.value);
}
defineExpose({list});//==> defineExpose({list: list}); 心甘情愿暴露出list
</script>
<style lang="css" scoped>
</style>
结语
1. border-style:solid(实线)/dashed(虚线)/dotted(点划线)/double(双线)
2. padding 内容区域距离边框
3. padding会撑开原有盒子的宽、高所以我们要减去padding的长度
4. padding的属性值4种方式:上 右 下 左、上 左右 下、上下 左右、 一个值四个方向(可以单独设置某一边)
5. 如果出现边框塌陷那么:overflow:hidden;
1. margin 块与块之间的位置
2. margin: 0 auto
3. margin-top;设置时,如果子父都设置了margin,子的margin会传递到父的margin,例如:
解决方法:在父元素加入:overflow:hidden;
4. margin与padding
1. margin框架与框架之间、块与块之间、盒子与盒子、
2. padding盒子内部
1. 语法{overflow:visible/hidden/scroll/auto/inherit;}
说明:
visible:默认值,内容不会被修剪,会出现在元素框之外。
hidden:内容会被修剪,并且其余内容是不可见的;
sorcll:内容会被修剪,但浏览器会显示滚动条,以便查看其余的内容;
auto:如果内容被修剪,则浏览器会显示滚动条,以便看见其他的内容;
inherit:规定应该从父元素继承overflow属性的值。
2. 语法{white-space:normal/pre/nowrap/pre-wrap/pre-line/inherit;}
normal:默认。空白会被浏览器忽略。
pre:空白会被浏览器保留。
nowrap:文本不会换行,文本会在在同一行上继续,直到遇到<br>标签为止。
pre-wrap:保留空白符序列,但是正常的进行换行
pre-line:合并空白符序列,但保留换行符。
inherit:规定应该从父元素继承white-space属性的值。
1. 语法{text-overflow:clip/ellipsis;}
clip:不显示省略号,而是简单的裁剪。
ellipsis:当对象内文本没有溢出时,显示省略标记。
2. 使用ellipsis时需要配合下面:
width:10px;容器的宽,
white-space:nowrap;强制文本在一行内显示,
overflow:hidden; 溢出内容为隐藏,
text-overflow:ellipsis; 溢出文本显示省略号,
*请认真填写需求信息,我们会在24小时内与您取得联系。