每周总结|每周总结 20210801 vue文档学习

vue学习 箭头函数

function() => {}

js位置 JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到中;
可以在同一个页面中引入多个.js文件,还可以在页面中多次编写,浏览器按照顺序依次执行。
由于浏览器的安全限制,以file://开头的地址无法执行如联网等JavaScript代码,最终,你还是需要架设一个Web服务器,然后以http://开头的地址来正常执行所有JavaScript代码。
js分号 JavaScript并不强制要求在每个语句的结尾加;
数字判断 唯一能判断NaN的方法是通过isNaN()函数
要特别注意相等运算符==。JavaScript在设计时,有两种比较运算符:
第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。
这不是JavaScript的设计缺陷。浮点数在运算过程中会产生误差,因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true

动态语言与静态语言 变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。
动态参数
...

eventName的值为"focus"时,v-on:[eventName]将等价于v-on:focus
v-bind v-bind:属性,单向绑定?
v-on 事件监听,v-on:click="",简写@click=""
2.6.0新增动态参数,可以根据条件响应不同的事件
需要注意的是,动态表达式中更不要有引号和空格,因为对于html的attribute名来说这些符号无效,同时浏览器会将attribute名转为小写,所以也不要有大写字符

防抖与节流 有些函数如mousemove触发的函数会在短时间内连续调用多次,如果要使其在一段事件内只执行一次函数,就需要防抖与节流.
防抖:每隔一段事件才触发一次
节流:连续触发后,每隔一段时间才处理一次
//防抖 function debounce(fn, wait) { let timeout = null return function() { if(timeout !== null) clearTimeout(timeout) timeout = setTimeout(fn, wait); } } function handle() { console.log(Math.random()) } window.addEventListener('scroll', debounce(handle, 1000))

计算属性 一般来说,模板要求简单的、声明性的,如{{label}},但是有时会过于复杂如:
{{ author.books.length > 0 ? 'Yes' : 'No' }}

虽然代码可以工作,但是过于复杂,推荐使用计算属性来声明
{{ publishedBooksMessage }}

computed: { // 计算属性的 getter publishedBooksMessage() { // `this` points to the vm instance return this.author.books.length > 0 ? 'Yes' : 'No' } }

计算属性与方法比较:计算属性在响应式依赖改变时才会重新求值,而函数在每次调用时都会重新执行
{{ countBooks1() }} {{ countBools2 }}

methods:{ countBooks1() { return books.length } }, computed:{ countBooks2() { return books.length } }

计算属性可以设置setter和getter
computed: { fullName: { // getter get() { return this.firstName + ' ' + this.lastName }, // setter set(newValue) { const names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } }

侦听器watch 可以在响应式数据变化的时候执行函数,相比于计算属性,watch可以执行异步操作如访问api,但是开销比计算属性大
watch: { // whenever question changes, this function will run question(newQuestion, oldQuestion) { if (newQuestion.indexOf('?') > -1) { this.getAnswer() } } }

truthiness真值 在js中,除了false0""nullundefinedNaN之外都为真值。
if (true) if ({}) if ([]) if (42) if ("foo") if (new Date()) if (-42) if (3.14) if (-3.14) if (Infinity) if (-Infinity)

:class :class="{ active: isActive }"class为isActive值,当isActivenul时,没有class。
此外,:class可以与class属性共存,:class内也可以有多个值,或者使用数组来提供class

data() { return { activeClass: 'active', errorClass: 'text-danger' } }

:style语法 :style的对象语法十分直观——看着非常像CSS,但其实是一个JavaScript对象。CSS property名可以用驼峰式(camelCase)或短横线分隔(kebab-case,记得用引号括起来)来命名
条件渲染 条件渲染有两种:v-ifv-show
v-if只有在条件为真时才渲染条件快,可以和v-else-ifv-else配合使用。
v-show总是会被渲染,真假值变化体现为css的变化
v-for 可以来对应数组,也可以对应对象。
对应数组时,两个参数依次分别表示值和索引;
对应对象时,三个参数依次分别表示值、键和索引。
  • {{ parentMessage }} - {{ index }} - {{ item.message }}

  • {{ index }}. {{ name }}: {{ value }}

  • 当v-for对应的数据中的数据项改变了顺序,vue不会移动DOM元素来匹配数据,而是使用“就地更新”的策略,如果想要对应的DOM元素改变位置,需要添加:key属性
    数组更新检测 数组变更
    以下函数可以触发视图更新
    • push()
    • pop()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()
      数组替换
      以下函数可以保留原来数组,且返回新的数组
    • filter()
    • concat()
    • slice()
    显示过滤、排序数组 可以在v-for中使用计算属性或者方法
    在组件上使用v-for 因为组件自己独立的作用域,所以在定义组件的时候要使用props来传递参数。

    const app = Vue.createApp({ data() { return { newTodoText: '', todos: [ { id: 1, title: 'Do the dishes' }, { id: 2, title: 'Take out the trash' }, { id: 3, title: 'Mow the lawn' } ], nextTodoId: 4 } }, methods: { addNewTodo() { this.todos.push({ id: this.nextTodoId++, title: this.newTodoText }) this.newTodoText = '' } } })app.component('todo-item', { template: `
  • {{ title }}
  • `, props: ['title'] })app.mount('#todo-list-example')

    事件处理 若在事件处理中要访问原始的DOM事件,可以用特殊变量$event传入方法

    warn(message, event) { if (event) { event.preventDefault() } }

    一个事件可以有多个方法处理,方法间使用逗号分隔

    event.preventDefault() 与 event.stopPropagation() event.preventDefault()阻止事件的默认动作发送,比如点击勾选框不能切换勾选状态、在input框输入非规定内的字符就无法输入等等。
    event.stopPropagation()仍会执行默认动作,但是执行完后事件不再被分派到其他节点。
    js冒泡与捕获 首先我们需要形成监听器的思想。在不使用任何框架的情况下,我们在js中通过addEventListener方法给Dom添加事件监听。这个方法直译就是添加事件监听器。我们对Dom的操作作为事件会从最外面的祖先Dom逐步传递到目标Dom(捕获过程),然后再从目标的Dom原路传出去(冒泡过程)。通常我们只监听冒泡过程。在vue中,当我们添加了事件修饰符capture后,才会变成捕获监听器。
    所以vue中的.stop修饰符的停止传播就容易理解了,一般来说在冒泡监听时,是有内层的子DOM开始到外层的祖先DOM,设置了.stop后,在本DOM处理事件后,事件便不再冒泡。
    .self可以理解为跳过冒泡事件和捕获事件,只有直接作用在该元素上的事件才可以执行。
    事件修饰符
    • .stop 执行事件后停止传播
    • .prevent 不执行默认动作,相当于执行event.preventDefault()
    • .capture 由冒泡监听改为捕获监听
    • .self 跳过冒泡事件和捕获事件,只有直接作用在该元素上的事件才可以执行
    • .once 只执行一次
    • .passive 不会执行event.preventDefault()
    按键修饰符 使用@监听键盘事件

    • .enter
    • .tab
    • .delete (捕获“删除”和“退格”键)
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right
    修饰键 修饰键与常规按键不同,只有在按住修饰键的情况下释放其它按键,才能触发事件。而单单释放修饰键也不会触发事件。
    Do something

    键盘修饰键
    • .ctrl
    • .alt
    • .shift
    • .meta
    鼠标修饰键
    • .left
    • .right
    • .middle
    .exact 修饰符
    .exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。

    v-model 对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值)
    v-model有三种修饰符
    • .lazy 在“change”时而非“input”时更新
    • .number 将用户的输入值转为数值类型,如果这个值无法被 parseFloat() 解析,则会返回原始的值
    • .trim 自动过滤用户输入的首尾空白字符
    组件基础 因为组件是可复用的组件实例,所以它们与new Vue接收相同的选项,例如datacomputedwatchmethods以及生命周期钩子等。通过component可以进行全局注册。
    // 定义一个名为 button-counter 的新全局组件 app.component('button-counter', { data() { return { count: 0 } }, template: ` ` })

    prop
    通过prop定义属性并向子组件传递数据
    const app = Vue.createApp({})app.component('blog-post', { props: ['title'], template: `{{ title }}` })app.mount('#blog-post-demo')

    监听子组件事件
    通过使用$emit来传入外部的事件名称,也可以将内部参数传出。

    app.component('blog-post', { props: ['title'], template: `{{ title }} ` })

    实现组件的v-model双向绑定
    为了在组件中可以使用v-model,组件需要向外暴露出一个接受的prop,并且向内规定该数据的gettersettergettersetter可以通过计算属性实现。

    app.component('custom-input', { props: ['modelValue'], template: ` `, computed: { value: { get() { return this.modelValue }, set(value) { this.$emit('update:modelValue', value) } } } })

    简单插槽
    组件中在需要插入的位置使用标签,在使用组件时直接用组件名标签包裹。
    Something bad happened.

    app.component('alert-box', { template: `Error!` })

    动态加载组件
    使用属性:is可以地将简单组件载入到该位置。

    const tabs = [ { name: 'Home', component: { template: `Home component` } }, { name: 'Posts', component: { template: `Posts component` } }, { name: 'Archive', component: { template: `Archive component` } } ]const app = Vue.createApp({ data() { return { tabs, currentTab: tabs[0] } }, computed: { currentTabComponent() { return 'tab-' + this.currentTab.toLowerCase() } } })app.component('tab-home', { template: `Home component` }) app.component('tab-posts', { template: `Posts component` }) app.component('tab-archive', { template: `Archive component` })app.mount('#dynamic-component-demo')

    特殊DOM解析注意事项
    形如
      等等这些标签对于哪些子标签可以出现在其内部是由严格规定的(比如
    可以出现在
    中)。而有些标签如
  • 等只能出现在特定的元素内部。如果在这些特定标签内部使用自定义的组件,可能会导致出错。此时可以使用v-is属性来帮助解析组件。

    深入组件 组件命名
    建议使用kebab-case (短横线分隔命名)
    局部注册
    局部注册需要引用
    import ComponentA from './ComponentA.vue'export default { components: { ComponentA } // ... }

    prop类型
    prop可以设置类型,在设置错误时会在控制台提示用户。
    props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // 或任何其他构造函数 }

    动态传入Prop
    在传入值时,由两种方式:

    静态赋值vue会视为一个字符串,而v-bind或缩写:告诉vue这是一个js表达式。
    特别地,当一个对象的所有属性都需要传入时,可以使用不带参数的v-bind
    post: { id: 1, title: 'My Journey with Vue' }


    单向数据流
    我们已经知道,prop中定义外部传入的数据。如果我们希望这些数据成为本地数据,可以供子组件使用,并且在数据更新时,子组件也会更新,与此同时反过来不行(会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解)的话,可以将定义在prop中的属性定义为一个data property或者计算属性。
    // 定义为data props: ['initialCounter'], data() { return { counter: this.initialCounter } }

    // 定义为计算属性 props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }

    prop数据验证
    可以定义数据类型、指定默认值和自定义验证规则。
    app.component('my-component', { props: { // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function() { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function(value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } }, // 具有默认值的函数 propG: { type: Function, // 与对象或数组默认值不同,这不是一个工厂函数 —— 这是一个用作默认值的函数 default: function() { return 'Default function' } } } })

    非Prop的Attribute继承
    非Prop的Attribute,指的是不定义在prop中的属性,如classidstyle等等。在外部使用组件时并使用这些属性时,默认会继承给组件内部的根元素;如果根元素有多个或者想要继承到非根元素,可以使用v-bind="$attrs"$attrs包括组件propsemits property中未包含的所有属性 (例如classstylev-on监听器等)。)来选定一个DOM元素继承。
    事件监听器的继承也同理,会默认继承到组件内部根元素。

    需要注意的是,如果要使非根节点继承,需要在组件的选项中设置inheritAttrs: false
    app.component('date-picker', { inheritAttrs: false, template: `` })


    自定义事件
    命名推荐使用kebab-case(短横线连接)的事件名,因为v-on事件监听器在DOM模板中会被自动转换为全小写。自定义事件可以和prop属性一样进行验证。
    app.component('custom-form', { emits: { // 没有验证 click: null,// 验证submit 事件 submit: ({ email, password }) => { if (email && password) { return true } else { console.warn('Invalid submit event payload!') return false } } }, methods: { submitForm() { this.$emit('submit', { email, password }) } } })

    v-model参数与多个v-model绑定
    在组件中,在prop中定义的属性,在外部可以用v-model:属性名的方式来进行多个v-model绑定。
    自定义v-model修饰符
    在组件中更可以自定义v-model修饰符。但是需要注意的是,修饰符的具体方法是写在属性的setter函数中,并且修饰符的名称为arg + "Modifiers"
    {{ myText }}

    const app = Vue.createApp({ data() { return { myText: '' } } })app.component('my-component', { props: { name: String, nameModifiers: { default: () => ({}) } }, methods: { emitValue(e) { let value = https://www.it610.com/article/e.target.value if (this.modelModifiers.capitalize) { value = value.charAt(0).toUpperCase() + value.slice(1) } this.$emit('update:name', value) } }, template: `` })app.mount('#app')

    插槽
    在组件的模板中可以定义标签,可以替换为字符串、html代码或其他组件。当标签中间有内容时,这部分内容会作为默认。

    具名插槽 在需要多个插槽的情况下,为了识别不同的插槽,需要给每一个插槽一个名字name,不带name的插槽会有一个隐含的名字“default”。在外部使用组件的具名插槽的时候,使用