Vue记录

vue2、vue3记录,参考地址:尚硅谷Vue项目实战硅谷甄选,vue3项目+TypeScript前端项目一套通关_哔哩哔哩_bilibili

vue2记录

经典vue2结构 index.vue:

<template>
    <div>...</div>
</template>

<script>
    import method from "xxx.js"
    import component from "xxx.vue"
    export default {
      name: "ComponentName",
      props: {
        rowId: {
          type: Number
        }
      },
      components: {
        component1, component2 ..
      },
      data() {
        return {
          table: [],
          ...
        }
      },
      created() {
        ...
      },
      mounted() {
        ...
      },
      methods: {
        method1() {
        
        }
        ...
      }
    }
</script>

<style scoped>
  .style1 {
    width: 90px
  }
  ...
</style>

实例如:

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"
    >
      <el-form-item label="录入时间" prop="createTime">
        <el-date-picker v-model="dateRangeCreateTime" style="width: 250px" value-format="yyyy-MM-dd" type="daterange"
                        range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/>
      </el-form-item>
      <el-form-item label="网点" prop="networkId">
        <el-select
          multiple
          v-model="queryParams.networkId"
          placeholder="请选择网点"
          clearable size="small">
          <el-option
            v-for="dict in netWorkOptions"
            :key="dict.dictValue"
            :label="dict.dictLabel"
            :value="dict.dictValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="单证编号" prop="dzNo">
        <el-input type="textarea"
                  v-model="queryParams.dzNo"
                  placeholder="请输入单证编号"
                  clearable
                  size="small"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['cusservice:dzmanage:add']"
        >新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['cusservice:dzmanage:remove']"
        >删除
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          icon="el-icon-download"
          size="mini"
          @click="handleImport"
          v-hasPermi="['cusservice:dzmanage:export']"
        >导入
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          icon="el-icon-upload"
          size="mini"
          @click="handleExport"
          v-hasPermi="['cusservice:dzmanage:export']"
        >导出
        </el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table
      border
      v-loading="loading"
      :data="manageList"
      @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center"/>
      <el-table-column label="录入时间" align="center" prop="createTime" width="160" fixed="left"/>
      <el-table-column label="网点" align="center" prop="networkName" fixed="left"/>
      <el-table-column label="单证编号" align="center" prop="dzNo" min-width="130px" fixed="left">
        <template slot-scope="{ row }">
          <copyView>
            <el-link type="primary" @click="handleDetail(row)">{{ row.dzNo }}</el-link>
          </copyView>
        </template>
      </el-table-column>
      <el-table-column label="单证类型" align="center" prop="dzType" :formatter="dzTypeFormat"/>
      <el-table-column label="快递公司" align="center" prop="expressCompany" :formatter="expressCompanyFormat"/>
      <el-table-column label="票数" align="center" prop="piaoNum"/>
      <el-table-column label="明细导入" align="center" prop="detailFileList">
        <template slot-scope="{ row }">
          <el-popover
            placement="right"
            width="400"
            trigger="click">
            <el-table :data="checkDetailShow(row) ? row.detailFiles : []">
              <el-table-column property="fileOriFileName" label="文件名">
                <template slot-scope="scope">
                  <el-link @click="downloadOss(scope.row.fileName)">
                    {{ scope.row.fileOriFileName }}
                  </el-link>
                </template>
              </el-table-column>
            </el-table>
            <el-link slot="reference" v-show="checkDetailShow(row)" type="primary"
                     @click="showDetail(row.detailFiles)">
              明细文件{{' (' + (checkDetailShow(row) ? row.detailFiles.length : 0) + ')'}}
            </el-link>
          </el-popover>
        </template>
      </el-table-column>
      <el-table-column label="录入人" align="center" prop="createBy"/>
      <el-table-column label="备注" align="center" prop="descr" :show-overflow-tooltip="true"/>
      <el-table-column label="状态" align="center" prop="dzStatus">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.dzStatus == 'zc'">暂存</el-tag>
          <el-tag type="success" v-else>归档</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="160"
                       v-if="checkPermi(['*:*:*','cusservice:dzmanage:edit','cusservice:dzmanage:remove'])">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['cusservice:dzmanage:edit']"
          >修改
          </el-button>
          <el-button
            type="text"
            icon="el-icon-delete"
            size="mini"
            @click="handleDelete(scope.row)"
            v-hasPermi="['cusservice:dzmanage:remove']"
          >删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 用户导入对话框 -->
    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
      <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
                 :action="upload.url" :disabled="upload.isUploading"
                 :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处,或
          <em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          <el-link type="info" style="font-size: 12px" @click="downTemple">下载模板</el-link>
        </div>
        <div class="el-upload__tip" style="color: red" slot="tip">
          提示:仅允许导入“xls”或“xlsx”格式文件!
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog title="新增单证" :visible.sync="openAddForm" v-if="openAddForm" width="800px" :before-close="cancelAdd">
      <addDz @cancelAdd="cancelAdd" @completeAdd="completeAdd"></addDz>
    </el-dialog>

    <el-dialog title="修改单证" :visible.sync="openEditForm" v-if="openEditForm" width="800px" :before-close="cancelEdit">
      <editDz @cancelEdit="cancelEdit" :rowId="rowId"></editDz>
    </el-dialog>
  </div>
</template>

<script>
  import {
    listManage,
    getManage,
    delManage,
    addManage,
    updateManage,
    downTemple,
    importTemplate,
    exportManage
  } from "@/api/cusservice/dzmanage";
  import {listNetworkOptions2} from "@/api/cusservice/network";
  import {checkPermi} from '@/utils/permission'
  import {getToken} from "@/utils/auth";
  import {downloadOss} from "@/utils/ruoyi";
  import addDz from "./add"
  import editDz from "./edit"


  export default {
    name: "Manage",
    components: {
      addDz, editDz
    },
    data() {
      return {
        // 遮罩层
        loading: true,
        // 选中数组
        ids: [],
        // 非单个禁用
        single: true,
        // 非多个禁用
        multiple: true,
        // 显示搜索条件
        showSearch: true,
        // 总条数
        total: 0,
        // 单证管理表格数据
        manageList: [],
        // 弹出层标题
        title: "",
        // 是否显示弹出层
        open: false,
        // 查询参数
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          networkId: [],
          dzNo: null,
          yundanNo: null,
          dzType: [],
          expressCompany: [],
          userId: null,
          descr: null,
          dzStatus: null,
        },
        //创建日期
        dateRangeCreateTime: [],
        //网点字典
        netWorkOptions: [],
        //单证类型字典
        dzTypeOptions: [],
        // 快递公司字典
        expressCompanyOptions: [],
        // 单证中台字典
        dzStatusOptions: [],

        //选中的行
        multipleTable: [],
        upload: {
          // 是否显示弹出层(用户导入)
          open: false,
          // 弹出层标题(用户导入)
          title: "单证导入",
          // 是否禁用上传
          isUploading: false,
          // 是否更新已经存在的用户数据
          updateSupport: 0,
          // 设置上传的请求头部
          headers: {Authorization: "Bearer " + getToken()},
          // 上传的地址
          url: process.env.VUE_APP_BASE_API + "/cusservice/dzmanage/ImportData",
        },
        openAddForm: false,
        openEditForm: false,
        rowId: null,

      };
    },
    created() {
      this.initPage();
    },
    methods: {
      checkPermi,
      initPage() {
        listNetworkOptions2().then((response) => {
          let temlist = [];
          response.rows.map((value, index, arry) => {
            temlist.push({
              dictValue: value.rowid + "",
              dictLabel: value.networkName,
            });
          });
          this.netWorkOptions = temlist;
        });
        this.getDicts("biz_dz_type").then((response) => {
          this.dzTypeOptions = response.data;
        });
        this.getDicts("bc_express_company").then((response) => {
          this.expressCompanyOptions = response.data;
        });
        this.getDicts("biz_dz_status").then((response) => {
          this.dzStatusOptions = response.data;
        });
        this.getList()
      },
      /** 查询单证管理列表 */
      getList() {
        this.loading = true;
        let query = {...this.queryParams}
        query.networkId = query.networkId ? query.networkId.join(',') : ''
        query.dzType = query.dzType ? query.dzType.join(',') : ''
        query.expressCompany = query.expressCompany ? query.expressCompany.join(',') : ''
        listManage(query).then(response => {
          this.manageList = response.rows;
          this.total = response.total;
          this.loading = false;
        });
      },
      // 取消按钮
      cancel() {
        this.open = false;
        this.reset();
      },
      // 表单重置
      reset() {
        this.dateRangeCreateTime = []
        this.queryParams = {
          pageNum: 1,
          pageSize: 10
        };
        this.resetForm("form");
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.queryParams.pageNum = 1;
        this.getList();
      },
      /** 重置按钮操作 */
      resetQuery() {
        this.reset();
        this.handleQuery();
      },
      // 多选框选中数据
      handleSelectionChange(selection) {
        this.ids = selection.map(item => item.id)
        this.single = selection.length !== 1
        this.multiple = !selection.length
        this.multipleTable = selection
      },
      /** 新增按钮操作 */
      handleAdd() {
        // this.reset();
        // this.$router.push({
        //   path: "/dzmanage/add",
        // });
        this.openAddForm = true;
      },
      cancelAdd() {
        // this.reset();
        // this.$router.push({
        //   path: "/dzmanage/add",
        // });
        this.openAddForm = false;
        // this.getList()
      },
      completeAdd() {
        this.openAddForm = false;
        this.getList();
      },
      cancelEdit() {
        this.openEditForm = false;
        this.rowId = null
        // this.getList()
      },
      /** 修改按钮操作 */
      handleUpdate(row) {
        // this.$router.push("/dzmanage/edit/" + row.id + "?t=" + Date.now());
        this.rowId = row.id;
        this.openEditForm = true;
      },
      guidang() {
        const ids = this.ids
        let ask = this.multipleTable && this.multipleTable.length == 1 ? ('单证编号为:' + this.multipleTable[0].dzNo)
          : (this.ids.length + '条')
        let ths = this;
        this.$confirm('是否确认归档所选的 ' + ask + ' 的数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function () {
          updateManage({id: ids[0], dzStatus: 'gd'}).then(() => {
            ths.getList();
            ths.msgSuccess("归档成功");
          })
        }).catch((e) => {
          console.log(e)
        })
      },
      /** 删除按钮操作 */
      handleDelete(row) {
        const ids = row.id || this.ids;
        let ask = row && row.dzNo ? ('单证编号:' + row.dzNo) : (this.ids.length + '条')
        this.$confirm('是否确认删除所选的 ' + ask + ' 数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          this.loading = true
          return delManage(ids)
        }).then(() => {
          this.msgSuccess("删除成功");
          this.getList();
        }).catch(() => {
          this.loading = false
        })
      },
      handleImport() {
        this.upload.open = true;
      },
      /** 下载模板 */
      downTemple() {
        downTemple().then((response) => {
          console.log(response)
          this.download(response.msg);
        });
      },
      /** 导入模板 */
      importTemplate() {
        importTemplate().then((response) => {
          console.log(response)
        });
      },
      // 文件上传中处理
      handleFileUploadProgress(event, file, fileList) {
        this.upload.isUploading = true;
      },
      // 文件上传成功处理
      handleFileSuccess(response, file, fileList) {
        this.upload.open = false;
        this.upload.isUploading = false;
        this.$refs.upload.clearFiles();
        this.$alert(response.msg, "导入结果", {
          dangerouslyUseHTMLString: true
        });
        this.getList();
      },
      // 提交上传文件
      submitFileForm() {
        this.$refs.upload.submit();
      },
      /** 导出按钮操作 */
      handleExport() {
        const queryParams = this.queryParams;
        this.$confirm('是否确认导出所有单证管理数据项?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function () {
          return exportManage(queryParams);
        }).then(response => {
          this.download(response.msg);
        }).catch(() => {
        })
      },
      dzTypeFormat(row, column) {
        return this.selectDictLabel(this.dzTypeOptions, row[column.property]);
      },
      expressCompanyFormat(row, column) {
        return this.selectDictLabel(this.expressCompanyOptions, row[column.property]);
      },
      handleDetail(row) {
        console.log(row)
        this.$router.push("/dzmanage/detail/" + row.id + "?t=" + Date.now());
      },
      checkDetailShow(row) {
        return (row.detailFiles && row.detailFiles.length > 0);
      },
      showDetail(fileList) {
        console.log(fileList)
      },
      downloadOss(fileName) {
        console.log(fileName)
        this.$message.info("正在下载,下载期间请勿重复操作...")
        downloadOss(fileName);
      },
    }
  };
</script>

<style scoped>
	.app-container {
	  padding: 10px
	}

</style>

vue2的组件通讯方式有:

vue3记录

1、父组件(通过符号:)向子组件传递参数,子组件通过defineProps接收:

//1、父组件中引入子组件并通过":"向子组件传值:
<Child info="我是父组件,给你钱" :money="money"></Child>
<script setup>
import Child from "./Child.vue";
//ref可以获取到真实的dom节点,也可以获取到子组件实例
import { ref } from "vue";
let money = ref(999);
</script>

//2、子组件中使用"defineProps"接收:
<template>
  <div class="son">
       <h1>我是子组件:曹植</h1>
       <p>{{props.info}}</p>
       <p>{{props.money}}</p>
      <!--props可以省略前面的名字--->
       <p>{{info}}</p>
       <p>{{money}}</p>
       <button @click="updateProps">修改props数据</button>
  </div>
</template>

<script setup>
//需要使用到defineProps方法去接受父组件传递过来的数据
//defineProps是Vue3提供方法,不需要引入直接使用
let props = defineProps(['info','money']); //数组|对象写法都可以
//按钮点击的回调
const updateProps = ()=>{
  props.money+=10;  //props:只读的
  console.log(props)
}
</script>

2、父组件(通过符号@)向子组件传递回调方法,子组件通过defineEmits触发:

1、父组件向子组件传递回调方法
<Event1 @fatherMethod="fatherMethod"></Event1>
<script setup lang="ts">
//等待回调
const fatherMethod= (param1, param2) => {
    $emit('fatherMethod', param1, param2);
};
</script>


2、子组件触发回调
<template>
  <div class="child">
    <p>我是子组件</p>
    <button @click="handler">点击我触发自定义事件xxx</button>
  </div>
</template>

<script setup lang="ts">
//利用defineEmits方法返回函数触发自定义事件
//defineEmits方法不需要引入直接使用
let $emit = defineEmits(['fatherMethod']);
//按钮点击回调
const handler = () => {
  //第一个参数:事件类型 第二个|三个|N参数即为注入数据
    $emit('fatherMethod','东风导弹','航母');
};
</script>

3、通过mitt实现总线功能

1、dependices 引入mitt,并在bus/index.js中使用
"mitt": "^3.0.0"

//引入mitt插件:mitt一个方法,方法执行会返回bus对象
import mitt from 'mitt';
const $bus = mitt();
export default $bus;


2、子组件注册 $bus.on 事件
<script setup lang="ts">
import $bus from "../../bus";
//组合式API函数
import { onMounted } from "vue";
//组件挂载完毕的时候,当前组件绑定一个事件,接受将来兄弟组件传递的数据
onMounted(() => {
  //第一个参数:即为事件类型  第二个参数:即为事件回调
  $bus.on("car", (car) => {
    console.log('收到一两car', car);
  });
});
</script>

3、另一个子组件触发 $bus.mitt 事件
<script setup lang="ts">
//引入$bus对象
import $bus from '../../bus';
//点击按钮回调
const handler = ()=>{
  $bus.emit('car',{car:"法拉利"});
}
</script>

4、通过 v-model 实现父子组件传值与修改

1、v-model的经典用法,在组件中实现数据绑定
<input type="text" v-model="info" />

2、通过v-model传值给子组件,并通过 emit 回调修改
父组件中:
<Child :modelValue="money" @update:modelValue="handler"></Child>
let money = ref(10000);
//自定义事件的回调
const handler = (num) => {
  //将来接受子组件传递过来的数据
  money.value = num;
};

子组件中:
<h3>钱数:{{ modelValue }}</h3>
<script setup lang="ts">
//接受props
let props = defineProps(["modelValue"]);
let $emit = defineEmits(['update:modelValue']);
//子组件内部按钮的点击回调
const handler = ()=>{
   //触发自定义事件
   $emit('update:modelValue',props.modelValue+1000);
}
</script>

以上方式等价于:<Child v-model="money"></Child>
即 v-model组件身上使用 
第一:相当有给子组件传递props[modelValue] = 10000
第二:相当于给子组件绑定自定义事件update:modelValue



3、如果是多个model,可以用v-model:参数名的方式
父组件:
<Child v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child>
子组件:
<template>
  <div class="child2">
    <h1>同时绑定多个v-model</h1>
    <button @click="handler">pageNo{{ pageNo }}</button>
    <button @click="$emit('update:pageSize', pageSize + 4)">
      pageSize{{ pageSize }}
    </button>
  </div>
</template>

<script setup lang="ts">
let props = defineProps(["pageNo", "pageSize"]);
let $emit = defineEmits(["update:pageNo", "update:pageSize"]);
//第一个按钮的事件回调
const handler = () => {
  $emit("update:pageNo", props.pageNo + 3);
};
</script>

5、通过 useAttrs 可以快速实现defineProps的效果,并可以传入方法

1、父组件中使用组件,并传入参数与方法
<HintButton type="primary" size="small" :icon="Edit" title="编辑按钮" @click="handler" @xxx="handler"></HintButton>

2、子组件通过useAttrs接收
<template>
  <div :title="title">
     <el-button :="$attrs"></el-button>   
  </div>
</template>

<script setup lang="ts">
//引入useAttrs方法:获取组件标签身上属性与事件
import {useAttrs} from 'vue';
//此方法执行会返回一个对象
let $attrs = useAttrs();

//万一用props接受title
let props =defineProps(['title']);
//props与useAttrs方法都可以获取父组件传递过来的属性与属性值
//但是props接受了useAttrs方法就获取不到了
console.log($attrs);
</script>

6、通过ref、$parent 来获取到子/父组件实例,以获取对应的数据和方法

1、父组件中,通过 ref 拿到子组件对象,通过 defineExpose 暴露自身属性或方法
<template>
    <div class="box">
        <h1>我是父亲曹操:{{money}}</h1>
        <button @click="handler">找我的儿子曹植借10元</button>
        <hr>
        <Son ref="son"></Son>
        <hr>
        <Dau></Dau>
    </div>
</template>

<script setup lang="ts">
    //ref:可以获取真实的DOM节点,可以获取到子组件实例VC
    //$parent:可以在子组件内部获取到父组件的实例
    //引入子组件
    import Son from './Son.vue'
    import Dau from './Daughter.vue'
    import {ref} from 'vue';
    //父组件钱数
    let money = ref(100000000);
    //获取子组件的实例
    let son = ref();
    //父组件内部按钮点击回调
    const handler = () => {
        money.value += 10;
        //儿子钱数减去10
        son.value.money -= 10;
        son.value.fly();
    }
    //对外暴露
    defineExpose({
        money
    })
</script>

2、子组件中,通过 $parent 拿到父组件,并通过 defineExpose 暴露自身属性或方法
<template>
    <div class="dau">
        <h1>我是闺女曹杰{{money}}</h1>
        <button @click="handler($parent)">点击我爸爸给我10000元</button>
    </div>
</template>

<script setup lang="ts">
    import {ref} from 'vue';
    //闺女钱数
    let money = ref(999999);
    //闺女按钮点击回调
    const handler = ($parent) => {
        money.value += 10000;
        $parent.money -= 10000;
    }
    const fly = () => {
        console.log('女儿可以飞');
    }
    //组件内部数据对外关闭的,别人不能访问
    //如果想让外部访问需要通过defineExpose方法对外暴露
    defineExpose({
        fly
    })
</script>

7、通过provide 与 inject 实现祖孙组件的数据传递

1、父组件中使用provide注入数据
<template>
  <div class="box">
    <h1>Provide与Inject{{car}}</h1>
    <hr />
    <Child></Child>
  </div>
</template>

<script setup lang="ts">
import Child from "./Child.vue";
//vue3提供provide(提供)与inject(注入),可以实现隔辈组件传递数据
import { ref, provide } from "vue";
let car = ref("法拉利");
//祖先组件给后代组件提供数据
//两个参数:第一个参数就是提供的数据key
//第二个参数:祖先组件提供数据
provide("TOKEN", car);
</script>


2、子/孙组件通过 inject 获取注入的数据,并且可以修改
<template>
  <div class="child1">
    <h1>孙子组件</h1>
    <p>{{car}}</p>
    <button @click="updateCar">更新数据</button>
  </div>
</template>

<script setup lang="ts">
import {inject} from 'vue';
//注入祖先组件提供数据
//需要参数:即为祖先提供数据的key
let car = inject('TOKEN');
const updateCar = ()=>{
   car.value  = '自行车';
}
</script>

8、通过 pinia 统一存储数据,以便在各个组件中共享数据

1、引入依赖,安装依赖,使用依赖
"pinia": "^2.0.14"
npm i
//main.js 引入仓库
import store from './store'
app.use(store)
 
2、新建 store/index.ts
//创建大仓库
import { createPinia } from 'pinia';
//createPinia方法可以用于创建大仓库
let store = createPinia();
//对外暴露,安装仓库
export default store;

3、新建小仓库:store/module/info.ts
//定义info小仓库
import { defineStore } from "pinia";
//第一个仓库:小仓库名字  第二个参数:小仓库配置对象
//defineStore方法执行会返回一个函数,函数作用就是让组件可以获取到仓库数据
let useInfoStore = defineStore("info", {
    //存储数据:state
    state: () => {
        return {
            count: 99,
            arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        }
    },
    actions: {
        //注意:函数没有context上下文对象
        //没有commit、没有mutations去修改数据
        updateNum(a: number, b: number) {
            this.count += a;
        }
    },
    getters: {
        total() {
            let result:any = this.arr.reduce((prev: number, next: number) => {
                return prev + next;
            }, 0);
            return result;
        }
    }
});
//对外暴露方法
export default useInfoStore;

各组件中使用 pinia

<template>
  <div class="child">
    <h1>{{ infoStore.count }}---{{infoStore.total}}</h1>
    <button @click="updateCount">点击我修改仓库数据</button>
  </div>
</template>

<script setup lang="ts">
//vuex:集中式管理状态容器,可以实现任意组件之间通信!!!
//核心概念:state、mutations、actions、getters、modules

//pinia:集中式管理状态容器,可以实现任意组件之间通信!!!
//核心概念:state、actions、getters
//pinia写法:选择器API、组合式API
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
console.log(infoStore);
//修改数据方法
const updateCount = () => {
  //仓库调用自身的方法去修改仓库的数据
  infoStore.updateNum(66,77);
};
</script>

9、通过插槽 slot 方式可以将子组件的数据回传给父组件,由父组件指定子组件的展现形式

1、父组件引入子组件,并填充具体的插槽的内容
<template>
  <div>
    <h1>slot</h1>
    <Test>
      <div>
        <pre>大江东去浪淘尽,千古分流人物</pre>
      </div>
      <!-- 具名插槽填充a -->
      <template #a>
        <div>我是填充具名插槽a位置结构</div>
      </template>
      <!-- 具名插槽填充b v-slot指令可以简化为# -->
      <template #b>
        <div>我是填充具名插槽b位置结构</div>
      </template>
    </Test>

    <Test1 :todos="todos">
      <template v-slot="{ $row, $index }">
        <p :style="{ color: $row.done ? 'green' : 'red' }">
          {{ $row.title }}--{{ $index }}
        </p>
      </template>
    </Test1>
  </div>
</template>

<script setup lang="ts">
import Test from "./Test.vue";
import Test1 from "./Test1.vue";
//插槽:默认插槽、具名插槽、作用域插槽
//作用域插槽:就是可以传递数据的插槽,子组件可以讲数据回传给父组件,父组件可以决定这些回传的
//数据是以何种结构或者外观在子组件内部去展示!!!

import { ref } from "vue";
//todos数据
let todos = ref([
  { id: 1, title: "吃饭", done: true },
  { id: 2, title: "睡觉", done: false },
  { id: 3, title: "打豆豆", done: true },
  { id: 4, title: "打游戏", done: false },
]);
</script>

<style scoped>
</style>


2、子组件通过插槽 slot 来预定内容,具体内容由父组件决定
<template>
  <div class="box">
    <h1>我是子组件默认插槽-start</h1>
    <!-- 默认插槽 -->
    <slot></slot>
    <h1>我是子组件默认插槽-end</h1>
    <h1>具名插槽填充数据--a-start</h1>
    <slot name="a"></slot>
    <h1>具名插槽填充数据--a-end</h1>
    <h1>具名插槽填充数据--b-start</h1>
    <slot name="b"></slot>
    <h1>具名插槽填充数据--b-end</h1>
  </div>
</template>

<template>
  <div class="box">
    <h1>作用域插槽</h1>
    <ul>
      <li v-for="(item, index) in todos" :key="item.id">
        <!--作用域插槽:可以讲数据回传给父组件-->
        <slot :$row="item" :$index="index"></slot>
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
//通过props接受父组件传递数据
defineProps(["todos"]);
</script>

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值