整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

子父双表树型grid组件javascript源码

子父双表树型grid组件javascript源码

父双表树型grid组件javascript源码, 拿走不谢~

先看pc端demo(下载后获得组件源码和使用API)

http://kgo-js.com/htmls/twintreegridsample.html

vue搭建项目的时候,会有父组件和子组件,你有没有思考一下当我想要得到父组件或者子组件的数据时,该怎么实现父组件和子组件之间的通讯呢?如果知道的话,那太nice啦,不太清楚的话那就往下看吧~ 正文 我们通过实现下面的小demo来介绍父组件和子组件之间的通讯吧~

添加图片注释,不超过 140 字(可选)

父组件传子组件

两种方式:

添加图片注释,不超过 140 字(可选)

父组件中存放列表数据和input,子组件来实现渲染列表,传列表给子组件

  • 父组件通过:list="list"list传给子组件
 <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>

父组件存放input,子组件放列表并实现渲染,父组件传input内的值给子组件

  • 父组件通过定义一个变量toChild,将value赋值给toChild
  • 通过:msg="toChild"toChildmsg传递给子组件
  <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>

子组件传父组件

子组件中存放input,父组件中存放数据清单并渲染数据

添加图片注释,不超过 140 字(可选)

第一种方法

  • 子组件创建一个add1事件
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>

第二种方法

  • 父组件通过 v-model:list="list"将list传给子组件
 <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>

第三种方法

将列表数据存放在子组件中:

  • 子组件通过defineExpose({list});list暴露出来
  • 父组件通过ref="childRef"赋予了一个名字为childRef的引用
 <Child ref="childRef"></Child>
  • 父组件通过 const childRef=ref(null);创建一个响应式的引用(ref)对象childRef
  • 通过(item, index) in childRef?.list来遍历列表数据
 <div class="child">
        <ul>
            <li v-for="(item, index) in childRef?.list" :key="index">{{ item }}</li>
        </ul>
    </div>

-childRef?.list 这是一种安全访问属性的方式,避免了尝试访问undefinednull对象的属性时抛出错误,也就是只有当childRef不为nullundefined时,才会尝试访问其list属性,因为此时子组件可能尚未被创建或挂载,直接访问childRef.list会导致错误,因为nullundefined没有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. 父子组件通讯 --- 父组件用v-bind绑定传给子组件,子组件用defineProps接收数据
  2. 子父组件通讯 --- 子组件用defineEmits创建一个事件,在发布该事件时传入数据,父组件通过v-on来订阅该事件
  3. 子父组件通讯 --- 父组件借助v-model将数据绑定给子组件,子组件创建'update:xxx'事件,并将接收到的数据修改后emits出来
  4. 子父组件通讯 --- 父组件通过ref获取子组件中的defineExpose()暴露出来的数据

2第一章笔记

11盒子模型

1. border-style:solid(实线)/dashed(虚线)/dotted(点划线)/double(双线)

2. padding 内容区域距离边框

3. padding会撑开原有盒子的宽、高所以我们要减去padding的长度

4. padding的属性值4种方式:上 右 下 左、上 左右 下、上下 左右、 一个值四个方向(可以单独设置某一边)

5. 如果出现边框塌陷那么:overflow:hidden;

12盒子模型

1. margin 块与块之间的位置

2. margin: 0 auto

3. margin-top;设置时,如果子父都设置了margin,子的margin会传递到父的margin,例如:

解决方法:在父元素加入:overflow:hidden;

4. margin与padding

1. margin框架与框架之间、块与块之间、盒子与盒子、

2. padding盒子内部

13文本溢出

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属性的值。

14文本溢出

1. 语法{text-overflow:clip/ellipsis;}

clip:不显示省略号,而是简单的裁剪。

ellipsis:当对象内文本没有溢出时,显示省略标记。

2. 使用ellipsis时需要配合下面:

width:10px;容器的宽,

white-space:nowrap;强制文本在一行内显示,

overflow:hidden; 溢出内容为隐藏,

text-overflow:ellipsis; 溢出文本显示省略号,