首页
留言
友情链接
Search
1
如何使用JavaScript获取和设置CSS root变量值
932 阅读
2
中国历史朝代顺序图
483 阅读
3
春和 《江海共余生》
400 阅读
4
清除浮动,单行多行超出用...
338 阅读
5
Centos7 下编译安装php8.2
310 阅读
分享
Web前端
html&css
javascript
Vue
shopify
shoplazza
后端
ThinkPHP
YII2
服务器端
软件安装
问题合集
历史
故事
诗词
生活
学习
其他
抖音
快手
小视频
随笔
易经
书摘
登录
/
注册
Search
标签搜索
诗词
sunshine
累计撰写
143
篇文章
累计收到
14
条评论
首页
栏目
分享
Web前端
html&css
javascript
Vue
shopify
shoplazza
后端
ThinkPHP
YII2
服务器端
软件安装
问题合集
历史
故事
诗词
生活
学习
其他
抖音
快手
小视频
随笔
易经
书摘
页面
留言
友情链接
搜索到
23
篇与
的结果
2022-12-23
Vue3 学习笔记(二)
02-组件的概念及组件的基本使用方式03-组件之间是如何进行互相通信的04-组件的属性与事件是如何进行处理的05-组件的内容是如何组合与分发处理的06-仿Element Plus框架的el-button按钮组件实现07-单文件组件SFC及Vue CLI脚手架的安装使用08-脚手架原理之webpack处理html文件和模块打包09-脚手架原理之webpack启动服务器和处理sourcemap10-脚手架原理之webpack处理样式模块和图片模块11-脚手架原理之webpack处理单文件组件及loader转换12-Vite3介绍及基本使用13-仿Element Plus的el-rate评分组件实现(单文件组件)官网地址:https://cn.vuejs.org/Vue.js文件下载地址下载地址:https://unpkg.com/vue@3.2.36/dist/vue.global.js组件的概念及组件的基本使用方式组件的概念组件是带有名称的可复用实例,通常一个应用会以一棵嵌套的组件树的形式来组织,比如:页头、侧边栏、内容区等组件。 vue组件 组件可以拥有自己独立的结构,样式,逻辑。这样对于后期的维护是非常方便的。下面给出评分组件与按钮组件的抽离过程。 组件的划分 组件的命名方式与规范定义组件可通过驼峰、短线两种风格定义调用组件推荐短线方式<div id="app"> <my-head></my-head> </div> <script> let app = Vue.createApp({ data(){ return { } } }) app.component('my-head', { template: ` <header> <div>{{ message }}</div> <h2>logo</h2> <ul> <li>首页</li> <li>视频</li> <li>音乐</li> </ul> </header>`, data(){ return { message: 'hello world' } } }); let vm = app.mount('#app'); </script>根组件app容器可以看成根组件,所以根组件跟普通组件都具备相同的配置信息,例如:data、computed、methods等等选项。<div id="app"> <my-head></my-head> </div> <script> // 根组件 let RootApp = { data(){ return { } } }; // MyHead组件 let MyHead = { template: ` <header> <div>{{ message }}</div> <h2>logo</h2> <ul> <li>首页</li> <li>视频</li> <li>音乐</li> </ul> </header> ` }; let app = Vue.createApp(RootApp) app.component('MyHead', MyHead); let vm = app.mount('#app'); </script>根组件与MyHead组件形成了父子组件。局部组件与全局组件局部组件只能在指定的组件内进行使用,而全局组件可以在容器app下的任意位置进行使用。组件之间是如何进行互相通信的上一个小节中,我们了解了组件是可以组合的,那么就形成了父子组件,父子组件之间是可以进行通信的, 那么为什么要通信呢?主要是为了让组件满足不同的需求。 组件之间差异化 父子通信最常见的通信方式就是父传子,或者子传父,那么父传子通过props实现,而子传父则通过emits自定义事件实现。 父子通信 <div id="app"> <my-head :count="count" @custom-click="handleClick"></my-head> </div> <script> let app = Vue.createApp({ data(){ return { count: 10 } }, methods: { handleClick(data){ console.log(data); } } }) app.component('MyHead', { props: ['count'], emits: ['custom-click'], template: ` <header> <div>{{ count }}</div> <h2>logo</h2> <ul> <li>首页</li> <li>视频</li> <li>音乐</li> </ul> </header>`, mouted(){ this.$emit('custom-click', 'MyHead Data') } }); let vm = app.mount('#app'); </script>父子通信需要注意的点组件通信的props是可以定义类型的,在运行期间会进行检测组件之间的数据是单向流动的,子组件不能直接修改传递过来的值但是有时候也需要数据的双向流动,可利用v-model来实现组件的属性与事件是如何进行处理的有时候组件上的属性或事件并不想进行组件通信,那么Vue是如何处理的呢?组件的属性与事件默认不通过props接收的话,属性会直接挂载到组件容器上,事件也是如此,会直接挂载到组件容器上。可通过 inheritAttrs 选项阻止这种行为,通过指定这个属性为false,可以避免组件属性和事件向容器传递。可通过 $attrs 内置语法,给指定元素传递属性和事件,代码如下:<div id="app"> <my-head title="hello world" class="box" @click="handleClick"></my-head> </div> <script> let app = Vue.createApp({ data(){ return { } }, methods: { handleClick(ev){ console.log(ev.currentTarget); } } }) app.component('MyHead', { template: ` <header> <h2 v-bind:title="$attrs.title">logo</h2> <ul v-bind:class="$attrs.class"> <li>首页</li> <li>视频</li> <li>音乐</li> </ul> </header> `, mounted(){ console.log( this.$attrs ); // 也可以完成父子通信操作 }, inheritAttrs: false // 阻止默认的属性传递到容器的操作 }); let vm = app.mount('#app'); </script>$attrs也可以实现组件之间的间接通信。组件的内容是如何组合与分发处理的在前面的小节中,我们学习了组件之间的通信,让组件之间实现了不同的需求,我们通过给组件添加不同的属性来实现。那么在Vue中如何去传递不同的组件结构呢?这就涉及到了组件内容的分发处理。插槽slot在Vue中是通过插槽slot方式来进行分发处理的,Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 元素作为承载分发内容的出口。<div id="app"> <my-head> <p>logo</p> </my-head> </div> <script> let app = Vue.createApp({ data(){ return { message: 'hello' } } }) app.component('MyHead', { data(){ return { }; }, template: ` <header> <slot></slot> </header>`, }); let vm = app.mount('#app'); </script>组件内的结构,即<p>logo</p>会被分发到<slot></slot>所在的区域。内容分发与插槽的注意点渲染作用域 -> 插槽只能获取当前组件的作用域具名插槽 -> 处理多个插槽的需求,通过v-slot指令实现,简写为#作用域插槽 -> 希望插槽能访问子组件的数据完整代码如下:<div id="app"> <my-head> <template #title> <p>logo, {{ message }}, {{ count }}</p> </template> <template #list="{ list }"> <ul> <li v-for="item in list">{{ item }}</li> </ul> </template> </my-head> </div> <script> let app = Vue.createApp({ data(){ return { message: 'hello' } } }) app.component('MyHead', { data(){ return { count: 123, list: ['首页', '视频', '音乐'] }; }, template: ` <header> <slot name="title"></slot> <hr> <slot name="list" :list="list"></slot> </header> `, }); let vm = app.mount('#app'); </script>单文件组件SFC及Vue CLI脚手架的安装使用Vue 单文件组件(又名 *.vue 文件,缩写为 SFC)是一种特殊的文件格式,它允许将 Vue 组件的模板、逻辑 与 样式封装在单个文件中。为什么要使用 SFC使用 SFC 必须使用构建工具,但作为回报带来了以下优点:使用熟悉的 HTML、CSS 和 JavaScript 语法编写模块化的组件让本来就强相关的关注点自然内聚预编译模板,避免运行时的编译开销组件作用域的 CSS在使用组合式 API 时语法更简单通过交叉分析模板和逻辑代码能进行更多编译时优化更好的 IDE 支持,提供自动补全和对模板中表达式的类型检查开箱即用的模块热更新 (HMR) 支持如何支持SFC可通过项目脚手架来进行支持,Vue支持Vite脚手架和Vue CLI脚手架。这里我们先来介绍Vue CLI的基本使用方式。# 安装 npm install -g @vue/cli # 创建项目 vue create vue-study # 选择default default (babel, eslint) # 启动脚手架 npm run serve通过localhost:8080进行访问。脚手架文件的组成src/main.js -> 主入口模块src/App.vue -> 根组件src/components -> 组件集合src/assets -> 静态资源单文件的代码组成template -> 编写结构script -> 编写逻辑style -> 编写样式 单文件组件 其中style中的scoped属性,可以让样式成为局部的,不会影响到其他组件,只会作用于当前组件生效,同时在脚手架下支持常见的文件进行模块化操作,例如:图片、样式、.vue文件等。
2022年12月23日
131 阅读
0 评论
0 点赞
2022-12-23
Vue3学习笔记(一)
03-选项式API的编程风格与优势04-声明式渲染及响应式数据实现原理05-指令系统与事件方法及传参处理06-计算属性与侦听器区别与原理(一)06-计算属性与侦听器区别与原理(二)07-条件渲染与列表渲染及注意点08-class样式与style样式的三种形态09-表单处理与双向数据绑定原理10-生命周期钩子函数及原理分析11-搜索关键词加筛选条件的综合案例选项式API的编程风格与优势选项式API,即:options APIlet vm = createApp({ methods: {}, computed: {}, watch: {}, data(){}, mounted(){} })这种写法的优势:只有一个参数,不会出现参数顺序的问题,随意调整配置的位置非常清晰,语法化特别强非常适合添加默认值的声明式渲染及响应式数据实现原理Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:<div id="counter"> Counter: {{ counter }} </div>const Counter = { data() { return { counter: 0 } } } Vue.createApp(Counter).mount('#counter')声明式编程:不需要编写具体是如何实现的,直接调用声明就可以实现功能。SQL就是比较经典的声明式语言:SELECT * from user WHERE username = xiaomingfor(var i=0;i<user.length;i++) { if(user[i].username == "xiaoming") { print("find"); break; } }注意:数据是通过 {{ }} 模板语法来完成的,模板语法支持编写JS表达式响应式数据实现的原理:利用JS的Proxy对象。Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,其实就是直接监控值的修改,当值发生改变的时候,可以监控到。<div id="app"></div> <script> let data = new Proxy( { message: "hello", }, { get(target) { console.log("get") return target.message }, set(target, key, value) { console.log("set") app.innerHTML = value; }, } ) app.innerHTML = data.message; setTimeout(() => { data.message = "hi" }, 2000) </script>指令系统与事件方法及传参处理指令系统就是通过自定义属性实现的一套功能,也是声明式编程的体现。通常在标签上添加 v-* 字样,常见的指令有:v-bind -> 操作标签属性,可通过 : 简写v-on -> 操作事件,可通过 @ 简写<div id="app"> <p :title="message">这是一个段落</p> <button @click=" message = 'hi' ">点击</button> </div> {{ message }} <script> let vm = Vue.createApp({ data(){ return { message: 'hello' } } }).mount('#app') </script>如何添加事件方法,通过methods选项API实现,并且Vue框架已经帮我们帮事件传参机制处理好了。<div id="app"> <button @click="toClick($event, 123)">点击</button> </div> <script> let vm = Vue.createApp({ methods: { toClick(ev, num){ } } }).mount('#app') </script>计算属性与侦听器区别与原理计算属性模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,所以过于复杂的逻辑可以移植到计算属性中进行处理。<div id="app"> {{ reverseMessage }} </div> <script> let vm = Vue.createApp({ data(){ return { message: 'hello' } }, computed: { reverseMessage(){ return this.message.split('').reverse().join('') } } }).mount('#app') </script>计算属性与方法比较像,如下所示:<div id="app"> {{ reverseMessageMethod() }}<br> {{ reverseMessageMethod() }}<br> {{ reverseMessage }}<br> {{ reverseMessage }}<br> </div> <script> let vm = Vue.createApp({ data(){ return { message: 'hello world' } }, methods: { reverseMessageMethod(){ console.log(1); return this.message.split(' ').reverse().join(' '); } }, computed: { reverseMessage(){ console.log(2); return this.message.split(' ').reverse().join(' '); } } }).mount('#app'); </script>计算属性跟方法相比,具备缓存的能力,而方法不具备缓存,所以上面代码执行完,会弹出两次1和一次2。注意:默认是只读的,一般不会直接更改计算属性,如果想更改也是可以做到的,通过Setter写法实现,官方地址。既然计算属性编写的是一个函数,而调用的时候以函数名的形式进行使用,其实实现起来也不是特别难的事情:let computed = { num(){ return 123; } } let vm = {} for(let attr in computed){ Object.defineProperty(vm, attr, { value: computed[attr]() }) }侦听器虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。侦听器的目的:侦听器用来观察和响应Vue实例上的数据变动,类似于临听机制+事件机制。当有一些数据需要随着其它数据变化而变化时,就可以使用侦听器。<div id="app"> {{ message }} </div> <script> let vm = Vue.createApp({ data(){ return { message: 'hello' } }, watch: { message(newVal, oldVal){ } } }).mount('#app') </script>有时候,计算属性 和 侦听器 往往能实现同样的需求,那么他们有何区别呢?计算属性适合:多个值去影响一个值的应用;而侦听器适合:一个值去影响多个值的应用侦听器支持异步的程序,而计算属性不支持异步的程序class样式与style样式的三种形态操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。字符串数组对象let vm = Vue.createApp({ data() { return { myClass1: 'box box2', myClass2: ['box', 'box2'], myClass3: { box: true, box2: true }, myStyle1: 'background: red; color: white;', myStyle2: ['background: red', 'color: white'], myStyle3: { background: 'red', color: 'white' }, } }, }).mount("#app")数组和对象的形式要比字符串形式更加的灵活,也更容易控制变化。表单处理与双向数据绑定原理表单是开发过程中经常要进行操作的,一般需要收集表单数据,发送给后端,或者把后端的数据进行回显等。在Vue中是通过v-model指令来操作表单的,可以非常灵活的实现响应式数据的处理。<div id="app"> <input type="text" v-model="message"> {{ message }} </div> <script> let vm = Vue.createApp({ data() { return { message: 'hello' } } }).mount("#app") </script>尽管有些神奇,但 v-model 本质上不过是语法糖。可通过value属性 + input事件来实现同样的效果。<div id="app"> <input type="text" :value="message" @input="message = $event.target.value"> {{ message }} </div> <script> let vm = Vue.createApp({ data() { return { message: 'hello' } } }).mount("#app") </script>v-model除了可以处理输入框以外,也可以用在单选框、复选框、以及下拉菜单中。<div id="app"> <input type="checkbox" v-model="fruits" value="苹果">苹果<br> <input type="checkbox" v-model="fruits" value="西瓜">西瓜<br> <input type="checkbox" v-model="fruits" value="哈密瓜">哈密瓜<br> {{ fruits } <input type="radio" v-model="gender" value="女">女<br> <input type="radio" v-model="gender" value="男">男<br> {{ gender }} <select v-model="city"> <option value="北京">北京</option> <option value="上海">上海</option> <option value="杭州">杭州</option> </select> {{ city }} </div> <script> let vm = Vue.createApp({ data(){ return { fruits: ['西瓜', '哈密瓜'], gender: '男', city: '杭州' } } }).mount('#app'); </script>生命周期钩子函数及原理分析每个组件在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。就是工厂的流水线,每个工人站在各自的岗位,当任务流转到工人身边的时候,工人就开始工作。简单来说生命周期钩子函数就是回调函数,在Vue的某个时机去调用对应的回调函数。就像定时器一样,谁调用的定时器的回调函数呢?其实就是定时器内部在调用的。setTimeout(()=>{ console.log('2秒后被执行了'); }, 2000)官方提供的生命周期图示生命周期可划分为三个部分:初始阶段:beforeCreate、created、beforeMount、mounted更新阶段:beforeUpdate、updated销毁阶段:beforeUnmout、unmounted注:一般在,created,mounted中都可以发送数据请求,但是,大部分时候,会在created发送请求。因为这样可以更短的时间去响应数据。搜索关键词加筛选条件的综合案例准备好案例的JSON数据[ { "id": 1, "name": "小明", "gender": "女", "age": 20 }, { "id": 2, "name": "小强", "gender": "男", "age": 18 }, { "id": 3, "name": "大白", "gender": "女", "age": 25 }, { "id": 4, "name": "大红", "gender": "男", "age": 22 } ]参考代码<style> .active-gender{ background: red; } </style> <div id="app"> <input type="text" v-model="message"> <button :class="activeGender('全部')" @click="handleGender('全部')">全部</button> <button :class="activeGender('男')" @click="handleGender('男')">男</button> <button :class="activeGender('女')" @click="handleGender('女')">女</button> <ul> <li v-for="item in filterList" :key="item.id">{{ item.name }}, {{ item.gender }}, {{ item.age }}</li> </ul> </div> <script> let vm = Vue.createApp({ data() { return { list: [], message: '', gender: '全部' } }, created(){ fetch('./02-data.json').then((res)=> res.json()).then((res)=>{ this.list = res; }) }, computed: { filterList(){ return this.list .filter((v)=> v.name.includes(this.message)) .filter((v)=> v.gender === this.gender || '全部' === this.gender); } }, methods: { activeGender(gender){ return { 'active-gender': this.gender === gender }; }, handleGender(gender){ this.gender = gender; } } }).mount('#app'); </script>总结内容了解核心思想,例如:MVVM设计模式、选项式API优势了解Vue3各个选项的用法,例如:data、methods、computed等掌握常见的指令:v-bind、v-on、v-if、v-for等掌握样式操作、表单操作等行为了解Vue3的生命周期钩子函数,及如何使用
2022年12月23日
42 阅读
0 评论
1 点赞
2022-11-10
Vue3学习笔记
Vue3全家桶:Vue3,Composition API,Options API,Element Plus,Vue Router,Vue CLI,Vuex,Pinia,ViteVue3核心知识点:MVVM设计模式、响应式数据实现原理、指令系统、计算属性与侦听器、条件渲染与列表渲染、class样式与style样式的三种形态、表单处理、生命周期钩子函数、组件通信、组件属性与事件、组件内容分发、脚手架使用及原理实现、ref属性在元素和组件上、nextTick监听DOM、自定义指令及应用场景、组件功能之Mixin混入、插件的概念及插件的实现、动态组件与keep-alive组件缓存、transition动画与过渡的实现、异步组件与Suspense, Provide_Inject、Teleport、虚拟DOM与render函数及Diff算法、setup方法与script_setup及ref响应式、reactive,toRefs, watchEffect, defineProps...TypeScript与框架结合Vue组合式+TS,状态管理+TSVue选项式+TS,组件库+TSReact类组件+TS,Axios+TSReact函数组件+TS,路由+TSTypeScript核心知识点类型声明空间与变量声明空间、类型注解与类型推断、类型分类与联合类型与交叉类型、never类型与any类型与unknown类型、类型断言与非空断言、数组类型与元祖类型、对象类型与索引签名、函数类型与void类型、函数重载与可调用注解、枚举类型与const枚举、详解接口与类型别名之间区别、字面量类型和keyof关键字、类型保护与自定义类型保护、定义泛型和泛型常见操作、类型兼容性详解、映射类型与内置工具类型、条件类型和infer关键字、类中如何使用类型、模块系统与命名空间、d.ts声明文件和declare关键字、@types和DefinitelyTyped仓库、lib.d.ts和global.d.ts、tsconfig.json...MVC设计模式与MVVM设计模式选项式API的编程风格与优势指令系统与事件方法及传参处理声明式宣染及响应式数据实现原理计算属性与侦听器区别与原理条件渲染与列表宣染及注意点class样式与style样式的三种形态表单处理与双向数据绑定原理生命周期钩子函数及原理分析MVC设计模式与MVVM设计模式为什么使用Vue框架?◆最大的优点:就是不用自己完成复杂的DOM操作了,而由框架帮我们去完成选项式API的编程风格与优势:let vm = createApp( /* 选项*/ methods: {}, computed: {}, watch:{}, data(){}, mounted(){} }).mount(' #app');💠只有一个参数,不会出现参数顺序的问题,随意调整配置的位置 💠 非常清晰,语法化特别强 💠 非常适合添加默认值的声明式宣染及响应式数据实现原理💠利用ES6的Proxy对象对底层进行了监控计算属性与侦听器区别与原理🔸计算属性适合: 多个值去影响一个值的应用;而侦听器适合一个值去影响多个值的应用🔸侦听器支持异步的程序,而计算属性不支持异步的程序🔷 条件渲染:使用v-if指令条件性地宣染一块内容。这块内容只会在指令的表达式返回truthy真值的时候被渲染🔷 falsy假值 (即 false,0,-0, On, "“,null, undefined和NaN)条件宣染与列表渲染及注意点:列表宣染需要添加key属性 -> 用来跟踪列表的身份v-if和v-for尽量不要一起使用 -> 利用计算属性来完成这类功能template标签起到的作用 -> 形成一个整体容器并且不会被宣染<div id="app"> <!-- <input- type="text" - v-model="message">--> <input type="text" :value="message" @input="message = $event.target.value"> </div>
2022年11月10日
10 阅读
0 评论
1 点赞
1
2
3