当前位置: 首页 > news >正文

深入vue2[更新中]

frontend

Vue2

学习内容参考 /在线运行

Element

学习内容参考 /视频教学

vue2

1. vue 实例

  1. 当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中

  2. 但是当使用Object.freeze(),会阻止修改现有的 property,也意味着响应系统无法再追踪变化。

var obj = {foo: 'bar'
}
​
Object.freeze(obj)
​
new Vue({el: '#app',data: obj
})

  1. 不要在选项 property 或回调上使用箭头函数,因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

2. 模板语法

  1. render: 如果熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,也可以不用模板,直接写渲染 (render) 函数,使用可选的 JSX 语法。

  2. 在站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。因为如果用户输入内容包含恶意脚本,这些脚本会被执行,并且直接解析并渲染 HTML 内容。而{{ }}会被转义为纯文本,会更安全。

  3. js模板表达式 模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date 。不应该在模板表达式中试图访问用户定义的全局变量。

3. v-指令

  1. 指令支持动态参数

  2. 不推荐同时使用 v-if 和 v-for。因为当它们一起使用时,v-if 会优先于 v-for 被处理,这可能会导致一些意外的行为和性能问题。可以使用计算属性进行过滤, 也可以将 v-if 置于外层元素

  3. v-for 在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。如果你需要确保属性的遍历顺序是一致的, 可以使用map

  4. 替换数组: filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组

  5. 当ul标签使用v-for, 使用is渲染组件, is="todo-item" attribute。因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。这是因为这些结构有严格的子元素要求。例如,<ul> 元素只能包含 <li> 元素作为其直接子元素。查看 DOM 模板解析说明 来了解更多信息。

  6. 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

4. 组件

  1. 组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项

  2. 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝,否则可能影响到其他实例

  3. .prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。(差别在哪里?)

  4. is渲染组件,使用.vue,template 是不会有限制的

  5. HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名

    但是重申一次,如果你使用字符串模板,那么这个限制就不存在了。

  6. 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:

    场景: 网络请求res.data中的属性可能会被提示未定义

    props: ['initialCounter'],
    data: function () {return {counter: this.initialCounter}
    }

  7. prop 验证

    注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 datacomputed 等) 在 defaultvalidator 函数中是不可用的

  8. 组件可以接受任意的 attribute,从外部提供给组件的值会替换掉组件内部设置好的值。

  9. classstyle attribute 会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:form-control date-picker-theme-dark

  10. 若想要在一个组件的根元素上直接监听一个原生事件, Vue 提供了一个 $listeners property,包含了作用在这个组件上的所有监听器

    Vue.component('base-input', {inheritAttrs: false,props: ['label', 'value'],computed: {inputListeners: function () {var vm = this// `Object.assign` 将所有的对象合并为一个新对象return Object.assign({},// 我们从父级添加所有的监听器this.$listeners,// 然后我们添加自定义监听器,// 或覆写一些监听器的行为{// 这里确保组件配合 `v-model` 的工作input: function (event) {vm.$emit('input', event.target.value)}})}},template: `<label>{{ label }}<inputv-bind="$attrs"v-bind:value="value"v-on="inputListeners"></label>`
    })

  11. .sync 修饰符 处理组件之间的双向数据流 但vue3已移除

  12. 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

  13. 具名插槽 #

  14. 在每个 new Vue 实例的子组件中,其根实例可以通过 $root property 进行访问。

    // 获取根组件的数据 this.$root.foo

    但是中大型应用就要使用vuex了

  15. 类似的,$parent property 可以用来从一个子组件访问父组件的实例

    但是会失控,所以推荐依赖注入

  16. 目录树组件循环引用,可以使用webpack 的异步 import

5. 过渡

  • vue在插入,更新或者移除DOM时,提供多种不同方式的应用过渡效果,包括以下工具

    • css 过渡和动画

    • 第三方css动画库 Animate.css

    • js钩子函数

    • 第三方js动画库,如velocity.js

5.1 单元素/组件的过渡

  1. vue提供了transition的分装组件,为元素添加过度

    <div id="demo"><button v-on:click="show = !show">Toggle</button><transition name="fade"><p v-if="show">hello</p></transition>
    </div>
    ​
    <style>//元素从进入到离开 过程.fade-enter-active, .fade-leave-active{transition:opacity .5s;}//元素在刚开始进入和离开时 动作.fade-enter, .fade-leace-to{opacity: 0}
    </style>
    ​

5.1.1 过渡的类名

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

  3. v-enter-to2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

  6. v-leave-to2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移

5.1.2 自定义过度的类名

我们可以通过以下 attribute 来自定义过渡类名:

  • enter-class

  • enter-active-class

  • enter-to-class (2.1.8+)

  • leave-class

  • leave-active-class

  • leave-to-class (2.1.8+)

<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
​
<div id="example-3"><button @click="show = !show">Toggle render</button><transitionname="custom-classes-transition"enter-active-class="animated tada"leave-active-class="animated bounceOutRight"><p v-if="show">hello</p></transition>
</div>

5.2 初始渲染的过度

<transition appear><!-- ... -->
</transition>
5.2.1自定义css类名
<transitionappearappear-class="custom-appear-class"appear-to-class="custom-appear-to-class" (2.1.8+)appear-active-class="custom-appear-active-class"
><!-- ... -->
</transition>
5.2.2 自定义js钩子
<transitionappearv-on:before-appear="customBeforeAppearHook"v-on:appear="customAppearHook"v-on:after-appear="customAfterAppearHook"v-on:appear-cancelled="customAppearCancelledHook"
><!-- ... -->
</transition>

5.3 多个元素的过度

<transition><table v-if="items.length > 0"><!-- ... --></table><p v-else>Sorry, no items found.</p>
</transition>
5.3.1 过渡模式
  • in-out:新元素先进行过渡,完成之后当前元素过渡离开。

  • out-in:当前元素先进行过渡,完成之后新元素过渡进入。(常用)

    <transition name="fade" mode="out-in"><!-- ... the buttons ... -->
    </transition>

5.4 多个组件的过度

  • 使用动态组件

    <transition name="component-fade" mode="out-in"><component v-bind:is="view"></component>
    </transition>

5.5 列表过度

  • 使用transition-group

    <div id="list-demo" class="demo"><button v-on:click="add">Add</button><button v-on:click="remove">Remove</button><transition-group name="list" tag="p"><span v-for="item in items" v-bind:key="item" class="list-item">{{ item }}</span></transition-group>
    </div>

6. 可复用性&组合

6.1 JSX

7. 测试

  • Vue 组件通常包含 .vue 文件,里面包含模板、脚本和样式。这种单文件组件(SFC)格式并不是原生 JavaScript 或 TypeScript 能直接识别的。因此,vue-jest 使用 Babel 来将 .vue 文件转换为可被 Jest 识别的格式。

  • Jest 本身依赖 Babel 来处理 Vue 单文件组件及 ES 模块。babel-jest 可以帮你将非标准的 J

7.1 步骤

  • vue2

7.1.1 ts
  1. 安装jest

    npm install jest --save-dev
  2. 配置jest

    在根目录下创建jest.config.js

    module.exports = {moduleFileExtensions: ['js', 'vue'],moduleNameMapper: {'^@/(.*)$': '<rootDir>/src/$1'},transform: {'^.+\.js$': 'babel-jest','.*\.vue$': 'vue-jest'},snapshotSerializers: ['jest-serializer-vue'],// 在Vue单元测试中使用了v-model, 需要添加一下配置,请参考官方文档.// https://vue-test-utils.vuejs.org/guides/common-tips.html#mocking-components-that-use-v-model// setupFiles: ['<rootDir>/tests/unit/setup.js'],testMatch: ['<rootDir>/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'],testURL: 'http://localhost/'
    }
    • moduleFileExtensions 中包含了Vue文件,这是允许Vue文件被编译并测试的必要配置。

    • moduleNameMapper 是用来解析@符号的。

    • transform 配置了如何转换代码,vue-jest 转换.vue文件,babel-jest 转换.js文件。

    • snapshotSerializers 在snapshot test中使用,使快照测试更加容易。

    • testMatch 配置了测试文件的匹配规则。

    • testURL 配置了测试时浏览器的URL。

  3. 编写测试用例

    import { shallowMount } from '@vue/test-utils'
    import HelloWorld from '@/components/HelloWorld.vue'
    ​
    describe('HelloWorld.vue', () => {it('renders props.msg when passed', () => {const msg = 'new message'const wrapper = shallowMount(HelloWorld, {propsData: { msg }})expect(wrapper.text()).toMatch(msg)})
    })
  4. npm run jest 运行

7.1.2 babel
  1. 安装依赖

    npm install --save-dev jest @vue/test-utils babel-jest vue-jest
  1. 配置Jest

    • 在项目根目录添加jest.config.js

      module.exports = {preset: '@vue/cli-plugin-unit-jest',transform: {'^.+\\.vue$': 'vue-jest','^.+\\.js$': 'babel-jest',},moduleFileExtensions: ['js', 'vue'],testMatch: ['**/tests/**/*.spec.js'],
      };
      ​
 * 确保Jest能够识别和处理Vue组件以及js文件
  1. 创建测试文件

    • 放在test文件夹下,以.spec.js结尾

      //shallowMount 用于浅层挂载一个 Vue 组件,它只渲染组件的最外层,不会递归渲染子组件,适用于组件依赖的其他子组件较复杂时进行测试。
      import {shallowMount} from '@vue/test-utils';
      import HelloWorld from '@/components/HelloWorld.vue';
      //describe 用于组织和分组相关的测试,括号中的 'HelloWorld.vue' 作为测试套件的名称,指明我们要测试的目标是 HelloWorld.vue 组件。
      describe('HelloWorld.vue', () => {//it 函数用于定义一个测试用例,括号中的 'renders props.msg when passed' 是对测试的简短描述,意思是“当传递 msg 属性时,组件应该正确渲染出来”。it('renders props.msg when passed', () => {//我们将在测试中传递msg作为组件的 props,以测试它是否正确渲染出来。  const msg = 'Hello Jest';//shallowMount 用于浅层挂载 HelloWorld 组件。  //wrapper 是一个包装器对象,它包含了挂载后的组件实例,并提供了访问和操作组件的方法,比如获取 DOM 元素、触发事件等。  const wrapper = shallowMount(HelloWorld, {propsData: {msg}});//这一行是断言(assertion),它使用 Jest 的 expect 函数来验证测试结果。//wrapper.text() 获取组件的文本内容(包括组件的所有子元素)。//toMatch 用于检查文本是否包含指定的字符串 msg,即 'Hello Jest'。这个断言期望组件渲染的文本内容中包含传递的 msg。  expect(wrapper.text()).toMatch(msg);});
      });

7.2 报错

  • 由于未知原因,我的js项目竟然必须安装@types/jest,才可以正确引入jest,实在不知道为什么,先贴出来吧

  • yarn add --dev @types/jest

8. 规模化

8.1 路由

8.2 状态管理

  1. Redux 事实上无法感知视图层,所以它能够轻松的通过一些简单绑定和 Vue 一起使用

8.3 服务端渲染

9. 安全

  1. 用户提供的 URL 永远需要通过后端在入库之前进行过滤.需要对该 URL 进行“过滤”以防止通过 javascript: 来执行 JavaScript

  2. Vue 要在模板内避免渲染 style 标签,避免用户伪造样式,推荐在style属性中使用对象语法,提供特定property值

  3. 向后端提供 CSRF token 为每个表单生成一个唯一的随机令牌,并要求客户端在提交表单时也附带这个令牌。

深入响应式原理 vue最独特的特性之一

  1. Vue 遍历data中数据对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更

    这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。

    不能检测数组和对象的变化,,而Vue3中的proxy代理解决了这个问题

  2. 每个组件实例都对应一个 watcher

  3. windows事件直接赋给变量,不是响应式,需要在onMounted事件中进行监听

从头创建vue2 项目

1. 步骤

  1. 安装vue cli

    npm install -g @vue/cli
  2. 创建新项目

     vue create yhs-web
  3. 选择特性


http://www.mrgr.cn/news/54943.html

相关文章:

  • linux file结构体与inode结构体
  • android 与网页交互通过网页修改宿主布局和异常处理——未来之窗行业应用跨平台架构
  • SQL 自学:事务处理的COMMIT 和 ROLLBACK 语句的运用
  • MT1351-MT1360 码题集 (c 语言详解)
  • Qt中使用线程之QThread
  • PyMySQL连接MySQL和StarRocks查询表
  • 【JavaEE初阶】深入理解网络编程—使用UDP协议API实现回显服务器
  • [0xGame 2024] week2
  • Maple :一款强大的计算软件,广泛应用于数学、工程、物理和其他科学领域
  • OpneCV与dlib-换脸
  • 搭建LeNet-5神经网络,并搭建自己的图像分类训练和测试的模板,模板通用!!!均有详细注释。
  • SOD-YOLOv8 - 增强YOLOv8以在交通场景中检测小目标
  • 线程的同步
  • 二、Linux 入门教程:开启大数据领域的神奇之旅
  • 【Linux】从多线程同步到生产者消费者模型:多线程编程实践
  • Qml-Item的Id生效范围
  • Java集合剖析2】Java集合底层常用数据结构
  • 利士策分享,财富多少,才是恰到好处?
  • 推荐一款多功能理科计算器:Math Resource Studio Pro
  • WPF入门_03路由事件
  • 数据结构(C语言):顺序表
  • WPF 回到主线程
  • Egg.js 项目的合理 ESLint 配置文件模板
  • 锁的原理以及使用
  • 《知道做到》
  • 【MySQL核心面试题】MySQL 核心 - Explain 执行计划详解!