Vue3+element-plus摘要
1.如果自己电脑vue版本是vue2版本,下面将详细介绍如何在vue2版本基础上继续安装
vue3版本且不会影响vue2版本的使用
1-1 在c盘或者别的盘建一个文件夹vue3
1-2 在这个文件夹里使用WIN+R 打开终端 输入命令 npm install @vue/cli 安装完即可
1-3 然后进入此文件夹中的node_modules中的.bin文件夹中,修改里面文件如下:
vue修改为vue3, vue.cmd修改为vue3.cmd
1-4 然后把vue3.cmd拖拽到命令窗口中加上-v即可看到版本号 如下图所示
1-5 接下来就是配置环境变量
1-5-1 打开电脑系统属性-高级-环境变量
1-5-2 点击系统变量下方的新建 配置新的变量
变量名:vue3_cli 变量值:"C:\vue3\node_modules\.bin"(根据自己位置就行)
1-5-3 点击变量中的path 点击编辑 完了把新增 把%vue_cli3%
1-5-5 如果是建vue3项目的话 具体命令是 vue3 create demo_project,然后根据具体内容去选择
2.element-plus新增组件库
2-1 Text 基本用法 具体代码如下(可以直接新建完项目以后粘贴验证):
<template>
<div class="div_container">
<h3>Text 基本用法</h3>
<el-text class="mr-5">Default</el-text>
<el-text class="mr-5" type="primary">Primary</el-text>
<el-text class="mr-5" type="success">Success</el-text>
<el-text class="mr-5" type="info">Info</el-text>
<el-text class="mr-5" type="warning">Warning</el-text>
<el-text class="mr-5" type="danger">Danger</el-text>
<h3>Text 尺寸</h3>
<el-text class="mr-5" size="large">Large</el-text>
<el-text class="mr-5">Default</el-text>
<el-text class="mr-5" size="small">Small</el-text>
<h3 style="margin-bottom: 10px">Text 省略</h3>
<div style="margin-bottom: 10px">
通过 truncated 属性,在文本超过视图或最大宽度设置时展示省略符。 通过
line-clamp 属性控制多行的样式
</div>
<div>
<el-text class="w-150px mb-2" truncated>
Self element set width 100px
</el-text>
<el-row class="w-150px mb-2">
<el-text truncated>Squeezed by parent element</el-text>
</el-row>
<el-text line-clamp="2">
The -webkit-line-clamp CSS property<br />
allows limiting of the contents of<br />
a block to the specified number of lines.
</el-text>
</div>
<h3>Text 覆盖</h3>
<el-space direction="vertical">
<el-text>span</el-text>
<el-text tag="p">This is a paragraph.</el-text>
<el-text tag="b">Bold</el-text>
<el-text tag="i">Italic</el-text>
<el-text>
This is
<el-text tag="sub" size="small">subscript</el-text>
</el-text>
<el-text>
This is
<el-text tag="sup" size="small">superscript</el-text>
</el-text>
<el-text tag="ins">Inserted</el-text>
<el-text tag="del">Deleted</el-text>
<el-text tag="mark">Marked</el-text>
</el-space>
</div>
</template>
<script setup>
import "@element-plus/icons-vue";
</script>
<style scoped>
.div_container {
}
.mr-5 {
margin-right: 5px;
}
.w-150px {
width: 150px;
}
.mb-2 {
margin-bottom: 2px;
}
</style>
2-2 TreeSelect 树形选择
<template>
<h3>TreeSelect 树形选择 选择任意级别</h3>
<div style="color: lightseagreen">
(注意:当属性 check-strictly=true
时,任何节点都可以被选择,否则只有子节点可被选择。)
</div>
<div class="node_css mt_15">
<el-tree-select
v-model="value"
:data="data"
:check-strictly="checkStrictly"
:render-after-expand="false"
style="width: 240px"
/>
<div class="mt_15">
show checkbox(only click checkbox to select):
<el-tree-select
v-model="value2"
:data="data"
:check-strictly="checkStrictly"
:render-after-expand="false"
show-checkbox
style="width: 240px"
/>
</div>
<div class="mt_15">
show checkbox with `check-on-click-node`:
<el-tree-select
v-model="value3"
:data="data"
:check-strictly="checkStrictly"
:render-after-expand="false"
show-checkbox
check-on-click-node
style="width: 240px"
/>
</div>
</div>
<div style="display: flex; flex-direction: row">
<div style="flex: 5">
<el-watermark
:width="130"
:height="30"
image="https://element-plus.org/images/element-plus-logo.svg"
>
<div style="height: 500px" />
</el-watermark>
</div>
<div style="flex: 5">
<el-watermark
:font="font"
:content="['Element+', 'Element Plus']"
:width="130"
:height="40"
>
<div style="height: 500px" />
</el-watermark>
</div>
</div>
</template>
<script setup>
import { ref, reactive, toRaw, onMounted } from "vue";
const value = ref();
const value2 = ref();
const value3 = ref();
const checkStrictly = ref(false);
const demolist = reactive({
list: [
{
title: "一般",
// icon: h(Home),
name: "home",
value: "0",
},
{
title: "还好",
// icon: h(Category),
name: "category",
value: "0",
},
{
title: "很好",
// icon: h(Find),
name: "find",
value: "0",
},
{
title: "最爱",
// icon: h(Cart),
name: "cart",
value: "0",
},
{
title: "改进",
// icon: h(My),
name: "my",
value: "0",
},
],
});
const data = [
{
value: "1",
label: "Level one 1",
children: [
{
value: "1-1",
label: "Level two 1-1",
children: [
{
value: "1-1-1",
label: "Level three 1-1-1",
},
],
},
],
},
{
value: "2",
label: "Level one 2",
children: [
{
value: "2-1",
label: "Level two 2-1",
children: [
{
value: "2-1-1",
label: "Level three 2-1-1",
},
],
},
{
value: "2-2",
label: "Level two 2-2",
children: [
{
value: "2-2-1",
label: "Level three 2-2-1",
},
],
},
],
},
{
value: "3",
label: "Level one 3",
children: [
{
value: "3-1",
label: "Level two 3-1",
children: [
{
value: "3-1-1",
label: "Level three 3-1-1",
},
],
},
{
value: "3-2",
label: "Level two 3-2",
children: [
{
value: "3-2-1",
label: "Level three 3-2-1",
},
],
},
],
},
];
onMounted(() => {
console.log(demolist, "demolist");
console.log(toRaw(demolist));
// console.log(JSON.parse(JSON.stringify(demolist)));
});
</script>
<style scoped>
.mt_15 {
margin-top: 15px;
}
.node_css {
display: flex;
flex-direction: column;
}
</style>
3.vue3新增属性-setup使用俩种方式
3-1 第一种方式 标签以外写 setup 函数,需要显式导入 defineComponent,但上下文指向组件实例,可以使用传统的生命周期钩子和直接访问组件的属性和方法。
3-2 第二种方式 语法更简洁,但上下文不指向组件实例。
<script setup>
import {onMounted, ref} from 'vue';
const value=ref();
const showFlag=ref(false);
const handleClick=()=>{};
onMounted(()=>{
console.log(showFlag)
})
</script>
4.vue3已废除$set向对象中添加响应式的属性 以下是常用的集中方法
4-1 使用ES6属性 Reflect
<script setup>
import { ref, reactive, toRaw, onMounted } from "vue";
const demolist = reactive({
list: [
{
title: "一般",
// icon: h(Home),
name: "home",
value: "0",
},
{
title: "还好",
// icon: h(Category),
name: "category",
value: "0",
},
{
title: "很好",
// icon: h(Find),
name: "find",
value: "0",
},
{
title: "最爱",
// icon: h(Cart),
name: "cart",
value: "0",
},
{
title: "改进",
// icon: h(My),
name: "my",
value: "0",
},
],
});
const inpChange = () => {
for (var e = 0; e < toRaw(demolist.list).length; e++) {
Reflect.set(toRaw(demolist.list)[e], "index", e + 1);
}
console.log(toRaw(demolist), "demolist");
}
</script>
4-2 使用vue3响应式
<script setup>
import { ref, reactive, toRaw, onMounted } from "vue";
const demolist = reactive({
list: [
{
title: "一般",
// icon: h(Home),
name: "home",
value: "0",
},
{
title: "还好",
// icon: h(Category),
name: "category",
value: "0",
},
{
title: "很好",
// icon: h(Find),
name: "find",
value: "0",
},
{
title: "最爱",
// icon: h(Cart),
name: "cart",
value: "0",
},
{
title: "改进",
// icon: h(My),
name: "my",
value: "0",
},
],
});
const inpChange = () => {
for (var e = 0; e < toRaw(demolist.list).length; e++) {
toRaw(demolist.list)[e].index = e + 1;
}
console.log(toRaw(demolist), "demolist");
}
</script>
效果图如下:
4-3 上述俩种是有一定规律添加 如果是特定的添加 用以下这种方法
<script setup>
import { ref, reactive, toRaw, onMounted } from "vue";
const demolist = reactive({
list: [
{
title: "一般",
// icon: h(Home),
name: "home",
value: "0",
},
{
title: "还好",
// icon: h(Category),
name: "category",
value: "0",
},
{
title: "很好",
// icon: h(Find),
name: "find",
value: "0",
},
{
title: "最爱",
// icon: h(Cart),
name: "cart",
value: "0",
},
{
title: "改进",
// icon: h(My),
name: "my",
value: "0",
},
],
});
const inpChange = () => {
for (var e = 0; e < toRaw(demolist.list).length; e++) {
if (e % 2 == 0) {
console.log(toRaw(demolist.list[e]),"toRaw(demolist.list[e] %2===0";
toRaw(demolist.list)[e].index = e + 1;
} else {
console.log(toRaw(demolist.list[e]),"toRaw(demolist.list[e] %2!==0");
toRaw(demolist.list)[e].index = e + 2;
}
}
console.log(toRaw(demolist), "demolist");
}
</script>
效果图如下:
4-4 vue3写法归总 持续更新中......
1.获取输入框 下拉框的值 使用.value去拿
2.但是如果你这个属性是还包了一层 reactive 那么你就这样就代理了 打印出的值是包在了Proxy里
想要获取值有俩种方式:
第一种是vue自带的 toRaw(objectTarget)
第二种是序列化使用 JSON.parse(JSON.stringfy(objectTarget))
5.vue3七种传值方式
5-1 Props方式
父组件代码
<template>
<child-components :list="list"></child-components>
<div>
<input v-model="value" type="text" placeholder="请输入"/>
<button @click="handleAdd" type="button">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import ChildComponents from './child.vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value= ref('')
// add 触发后的事件处理函数
const handleAdd = () => list.value.push(value.value)
</script>
子组件代码(子组件只需要对父组件传递的值进行渲染即可)
<template>
<ul >
<li v-for="i in props.list" :key="i">{{ i }}</li>
</ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
list: {
type: Array,
default: () => [],
},
})
</script>
效果图如下:
5-2 emit方式 (emit方式也是Vue中最常见的组件通信方式,该方式用于子传父) 效果图如上所述 就不展示了
父组件 在父组件中只需要监听子组件自定义的事件,然后执行对应的添加操作。
<template>
<h8>我是父组件</h8>
<ul>
<li v-for="i in list" :key="i">{{ i }}</li>
</ul>
<child-components @add="handleAdd"></child-components>
</template>
<script setup>
import { ref } from "vue";
import ChildComponents from "./MainPage.vue";
const list = ref(["JavaScript", "HTML", "CSS"]);
// add 触发后的事件处理函数
const handleAdd = (value) => {
list.value.push(value);
};
</script>
子组件 在子组件中点击【添加】按钮后,emit一个自定义事件,并将添加的值作为参数传递。
<template>
<h8>我是子组件</h8>
<div>
<input v-model="value" type="text" placeholder="请输入" />
<button @click="handleSubmit" type="button">添加</button>
</div>
</template>
<script setup>
import { ref, defineEmits } from "vue";
const value = ref("");
const emits = defineEmits(["add"]);
const handleSubmit = () => {
emits("add", value.value);
value.value = "";
};
</script>
5-3 v-model 是vue3 比较出色的语法糖 将会着重讲
5-3-1 单独传值如下:
父组件
<template>
<h8>我是父组件</h8>
<ul>
<li v-for="i in list" :key="i">{{ i }}</li>
</ul>
<child-components v-model:list="list"></child-components>
</template>
<script setup>
import { ref } from "vue";
import ChildComponents from "./MainPage.vue";
const list = ref(["JavaScript", "HTML", "CSS"]);
</script>
子组件
<template>
<h8>我是子组件</h8>
<div>
<input v-model="value" type="text" placeholder="请输入" />
<button @click="handleAdd" type="button">添加</button>
</div>
</template>
<script setup>
import { ref, defineEmits, defineProps } from "vue";
const value = ref("");
const props = defineProps({
list: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(["update:list"]);
// 添加操作
const handleAdd = () => {
const arr = props.list;
arr.push(value.value);
emits("update:list", arr);
value.value = "";
};
</script>
5-3-2 多个传值情况写法如下:
特别需要注意俩点:
1.在父组件中 绑俩个v-model
<child-components v-model:list="list" v-model:listCopy='listCopy'></child-components>
2.在子组件中
const emits = defineEmits(["update:list","update:listCopy"]);
父组件
<template>
<h4>我是父组件</h4>
<ul>
<li v-for="i in list" :key="i">{{ i }}</li>
</ul>
<h4>我是父组件Copy</h4>
<ul>
<li v-for="i in listCopy" :key="i">{{ i }}</li>
</ul>
<child-components v-model:list="list" v-model:listCopy='listCopy'></child-components>
</template>
<script setup>
import { ref } from "vue";
import ChildComponents from "./MainPage.vue";
const list = ref(["JavaScript", "HTML", "CSS"]);
const list = ref(["JavaScriptCopy", "HTMLCopy", "CSSCopy"]);
</script>
子组件
<template>
<h4>我是子组件</h4>
<div>
<input v-model="value" type="text" placeholder="请输入" />
<button @click="handleAdd" type="button">添加</button>
</div>
<h4>我是子组件Copy</h4>
<div>
<input v-model="valueCopy" type="text" placeholder="请输入" />
<button @click="handleAddCopy" type="button">添加</button>
</div>
</template>
<script setup>
import { ref, defineEmits, defineProps } from "vue";
const value = ref("");
const valueCopy = ref("");
const props = defineProps({
list: {
type: Array,
default: () => [],
},
listCopy: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(["update:list","update:listCopy"]);
// 添加操作
const handleAdd = () => {
const arr = props.list;
arr.push(value.value);
emits("update:list", arr);
value.value = "";
};
const handleAddCopy = () => {
const arr = props.listCopy;
arr.push(valueCopy.value);
emits("update:listCopy", arr);
valueCopy.value = "";
};
</script>
5-4 refs
在使用选项式API时,我们可以通过this.$refs.name的方式获取指定元素或者组件,但是组合式API中就无法使用哪种方式获取。如果我们想要通过ref的方式获取组件或者元素,需要定义一个同名的Ref对象,在组件挂载后就可以访问了。
父组件
<template>
<ul>
<li v-for="i in childRefs?.list" :key="i">
{{ i }}
</li>
</ul>
<!-- 子组件 ref的值与<script>中的保持一致 -->
<child-components ref="childRefs"></child-components>
<!-- 父组件 -->
</template>
<script setup>
import { ref } from 'vue'
import ChildComponents from './MainPage.vue'
const childRefs = ref(null)
</script>
子组件
<template>
<div>
<input v-model="value" placeholder="请输入"/>
<button @click="handleAdd" type="button">添加</button>
</div>
</template>
<script setup>
import { ref, defineExpose } from 'vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value= ref('1')
// add触发后的事件处理函数
const handleAdd = () => {
list.value.push(value.value)
value.value = ''
}
defineExpose({ list })
</script>
5-5 provide/inject
provide和inject是Vue中提供的一对API,该API可以实现父组件向子组件传递数据,无论层级有 多深,都可以通过这对API实现。示例代码如下所示:
父组件
<template>
<!-- 子组件 -->
<child-components></child-components>
<!-- 父组件 -->
<div>
<input v-model="value" placeholder="请输入"/>
<button @click="handleAdd" type="button">添加</button>
</div>
</template>
<script setup>
import { ref, provide } from 'vue'
import ChildComponents from './MainPage.vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value= ref('')
// 向子组件提供数据
provide('list', list.value)
// add 触发后的事件处理函数
const handleAdd = () => {
list.value.push(value.value)
value.value = ''
}
</script>
子组件
<template>
<ul >
<li v-for="i in list" :key="i">{{ i }}</li>
</ul>
</template>
<script setup>
import { inject } from 'vue'
// 接受父组件提供的数据
const list = inject('list')
</script>
5-6 事件总线 结合外部第三方库来完成 官方推荐了俩种 mitt和tiny-emitter
我这里以mitt为例来说
5-6-1 首先安装mitt
npm install mitt
5-6-2 找到vue项目中的utils文件夹,新建一个bus.js,代码:
import mitt from "mitt";
const mitter = mitt();
export default mitter;
5-6-3 使用 我现在使用mitt进行兄弟组件之间的通信实现
父组件
<template>
<child1></child1>
<child2></child2>
</template>
<script setup>
import Child1 from "./MainPage.vue";
import Child2 from "./GoodsPage.vue";
</script>
子组件-child1
<template>
<div>child1<button @click="click">给child2 传值</button></div>
</template>
<script setup>
import emitter from "@/utils/bus";
function click() {
emitter.emit("child2Data", { name: "小米" });
}
</script>
子组件-child2
<template>
<div>child2---{{ str }}</div>
</template>
<script setup>
import emitter from "@/utils/bus";
import { onBeforeUnmount, ref } from "vue";
let str = ref();
emitter.on("child2Data", (data) => {
str.value = data.name;
});
onBeforeUnmount(() => {
emitter.off("child2Data"); //关闭
});
</script>
效果图如下:
6.后续会陆续补充:
6-1 创建vue3项目的时候一些选择
6-2 element-plus新增组件在实际项目中使用
6-3 vue3新增属性及生命周期及写法+element-plus 在实际项目中使用
持续更新中......