[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-9":3},{"id":4,"title":5,"title_en":6,"abstract":7,"abstract_en":8,"content":9,"content_en":10,"category":11,"banner_id":12,"banner_path":13,"tags":14,"is_recommend":16,"prev_article":17,"next_article":21,"created_at":25},9,"枫枫知道--Vue全系列课程","Maple Fengfeng knows - Vue full range of courses","# vue基本概述\n\nVue (读音 \u002Fvjuː\u002F，类似于 view) 是一套用于构建用户界面的渐进式框架。\n\nVue.js是一套构建用户界面的渐进式框架，采用自底向上增量开发的设计。Vue的核心库关注于视图（html），不仅易上手，还便于与第三方库或项目整合。\n\n渐进式：一步一步，不是将所有的东西都学完才能使用。\n\n自底向上设计：一种设计程序的过程和方法，就是先编写出基础程序段，然后在逐步扩大规范、补充和升级某些 功能，实际上是一种自底向上构造程序的过程。\n\nVue.js的核心是允许采用简洁式模板语法来声明的将数据渲染进DOM的系统\n\n在使用数据之前需要先进性声明才可以使用\n","\nVue (pronounced \u002Fvjuː\u002F, similar to view) is a set of progressive frameworks for building user interfaces.\n\nVue.js is a progressive framework for building user interfaces, designed with incremental development from the bottom up. Vue's core libraries focus on views (html), making them easy to use and integrate with third-party libraries or projects.\n\nProgressive: step by step, not learning everything before using it.\n\nBottom-up design: A process and method of designing a program, that is, first write the basic program segments, and then gradually expand the specification, supplement and upgrade certain functions, which is actually a process of constructing the program from the bottom up.\n\nAt the heart of Vue.js is a system that allows declarations using a concise template syntax to render data into the DOM\n\nA declaration of advancement is required before the data can be used\n","# vue基本概述\n\nVue (读音 \u002Fvjuː\u002F，类似于 view) 是一套用于构建用户界面的渐进式框架。\n\nVue.js是一套构建用户界面的渐进式框架，采用自底向上增量开发的设计。Vue的核心库关注于视图（html），不仅易上手，还便于与第三方库或项目整合。\n\n渐进式：一步一步，不是将所有的东西都学完才能使用。\n\n自底向上设计：一种设计程序的过程和方法，就是先编写出基础程序段，然后在逐步扩大规范、补充和升级某些 功能，实际上是一种自底向上构造程序的过程。\n\nVue.js的核心是允许采用简洁式模板语法来声明的将数据渲染进DOM的系统\n\n在使用数据之前需要先进性声明才可以使用\n\n### 为什么要学习Vue？\n\n简单，前端三大框架（Vue，React，angler）中是对小白最友好的框架\n\n另一方面，当与现代化的工具链以及各种支持类库结合使用时，Vue 也完全能够为复杂的单页应用提供驱动。\n\n### Vue和Jquery有什么区别？\n\n数据驱动试图\n\n1. jquery到vue转变是一个思想的转变，是将jquery直接操作dom的思想转变到操作数据上去。\n2. jQuery是使用选择器选取DOM对象，对其进行赋值、取值、事件绑定等操作，其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象\n3. Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象，可以说数据和View是分离的，他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM\n\n### 什么时候学习Vue？\n\n先把前端三件套熟悉（HTML，CSS，JavaScript）\n\n\n\n\n\n# Vue基本语法\n\n官方文档\n\n\n\n## 插值表达式\n\n使用{{ }}进行渲染`data:{}`里面的变量\n\n也可以是函数，不过在data里面的方法，在插值表达式中需要补充大括号\n\n例如\n\n```HTML\n\u003Cdiv id=\"app\">\n    \u003Cdiv>{{ msg }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getInfo() }}\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n```\n\n\n\n![](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208164829.png)\n\n在插值表达式中，支持运算符，以及一些方法\n\nvue指令：\n\n## v-text\n\n渲染文本，和插值表达式类似\n\n```HTML\n\u003Cdiv>\u003C\u002Fdiv>\n\u003Cdiv>{{ msg }}\u003C\u002Fdiv>\n```\n\n也是支持运算符的\n\n```HTML\n\u003Cdiv>\u003C\u002Fdiv>\n```\n\n## v-html\n\n渲染标签，如果字符串是含标签的特殊字符，那么vue会将它渲染成标签\n\n如果是v-text或者是使用插值表达式，则会原样输出\n\n![](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208165756.png)\n\n注意：\n\nv-html一般是用来渲染信任的文本，例如文章的详情内容等，最好不要用在用户提交的地方\n\n容易造成XSS攻击\n\n## v-bind\n\n可以给标签动态添加内容，也可以给动态的修改标签属性\n\n不过在属性上的操作稍微和操作内容不太一样，我们使用`v-bind`指令\n\n例如我想动态修改img标签的src属性，希望它去读取data里面的值\n\n但是我们不能在属性中使用插值表达式\n\n![](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208170933.png)\n\n这样写src直接将我的内容原样输出了，所以我们需要使用v-bind，全称为动态属性\n\n那么我可以这么做\n\n```HTML\n\u003Cimg alt=\"\">\n```\n\n![](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208171135.png)\n\n当然，`v-bind:`  可以简写为  `:`\n\n```HTML\n\u003Cimg alt=\"\">\n\n```\n\nv-bind不仅可以用于HTML存在的属性，还可以应用在自定义属性上\n\n例如\n\n```HTML\n\u003Cp>\u003C\u002Fp>\n\n实际结果：\n\u003Cp id=\"p_01\">\u003C\u002Fp>\n\n```\n\n在vue所有的指令中，都是支持表达式的\n\n例如：\n\n```JavaScript\n\u003Cdiv class=\"name\">\n    {{ a.length === 0 ? '没有数据' : a }}\n    -{{ a.split('.')[1] }}\n\u003C\u002Fdiv>\n```\n\n什么是表达式？\n\n```JavaScript\n\u002F\u002F 这是语句\nvar a = 1;\n\n\u002F\u002F 这是表达式\na.length === 0 ? '没有数据' : a\n\n```\n\n## 条件渲染\n\n### v-if和v-else的普通使用\n\nv-if中的布尔值为true，则渲染这个div\n\n如果if不成立，则渲染else中的代码块\n\n```HTML\n\u003Cdiv id=\"app\">\n    \u003Cdiv>{{ num }}\u003C\u002Fdiv>\n    \u003Cdiv id=\"if\">\n        \u003Cdiv>大于0.9的概率\u003C\u002Fdiv>\n        \u003Cdiv>v-if不满足显示我\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n```\n\n### v-else-if多条件语句\n\n```HTML\n\u003Cdiv id=\"v-else-if\">\n    \u003Cdiv>大于0.9的概率\u003C\u002Fdiv>\n    \u003Cdiv>大于0.6的概率\u003C\u002Fdiv>\n    \u003Cdiv>大于0.4的概率\u003C\u002Fdiv>\n    \u003Cdiv>大于0.2的概率\u003C\u002Fdiv>\n    \u003Cdiv>所有条件都不成立\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n\n\n\n\nv-if=\"flag\"，为true的时候显示\n\n为false的时候消失\n\n```JavaScript\n\u003Cdiv id=\"app\">\n    \u003Cdiv class=\"name\">\n        {{ name }}\n    \u003C\u002Fdiv>\n    \u003Cdiv>\n        if没匹配到就显示我\n    \u003C\u002Fdiv>\n\n\u003C\u002Fdiv>\n\n```\n\n## v-show与v-if的区别\n\n1. v-if如果是false，不会渲染\n2. v-show如果是false，不会显示 ` style=\"display: none;\"`\n\n体会一下v-if和v-show\n\n```HTML\n一个是看不见，但是我存在，只是我隐藏了    v-show \n一个是看不见，因为我本来就没被渲染       v-if\n```\n\n\n\n## 列表渲染\n\n主要分为遍历列表和遍历对象\n\n#### 遍历列表\n\n```JavaScript\nlis: [\n    '张三',\n    '王伟',\n    '张伟',\n    '王五',\n]\n```\n\n此时的item就是每个元素\n\n```HTML\n\u003Cul>\n    \u003Cli>\n        {{ item }}\n    \u003C\u002Fli>\n\u003C\u002Ful>\n```\n\nkey要唯一！！！\n\n\n\n如果需要遍历出每个元素的索引\n\n则在遍历的时候指定index\n\n```HTML\n\u003Cul>\n    \u003Cli>\n        {{ index }} -- {{ item }}\n    \u003C\u002Fli>\n\u003C\u002Ful>\n```\n\n#### 遍历对象\n\n```JavaScript\nobj:{\n    name: '张三',\n    age: 21,\n    addr: '北京市',\n}\n```\n\n一个参数，就是遍历对象的值\n\n二个参数，值和键\n\n三个参数，值，键，索引\n\n```HTML\n\u003Cul>\n    \u003Cli>\n        对象的值：{{ item }}\n    \u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cul>\n    \u003Cli>\n        对象的值：{{ item }}\n        对象的键：{{ key }}\n    \u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cul>\n    \u003Cli>\n        对象的值：{{ item }}\n        对象的键：{{ key }}\n        变量的索引：{{ index }}\n    \u003C\u002Fli>\n\u003C\u002Ful>\n```\n\n\n\n## Vue事件\n\nv-on:或者@\n\n\n```HTML\n\u003Cdiv id=\"app\">\n    \u003Cdiv>\n        {{ num }}\n    \u003C\u002Fdiv>\n    \u003Cdiv>\n        \n        \u003Cbutton>点我 +\u003C\u002Fbutton>\n        \u003Cbutton>点我 -1\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n```\n\n事件所执行的方法是要被定义在methods里面\n\n```JavaScript\nmethods: {\n    add() {\n        this.num ++\n    }\n}\n\n```\n\n参数问题\n\n可以通过传参进行参数传递\n\n```HTML\n\u003Cbutton>点我 +\u003C\u002Fbutton>\n\n\n...\nadd(number) {\n    this.num += number\n}\n\u002F\u002F 此时的add函数就能接收到传递进来的参数值\n```\n\n默认参数\n\n默认参数就是触发当前事件的事件对象\n\n```JavaScript\n\u003Cbutton id=\"add\" class=\"add_cls\">点我 +\u003C\u002Fbutton>\n```\n\n一定是`v-on:click=\"add\"`，只写一个函数名，\n\n而不是`v-on:click=\"add()\"`，这样获取不到事件对象\n\n```JavaScript\n\u002F\u002F 获取触发当前事件的标签\nadd(event) {\n    \u002F\u002F 触发当前事件的事件对象\n    console.log(event)\n    \u002F\u002F 获取标签\n    console.log(event.target)\n    \u002F\u002F 获取id，class\n    console.log(event.target.id)\n    console.log(event.target.className)\n}\n\n```\n\n如果有参数，想接收事件对象\n\n使用`$event`进行传递\n\n```JavaScript\n\u003Cbutton id=\"add\" class=\"add_cls\">点我 +\u003C\u002Fbutton>\n\n...\n\nadd(number, event) {\n    this.num += number\n    \u002F\u002F 触发当前事件的事件对象\n    console.log(event)\n    \u002F\u002F 获取标签\n    console.log(event.target)\n    \u002F\u002F 获取id，class\n    console.log(event.target.id)\n    console.log(event.target.className)\n}\n```\n\n\n\n### 图片轮播案例\n\n```HTML\n\n\n\n    \n    \u003Ctitle>图片轮播\u003C\u002Ftitle>\n    \n\n\n\u003Cdiv id=\"app\">\n    \u003Cdiv>\n        \u003Cimg alt=\"\">\n    \u003C\u002Fdiv>\n    \u003Cdiv>\n        \u003Cbutton>上一张\u003C\u002Fbutton>\n        \u003Cbutton>下一张\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n```\n\n### 事件修饰符\n\n在事件处理程序中调用 `event.preventDefault()` 或 `event.stopPropagation()` 是非常常见的需求。尽管我们可以在方法中轻松实现这点，但更好的方式是：方法只有纯粹的数据逻辑，而不是去处理 DOM 事件细节。\n\n为了解决这个问题，Vue.js 为 `v-on` 提供了**事件修饰符**。之前提过，修饰符是由点开头的指令后缀来表示的。\n\n```HTML\n\n\u003Ca>\u003C\u002Fa>\n\n\n\u003Cform>\u003C\u002Fform>\n\n\n\u003Ca>\u003C\u002Fa>\n\n\n\u003Cform>\u003C\u002Fform>\n\n\n\n\u003Cdiv>...\u003C\u002Fdiv>\n\n\n\n\u003Cdiv>...\u003C\u002Fdiv>\n\n\u003Ca href=\"http:\u002F\u002Fwww.fengfengzhidao.com\">枫枫知道\u003C\u002Fa>\n\n```\n\n\n\n#### 事件冒泡\n\n```HTML\n\u003Cdiv class=\"parent\">\n    \u003Cdiv class=\"center\">\n        \u003Cdiv class=\"child\">\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n点击里元素，执行顺序\n\n![](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211210092420.png)\n\n点击中间的元素\n\n![](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211210092456.png)\n\n被父元素包裹的元素，点击事件发送后会逐级将事件向上传递\n\n```HTML\n\u003Cp>阻止事件冒泡\u003C\u002Fp>\n\u003Cdiv class=\"parent\">\n    \u003Cdiv class=\"center\">\n        \u003Cdiv class=\"child\">\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n```\n\n添加stop事件修饰符之后，点击里元素，会阻止事件继续向上传播\n\n\n\n键盘事件\n\n```HTML\n@keydown   键盘按下\n@keyup     键盘回弹\n\n```\n\n\n\n按下回车触发\n\n支持组合键\n\n```HTML\n\u003Cinput type=\"text\">\n\u003Cinput type=\"text\">\n```\n\n\n\n&gt; 使用修饰符时，顺序很重要；相应的代码会以同样的顺序产生。因此，用 `v-on:click.prevent.self` 会阻止**所有的点击**，而 `v-on:click.self.prevent` 只会阻止对元素自身的点击。\n\n#### 2.1.4新增\n\n```HTML\n\n\u003Ca>\u003C\u002Fa>\n```\n\n\n\n### 按键修饰符\n\n最常见的可能就是在一个输入框中，判断用户是否按下了回车键\n\n```HTML\n\n\u003Cinput>\n```\n\n一些必要的按键名称\n\n```HTML\n.enter\n.tab\n.delete (捕获“删除”和“退格”键)\n.esc\n.space\n.up\n.down\n.left\n.right\n```\n\n组合按键\n\n```HTML\n\n\u003Cinput>\n\n\n\u003Cdiv>Do something\u003C\u002Fdiv>\n```\n\n\n\n\n\n\n\n## 计算属性\n\n- 调用的时候不用加括号（只是一个属性）\n- 可以监听属性变化，属性变化，计算属性重新执行\n- 并且有缓存（多个计算属性，只执行一次）\n\n和methods的区别\n\n属性变化，methods方法全部重新获取\n\n```HTML\n\n\n\n    \n    \u003Ctitle>计算属性\u003C\u002Ftitle>\n    \n\n\n\u003Cdiv id=\"app\">\n    \u003Cdiv>{{ name }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ name.split('').reverse().join('') }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ name.length === 5 ? '五言绝句' : '七言绝句' }}\u003C\u002Fdiv>\n    \u003Cdiv>五言绝句\u003C\u002Fdiv>\n    \u003Cdiv>七言绝句\u003C\u002Fdiv>\n    \u003Cdiv>错了\u003C\u002Fdiv>\n\n    \n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n    \u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n\n    \u003Cbutton>\n        点我\n    \u003C\u002Fbutton>\n    \u003Cspan>{{ num }}\u003C\u002Fspan>\n    \u003Cbutton>计算属性\u003C\u002Fbutton>\n\u003C\u002Fdiv>\n\n\n\n```\n\n### computed与watch，methods的区别\n\nmethods：可以放入函数，并且没有缓存\n\nwatch：\n\n监听，当数据发送变化时，才会触发\n\n可以得到现在的值和过去的值\n\n还可以监听路由变化\n\n和属性同名\n\n## 自定义过滤器\n\n创建一个过滤器\n\n```JavaScript\n\u002F\u002F 自定义过滤器\nfilters:{\n    \u002F\u002F 截取最后一个字符\n    getLastChar(item){\n        return item.substr(item.length-1,1)\n    }\n}\n```\n\n使用过滤器\n\n```HTML\n\u003Cli>\n    {{item.name|getLastChar }} -- {{ item.addr }}\n\u003C\u002Fli>\n```\n\n### 时间过滤器\n\n![](http:\u002F\u002Fpython.fengfengzhidao.com\u002F1031\u002F20211208215339.png)\n\n```HTML\n\u003Cdiv id=\"app\">\n    \u003Cdiv>\n        当前时间：{{ now|get_date }}\n    \u003C\u002Fdiv>\n    \u003Cul>\n        \u003Cli>\n            id：{{ item.id }} 时间：{{ item.date|get_date }}\n        \u003C\u002Fli>\n    \u003C\u002Ful>\n    \u003Cdiv>\n        时间过滤\n    \u003C\u002Fdiv>\n    \u003Cul>\n        \u003Cli>\n            id：{{ item.id }} 时间：{{ item.date|time_to_filter }}\n        \u003C\u002Fli>\n    \u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n```\n\n### 参数问题\n\n自定义过滤器也是可以接受参数，它的书写语法是\n\n```JavaScript\n\u003Cli>\n    id：{{ item.id }} 时间：{{ item.date|time_to_filter('a', 'b') }}\n\u003C\u002Fli>\n\n\n...\n\nfilters: {\n    ...\n    time_to_filter(date_str, a, b) {\n        \u002F\u002F date_str  -&gt;  '自身的值'\n        \u002F\u002F a  -&gt; 'a'\n        \u002F\u002F b  -&gt; 'b'\n        \n        return date_str\n    }\n}\n\n```\n\n过滤器方法的第一个参数就是调用者本身的值，第二个参数之后就是调用的实参\n\n并且支持链式过滤器\n\n```HTML\n\u003Cdiv>{{now|get_now|get_now1}}\u003C\u002Fdiv>\n```\n\n\n\n\n\n## 全局方法\n\n需要将属性和方法挂载到`Vue.prototype`上\n\n```JavaScript\nVue.prototype.$com = \"全局变量\"\n\nlet global_method = ()=&gt;{\n    return \"全局方法\"\n}\nfunction add(){\n    return \"全局 add 方法\"\n}\nVue.prototype.$global_method = global_method\nVue.prototype.$add = add\n```\n\n使用\n\n```HTML\n\u003Cdiv>\n    {{ $global_method() }}\n\u003C\u002Fdiv>\n\u003Cdiv>\n    {{ $add() }}\n\u003C\u002Fdiv>\n```\n\n### 全局过滤器\n\n```JavaScript\n\u002F\u002F 全局过滤器\nlet global_filter = (item) =&gt; {\n    return item + '--global'\n}\n\u002F\u002F 注册全局过滤器   (过滤器名称，方法)\nVue.filter('global_filter', global_filter)\n```\n\n使用全局过滤器\n\n```HTML\n\u003Cdiv>\n    {{ $com|global_filter }}\n\u003C\u002Fdiv>\n```\n\n\n\n## 局部组件\n\n```HTML\n\n\n\n    \n    \u003Ctitle>局部组件\u003C\u002Ftitle>\n\n\n\u003Cdiv id=\"app\">\n      \n\u003C\u002Fdiv>\n\n\n\n\n```\n\n## 全局组件\n\n```HTML\n\n\n\n    \n    \u003Ctitle>局部组件\u003C\u002Ftitle>\n\n\n\u003Cdiv id=\"app\">\n      \n\u003C\u002Fdiv>\n\n\n\n\n```\n\n## 组件通信\n\n### 父传子\n\n父传子：通过`props`来进行通信\n\n```HTML\n1. 在自组件中声明props接收在父组件挂载的属性\n2. 可以在自组件的template在任意使用\n3， 在父组件绑定自定义的属性\n```\n\n\n\n### props传入一个对象\n\n```JavaScript\nprops: ['title', 'likes', 'isPublished', 'commentIds', 'author']\n\n\nprops: {\n  title: String,\n  likes: Number,\n  isPublished: Boolean,\n  commentIds: Array,\n  author: Object,\n  callback: Function,\n  contactsPromise: Promise \u002F\u002F or any other constructor\n}\n\n\nprops: {\n    data: {\n        type: String,  \u002F\u002F 类型\n        required: true,  \u002F\u002F 必填项\n        default: '张三'  \u002F\u002F 如果没传值，那么这个默认值就是它\n    }\n}\n\n```\n\n\n\n```HTML\n\u003Cdiv id=\"app\">\n      \n\u003C\u002Fdiv>\n\n\n```\n\n\n\n### created与mounted\n\n```JavaScript\ncreated(){\n    console.log(this.data, 1)\n},\nmounted(){\n    console.log(this.data, 2)\n}\n```\n\n\n\n### 子传父\n\n```HTML\n1. 在父组件中，自组件上绑定自定义事件\n2. 在自组件中，触发原生的事件，在事件函数通过this.$emit触发自定义的事件\n```\n\n父组件\n\n```JavaScript\n\n\ncomponents: {\n    comment1\n},\nmethods: {\n    eff(data) {\n        \u002F\u002F data 是子组件传递的数据\n        console.log('父组件被调用了', data)\n    }\n}\n\n```\n\n子组件\n\n```JavaScript\nlet comment1 = {\n    template: `\n      \u003Cdiv>\n      \u003Cul>\n        \u003Cli>兰州拉面\u003C\u002Fli>\n        \u003Cli>哈尔滨啤酒\u003C\u002Fli>\n        \u003Cli>四川担担面\u003C\u002Fli>\n        \u003Cbutton>点我触发父组件方法\u003C\u002Fbutton>\n      \u003C\u002Ful>\n      \u003C\u002Fdiv>`,\n    methods: {\n        add() {\n            this.$emit('eff', {name: '子组件传来的数据'})\n        }\n    }\n\n}\n```\n\n## 平行组件\n\n```HTML\n\n\n\n    \n    \u003Ctitle>平行组件\u003C\u002Ftitle>\n    \u003Cstyle>\n        body {\n            margin: 0;\n        }\n\n        #app {\n            display: flex;\n        }\n\n        #app > div {\n            width: 50%;\n            height: 200px;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n        }\n\n        #gouwuc {\n            background-color: #3a8ee6;\n        }\n\n        #get {\n            background-color: #b3d9d9;\n        }\n    \u003C\u002Fstyle>\n\n\n\u003Cdiv id=\"app\">\n      \n      \n\u003C\u002Fdiv>\n\n\n\n\n```\n\n多次嵌套取值\n\n```HTML\n1. provide  提供变量  函数(){return {} },\n2. inject  接收变量 inject: [],\n```\n\n\n\n## 匿名插槽\n\n```JavaScript\nlet base_layout = {\n    data() {\n        return {}\n    },\n    template: `\n      \u003Cdiv>\n      \u003Cheader>\n        我是页头\n      \u003C\u002Fheader>\n      \u003C\u002Fdiv>`\n}\nnew Vue({\n    el: '#app',\n    components: {\n        base_layout\n    }\n})\n```\n\n在模板中把想要替换的东西放在``标签中，这就是一个占位符\n\n```HTML\n实际的内容\n```\n\n这样就会将标签中的内容去代替slot中的内容\n\n如果slot都没有名字，那么如果有多个slot，就会全部进行替换\n\n## 具名插槽\n\n如果你的模板中需要有多个地方被替换\n\n那么匿名插槽就不太合适了，我们给每个插槽都起一个别名\n\n```JavaScript\nlet base_layout = {\n    data() {\n        return {}\n    },\n    template: `\n      \u003Cdiv>\n      \u003Cheader>\n        我是页头\n      \u003C\u002Fheader>\n      \u003Cmain>\n        我是内容\n      \u003C\u002Fmain>\n      \u003Cfooter>\n        我是页脚\n      \u003C\u002Ffooter>\n      \u003C\u002Fdiv>`\n}\n```\n\n这样我们在进行替换的时候，指明要替换哪个slot就OK了\n\n```HTML\n\n    \u003Ctemplate>\n        头部\n    \u003C\u002Ftemplate>\n    \u003Ctemplate>\n        身体\n    \u003C\u002Ftemplate>\n    \u003Ctemplate>\n        尾部\n    \u003C\u002Ftemplate>\n\n```\n\n注意v-slot的写法\n\n```HTML\nv-slot:header\n```\n\n`v-slot:` 可以简写为 #\n\n```HTML\n \n    \u003Ctemplate>\n        \n        \u003Cdiv>\n            哈哈哈哈\n        \u003C\u002Fdiv>\n    \u003C\u002Ftemplate>\n    \u003Ctemplate>\n        身体\n    \u003C\u002Ftemplate>\n    \u003Ctemplate>\n        尾部\n    \u003C\u002Ftemplate>\n\n```\n\n&gt; 我们在替换的时候，是可以写任意标签的，也就是说，在替换的时候，你也可以将组件写入插槽中\n\n```HTML\n\n    \u003Ctemplate>\n        \n        \u003Cdiv>\n            哈哈哈哈\n        \u003C\u002Fdiv>\n    \u003C\u002Ftemplate>\n    \u003Ctemplate>\n        身体\n    \u003C\u002Ftemplate>\n    \u003Ctemplate>\n        尾部\n    \u003C\u002Ftemplate>\n\n```\n\n\n\n## 作用域插槽\n\n```JavaScript\nlet base_layout = {\n    data() {\n        return {\n            user: {\n                name: '枫枫',\n                xin: '知道'\n            }\n        }\n    },\n    template: `\n      \u003Cdiv>\n      \u003Cmain>\n        {{ user.xin }}\n      \u003C\u002Fmain>\n      \u003C\u002Fdiv>`\n}\n```\n\n在子组件中，我在插槽里面显示的是user的xin，如果我想让它显示user的name应该怎么做呢\n\n如果我们直接在父组件调用的时候这样写\n\n```HTML\n\n    {{ user.name }}\n\n```\n\n这是错误的写法，因为我们的user是被定义再自组件中的，在父组件中就无法使用这个user，所以就会报错啦\n\n那么我们就应该将这个user对象传递给父组件\n\n在子组件中\n\n```HTML\n{{ user.xin }}\n```\n\n通过动态属性的方式将user传递给父组件\n\n在父组件中\n\n```HTML\n\n    \u003Ctemplate>\n        {{ slotProps.user.name }}\n    \u003C\u002Ftemplate>\n\n```\n\n接收传递来的user即可\n\nslotProps可以是你自己定义的名字，它里面存储的是这样的\n\n```HTML\n{ \"user\": { \"name\": \"枫枫\", \"xin\": \"知道\" } }\n```\n\n所以我们将slotProps中的user中的name传递给子组件，就可以做到数据动态替换\n\n\n\n如果你的组件中，有且只有一个默认插槽，那么在替换的时候，是可以这么做的\n\n```HTML\n\n    {{ slotProps }}\n\n```\n\n但是，如果出现了具名插槽，这样会导致作用域混乱\n\n我们应该这样使用\n\n```JavaScript\nlet base_1 = {\n    data(){\n        return {\n            user: {\n                name: '枫枫知道',\n                age: 21\n            }\n        }\n    },\n    template: `\n    \u003Cdiv>\n    \u003Cheader>\n      我的名字是 {{ user.name }}，年龄是{{ user.age }}\n    \u003C\u002Fheader>\n    \u003C\u002Fdiv>`\n}\n```\n\n\n\n```HTML\n\n    \u003Ctemplate>张子枫\u003C\u002Ftemplate>\n    \u003Ctemplate>{{ slotBase }}\u003C\u002Ftemplate>\n\n```\n\n\n\n## 动态组件\n\n&gt; ``元素是vue 里面的一个内置组件。\n在里面使用 v-bind: is，可以实现动态组件的效果。\n\n\n\n\n\n\n\n\n\n\n\n## 自定义指令\n\n前面使用的v-if， v-show，以及v-for这些都是Vue为我们提供的内置指令\n\n当然，我们也可以自己自定义一个指令\n\n### 局部自定义指令\n\n```JavaScript\ndirectives: {\n    focus: {\n        \u002F\u002F 指令的定义\n        \u002F\u002F 使用这个指令就会聚焦在输入框中\n        inserted: function (el) {\n            el.focus()\n        }\n    }\n}\n```\n\n使用\n\n```HTML\n\u003Cinput type=\"text\">\n```\n\n在focus中有几个钩子函数，需要了解\n\n- `bind`：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。\n- `inserted`：被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)。\n- `update`：所在组件的 VNode 更新时调用，**但是可能发生在其子 VNode 更新之前**。指令的值可能发生了改变，也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。","# Basic overview of vue\n\nThe > element is a built-in component inside Vue.\n\nVue (pronounced \u002Fvjuː\u002F, similar to view) is a set of progressive frameworks for building user interfaces.\n\nVue.js is a progressive framework for building user interfaces, designed with incremental development from the bottom up. Vue's core libraries focus on views (html), making them easy to use and integrate with third-party libraries or projects.\n\nProgressive: step by step, not learning everything before using it.\n\nBottom-up design: A process and method of designing a program, that is, first write the basic program segments, and then gradually expand the specification, supplement and upgrade certain functions, which is actually a process of constructing the program from the bottom up.\n\nAt the heart of Vue.js is a system that allows declarations using a concise template syntax to render data into the DOM\n\nA declaration of advancement is required before the data can be used\n\n### Why Learn Vue?\n\nSimple, the three front-end frameworks (Vue, React, angler) are the most friendly frameworks for beginners\n\nOn the other hand, when combined with modern toolchains and a variety of supporting libraries, Vue is also perfectly capable of powering complex single-page applications.\n\n### What is the difference between Vue and Jquery?\n\nData-driven attempts\n1. The transition from jquery to vue is a change of thinking, which is to change the idea of directly operating DOM in jquery to manipulating data.\n2. jQuery uses selectors to select DOM objects, assign values, take values, bind events, etc., in fact, the difference from native HTML is only that it can select and operate DOM objects more conveniently\n\n3. Vue completely separates data and views through Vue objects. It can be said that data and views are separated, and they bind each other through Vue objects. This is the legendary MVVM\n\n### When to learn Vue?\n\n\n\n\n\nFamiliarize yourself with the front-end three-piece set (HTML, CSS, JavaScript)\n\n# Vue basic syntax\n\n\n\nOfficial documentation\n\n## Interpolation Expressions\n\nUse {{ }} to render the variables in data:{}\n\nIt can also be a function, but the method in data needs to add braces in the interpolation expression\n\nFor example\n```HTML\n\u003Cdiv id=\"app\">\n\u003Cdiv>{{ msg }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getInfo() }}\u003C\u002Fdiv>\n\n\n\u003C\u002Fdiv>\n\n\n\n```\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208164829.png)\n\nIn interpolation expressions, operators are supported, as well as some methods\n\nvue command:\n\n## v-text\n\nRender text, similar to interpolation expressions\n```HTML\n\u003Cdiv>\u003C\u002Fdiv>\n\u003Cdiv>{{ msg }}\u003C\u002Fdiv>\n\n```\n\nIt also supports operators\n```HTML\n\u003Cdiv>\u003C\u002Fdiv>\n\n```\n\n## v-html\n\nRender labels, if the string is a special character with a label, then vue will render it as a label\n\nIf it is v-text or an interpolated expression is used, it will output as is\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208165756.png)\n\nNote:\n\nv-html is generally used to render trusted text, such as the details of an article, and it is best not to use it in user submissions\n\nIt is easy to cause XSS attacks\n\n## v-bind\n\nYou can dynamically add content to tags, or you can dynamically modify tag properties\n\nHowever, the operation on the properties is slightly different from the operation content, we use the 'v-bind' command\n\nFor example, I want to dynamically modify the src attribute of the img tag to read the value in the data\n\nBut we can't use interpolation expressions in properties\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208170933.png)\n\nWriting src directly outputs my content as it is, so we need to use v-bind, which stands for dynamic properties\n\nThen I can do that\n```HTML\n\u003Cimg alt=\"\">\n\n```\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211208171135.png)\n\nOf course, 'v-bind:' can be abbreviated as ':'\n```HTML\n\n\u003Cimg alt=\"\">\n\n```\n\nv-bind can be used not only for properties that exist in HTML, but also for custom properties\n\nFor example\n```HTML\n\n\u003Cp>\u003C\u002Fp>\nActual results:\n\n\u003Cp id=\"p_01\">\u003C\u002Fp>\n\n```\n\nAll of Vue's directives support expressions\n\nFor example:\n```JavaScript\n\u003Cdiv class=\"name\">\n{{ a.length === 0 ? 'No data' : a }}\n-{{ a.split('.') [1] }}\n\u003C\u002Fdiv>\n\n```\n\nWhat is an expression?\n```JavaScript\nThis is the statement\n\nvar a = 1;\nThis is the expression\n\na.length === 0 ? 'No data' : a\n\n```\n\n## Conditional Rendering\n\n### Common use of v-if and v-else\n\nIf the boolean value in v-if is true, then this div is rendered\n\nIf the if doesn't hold, render the code block in else\n```HTML\n\u003Cdiv id=\"app\">\n\u003Cdiv>{{ num }}\u003C\u002Fdiv>\n\u003Cdiv id=\"if\">\n\u003Cdiv>Probability greater than 0.9\u003C\u002Fdiv>\n\u003Cdiv>v-if does not satisfy showing me\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n\n\n\u003C\u002Fdiv>\n\n```\n\n### v-else-if multi-conditional statements\n```HTML\n\u003Cdiv id=\"v-else-if\">\n\u003Cdiv>Probability greater than 0.9\u003C\u002Fdiv>\n\u003Cdiv>Probability greater than 0.6\u003C\u002Fdiv>\n\u003Cdiv>Probability greater than 0.4\u003C\u002Fdiv>\n\u003Cdiv>Probability greater than 0.2\u003C\u002Fdiv>\n\u003Cdiv>All conditions are not true\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\n\n```\n\nv-if=\"flag\", which is displayed when true\n\ndisappears when false\n```JavaScript\n\u003Cdiv id=\"app\">\n\u003Cdiv class=\"name\">\n{{ name }}\n    \u003C\u002Fdiv>\n\u003Cdiv>\nIf it doesn't match, it shows me\n\n    \u003C\u002Fdiv>\n\n\u003C\u002Fdiv>\n\n```\n\n## Difference Between V-Show and V-If\n1. If v-if is false, it will not be rendered\n\n2. v-show will not display ' style=\"display: none if it is false; \"`\n\nExperience V-IF and V-SHOW\n```HTML\nOne is invisible, but I exist, only I hide the v-show\nOne is invisible because I wasn't rendered v-if in the first place\n\n\n\n```\n\n## List rendering\n\nIt is mainly divided into traversal lists and traversal objects\n\n#### Iterate through the list\n```JavaScript\nlis: [\n'Zhang San',\n'Wang Wei',\n'Zhang Wei',\n'Wang Wu',\n]\n\n```\n\nThe item at this point is each element\n```HTML\n\u003Cul>\n\u003Cli>\n{{ item }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\n```\n\n\n\nkey to be unique!!\n\nIf you need to iterate through the index of each element\n\nthen specify the index during traversal\n```HTML\n\u003Cul>\n\u003Cli>\n{{ index }} -- {{ item }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\n```\n\n#### Traverse the object\n```JavaScript\nobj:{\nname: 'Zhang San',\nage: 21,\naddr: 'Beijing',\n}\n\n```\n\nA parameter is the value of the traversal object\n\nTwo parameters, a value and a key\n\nThree parameters, values, keys, indexes\n```HTML\n\u003Cul>\n\u003Cli>\nValue of object: {{ item }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cul>\n\u003Cli>\nValue of object: {{ item }}\nObject's key: {{ key }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cul>\n\u003Cli>\nValue of object: {{ item }}\nObject's key: {{ key }}\nIndex of variables: {{ index }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\n\n\n```\n\n## Vue Events\n\n\nv-on: or @\n```HTML\n\u003Cdiv id=\"app\">\n\u003Cdiv>\n{{ num }}\n    \u003C\u002Fdiv>\n        \n\u003Cdiv>\n\u003Cbutton>Click Me +\u003C\u002Fbutton>\n\u003Cbutton>Tap me -1\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\n\u003C\u002Fdiv>\n\n```\n\nThe methods by which an event is executed are to be defined in the methods\n```JavaScript\nmethods: {\nadd() {\nthis.num ++\n    }\n\n}\n\n```\n\nParameter problem\n\nParameter passing can be done by passing parameters\n```HTML\n\n\n\u003Cbutton>Click Me +\u003C\u002Fbutton>\n...\nadd(number) {\nthis.num += number\n}\nAt this time, the add function can receive the parameter values passed in\n\n```\n\nDefault parameters\n\nThe default parameter is the event object that triggers the current event\n```JavaScript\n\u003Cbutton id=\"add\" class=\"add_cls\"> click me +\u003C\u002Fbutton>\n\n```\n\nIt must be 'v-on:click=\"add\"', just write a function name,\n\nInstead of 'v-on:click=\"add()\"', you won't get the event object\n```JavaScript\nGet the label that triggers the current event\nadd(event) {\nThe event object that triggers the current event\nconsole.log(event)\nGet the label\nconsole.log(event.target)\nGet the id, class\nconsole.log(event.target.id)\nconsole.log(event.target.className)\n\n}\n\n```\n\nIf there are parameters, you want to receive the event object\n\nUse '$event' for passing\n```JavaScript\n\n\u003Cbutton id=\"add\" class=\"add_cls\"> click me +\u003C\u002Fbutton>\n\n...\nadd(number, event) {\nthis.num += number\nThe event object that triggers the current event\nconsole.log(event)\nGet the label\nconsole.log(event.target)\nGet the id, class\nconsole.log(event.target.id)\nconsole.log(event.target.className)\n}\n\n\n\n```\n\n### Image carousel case\n\n\n\n    \n```HTML\n    \n\n\n\u003Ctitle>Picture carousel\u003C\u002Ftitle>\n\u003Cdiv id=\"app\">\n\u003Cdiv>\n\u003Cimg alt=\"\">\n    \u003C\u002Fdiv>\n\u003Cdiv>\n\u003Cbutton>Previous\u003C\u002Fbutton>\n\u003Cbutton>Next one\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\n\n\n\u003C\u002Fdiv>\n\n```\n\n### Event modifiers\n\nCalling event.preventDefault() or event.stopPropagation()' in the event handler is a very common requirement. While we can easily do this in the method, it would be better to do it in a way that only has pure data logic instead of dealing with DOM event details.\n\nTo solve this problem, Vue.js provides an event modifier for 'v-on'. As mentioned earlier, the modifier is represented by a command suffix that starts with a dot.\n\n```HTML\n\n\n\u003Ca>\u003C\u002Fa>\n\n\n\u003Cform>\u003C\u002Fform>\n\n\n\u003Ca>\u003C\u002Fa>\n\n\n\n\u003Cform>\u003C\u002Fform>\n\n\n\n\u003Cdiv>...\u003C\u002Fdiv>\n\n\u003Cdiv>...\u003C\u002Fdiv>\n\n\u003Ca href=\"http:\u002F\u002Fwww.fengfengzhidao.com\"> Fengfeng knows\u003C\u002Fa>\n\n\n\n```\n\n#### Event bubbles\n```HTML\n\u003Cdiv class=\"parent\">\n\u003Cdiv class=\"center\">\n\u003Cdiv class=\"child\">\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n```\n\nClick on the element to execute the order\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211210092420.png)\n\nClick the element in the middle\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.icu\u002Fimg\u002F20211210092456.png)\n\nElements wrapped in the parent element will pass the event upwards step by step after clicking Send event\n```HTML\n\u003Cp>Stop the event from bubbling\u003C\u002Fp>\n\u003Cdiv class=\"parent\">\n\u003Cdiv class=\"center\">\n\u003Cdiv class=\"child\">\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n```\n\n\n\nAfter adding the stop event modifier, clicking on the inside element will prevent the event from continuing to propagate upwards\n\nKeyboard events\n```HTML\n@keydown Keyboard press\n\n@keyup Keyboard bounce\n\n\n\n```\n\nPress enter to trigger\n\nSupport key combinations\n```HTML\n\u003Cinput type=\"text\">\n\u003Cinput type=\"text\">\n\n\n\n```\n\n> When using modifiers, order is important; the corresponding code is generated in the same order. Therefore, using 'v-on:click.prevent.self' will block all clicks, while 'v-on:click.self.prevent' will only block clicks on the element itself.\n\n#### Added in 2.1.4\n\n```HTML\n\u003Ca>\u003C\u002Fa>\n\n\n\n```\n\n### Key modifiers\n\nThe most common possibility is to determine whether the user has pressed enter in an input box\n\n```HTML\n\u003Cinput>\n\n```\n\nSome necessary key names\n```HTML\n.enter\n.tab\n.delete (captures the \"delete\" and \"backspace\" keys)\n.esc\n.space\n.up\n.down\n.left\n.right\n\n```\n\nCombination of buttons\n\n```HTML\n\n\n\u003Cinput>\n\u003Cdiv>Do something\u003C\u002Fdiv>\n\n\n\n\n\n\n\n```\n\n## Calculate Attributes\n- No parentheses (just an attribute) when calling\n- You can listen for attribute changes, change attributes, and calculate attributes to re-execute\n\n- And there is a cache (multiple calculated properties, executed only once)\n\nand methods\n\nThe attributes change, and the methods method is all reacquired\n\n\n\n    \n```HTML\n    \n\n\n\u003Ctitle>Calculate attributes\u003C\u002Ftitle>\n\u003Cdiv id=\"app\">\n\u003Cdiv>{{ name }}\u003C\u002Fdiv>\n\u003Cdiv>{{ name.split('').reverse().join('') }}\u003C\u002Fdiv>\n\u003Cdiv>{{ name.length === 5 ? 'Five-character quatrain' : 'Seven-character quatrain' }}\u003C\u002Fdiv>\n\u003Cdiv>A five-character quatrain\u003C\u002Fdiv>\n\u003Cdiv>Seven-character quatrain\u003C\u002Fdiv>\n\n    \n\u003Cdiv>Wrong\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ getName }}\u003C\u002Fdiv>\n\u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n\u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n\u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n\u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n\n\u003Cdiv>{{ get_data_name() }}\u003C\u002Fdiv>\n\u003Cbutton>\nClick me\n\u003C\u002Fbutton>\n\u003Cspan>{{ num }}\u003C\u002Fspan>\n\u003Cbutton>Calculate attributes\u003C\u002Fbutton>\n\n\n\n\u003C\u002Fdiv>\n\n```\n\n### Difference between computed and watch, methods\n\nmethods: can put in a function, and there is no cache\n\nwatch：\n\nListening, which is triggered only when the data is sent to change\n\nYou can get the present value and the past value\n\nYou can also listen for route changes\n\nIt has the same name as the attribute\n\n## Custom filters\n\nCreate a filter\n```JavaScript\nCustom filters\nfilters:{\nCapture the last character\ngetLastChar(item){\nreturn item.substr(item.length-1,1)\n    }\n}\n\n```\n\nUse filters\n```HTML\n\u003Cli>\n{{item.name|getLastChar }} -- {{ item.addr }}\n\u003C\u002Fli>\n\n```\n\n### Time filter\n\n! [](http:\u002F\u002Fpython.fengfengzhidao.com\u002F1031\u002F20211208215339.png)\n```HTML\n\u003Cdiv id=\"app\">\n\u003Cdiv>\nCurrent time: {{ now|get_date }}\n    \u003C\u002Fdiv>\n\u003Cul>\n\u003Cli>\nid:{{ item.id }} Time:{{ item.date|get_date }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cdiv>\nTime filtering\n    \u003C\u002Fdiv>\n\u003Cul>\n\u003Cli>\nid:{{ item.id }} Time:{{ item.date|time_to_filter }}\n\u003C\u002Fli>\n\u003C\u002Ful>\n\n\n\u003C\u002Fdiv>\n\n```\n\n### Parameter issues\n\nCustom filters are also acceptable parameters, and their writing syntax is\n```JavaScript\n\u003Cli>\nid:{{ item.id }} Time:{{ item.date|time_to_filter('a', 'b') }}\n\n\n\u003C\u002Fli>\n\n...\nfilters: {\n...\ntime_to_filter(date_str, a, b) {\ndate_str -> 'Own value'\n\u002F\u002F a  -> 'a'\n        \n\u002F\u002F b  -> 'b'\nreturn date_str\n    }\n\n}\n\n```\n\nThe first parameter of the filter method is the value of the caller itself, and the second parameter is followed by the calling argument\n\nAnd it supports chain filters\n```HTML\n\u003Cdiv>{{now|get_now|get_now1}}\u003C\u002Fdiv>\n\n\n\n\n\n```\n\n## Global Approach\n\nProperties and methods need to be mounted on 'Vue.prototype'\n```JavaScript\n\nVue.prototype.$com = \"Global Variable\"\nlet global_method = ()=>{\nreturn \"global approach\"\n}\nfunction add(){\nreturn \"Global Add Method\"\n}\nVue.prototype.$global_method = global_method\nVue.prototype.$add = add\n\n```\n\nuse\n```HTML\n\u003Cdiv>\n{{ $global_method() }}\n\u003C\u002Fdiv>\n\u003Cdiv>\n{{ $add() }}\n\u003C\u002Fdiv>\n\n```\n\n### Global Filters\n```JavaScript\nGlobal filters\nlet global_filter = (item) => {\nreturn item + '--global'\n}\nRegister a global filter (filter name, method)\nVue.filter('global_filter', global_filter)\n\n```\n\nUse global filters\n```HTML\n\u003Cdiv>\n{{ $com|global_filter }}\n\u003C\u002Fdiv>\n\n\n\n```\n\n## Local Components\n\n\n\n    \n```HTML\n\n\n\u003Ctitle>Local components\u003C\u002Ftitle>\n      \n\u003Cdiv id=\"app\">\n\n\n\n\n\u003C\u002Fdiv>\n\n```\n\n## Global Components\n\n\n\n    \n```HTML\n\n\n\u003Ctitle>Local components\u003C\u002Ftitle>\n      \n\u003Cdiv id=\"app\">\n\n\n\n\n\u003C\u002Fdiv>\n\n```\n\n## Component Communication\n\n### Father to son\n\nParent-to-child transmission: Communication is carried out through 'props'\n```HTML\n1. Declare props in the self-component to receive the attributes mounted on the parent component\n2. You can use any template of your own component\n3. Bind custom properties to the parent component\n\n\n\n```\n\n### props pass in an object\n```JavaScript\n\n\nprops: ['title', 'likes', 'isPublished', 'commentIds', 'author']\nprops: {\ntitle: String,\nlikes: Number,\nisPublished: Boolean,\ncommentIds: Array,\nauthor: Object,\ncallback: Function,\ncontactsPromise: Promise \u002F\u002F or any other constructor\n\n\n}\nprops: {\ndata: {\ntype: String, \u002F\u002F type\nrequired: true, \u002F\u002F required\ndefault: 'Zhang San' \u002F\u002F If no value is passed, then this default value is it\n    }\n\n}\n\n\n\n```\n```HTML\n      \n\u003Cdiv id=\"app\">\n\n\n\u003C\u002Fdiv>\n\n\n\n```\n\n### created and mounted\n```JavaScript\ncreated(){\nconsole.log(this.data, 1)\n},\nmounted(){\nconsole.log(this.data, 2)\n}\n\n\n\n```\n\n### The son inherits the father\n```HTML\n1. In the parent component, bind custom events from the component\n2. In the self-component, trigger a native event, and trigger a custom event in the event function via this.$emit\n\n```\n\nParent component\n\n\n```JavaScript\ncomponents: {\ncomment1\n},\nmethods: {\neff(data) {\ndata is the data passed by the child component\nconsole.log('Parent component called', data)\n    }\n\n}\n\n```\n\nSub-components\n```JavaScript\nlet comment1 = {\ntemplate: `\n\u003Cdiv>\n\u003Cul>\n\u003Cli>Lanzhou ramen\u003C\u002Fli>\n\u003Cli>Harbin Beer\u003C\u002Fli>\n\u003Cli>Sichuan Dandan Noodles\u003C\u002Fli>\n\u003Cbutton>Click I trigger the parent component method\u003C\u002Fbutton>\n\u003C\u002Ful>\n\u003C\u002Fdiv>`,\nmethods: {\nadd() {\nthis.$emit('eff', {name: 'data from subcomponents'})\n        }\n\n    }\n}\n\n```\n\n## Parallel Components\n\n\n\n    \n```HTML\n\u003Ctitle>Parallel components\u003C\u002Ftitle>\n\u003Cstyle>\nbody {\nmargin: 0;\n\n        }\n#app {\ndisplay: flex;\n\n        }\n#app > div {\nwidth: 50%;\nheight: 200px;\ndisplay: flex;\njustify-content: center;\nalign-items: center;\n\n        }\n#gouwuc {\nbackground-color: #3a8ee6;\n\n        }\n#get {\nbackground-color: #b3d9d9;\n        }\n\n\n\u003C\u002Fstyle>\n      \n      \n\u003Cdiv id=\"app\">\n\n\n\n\n\u003C\u002Fdiv>\n\n```\n\nNested values multiple times\n```HTML\n1. provide variable function (){return {} },\n2. inject receive variable inject: [],\n\n\n\n```\n\n## Anonymous Slots\n```JavaScript\nlet base_layout = {\ndata() {\nreturn {}\n    },\ntemplate: `\n\u003Cdiv>\n\u003Cheader>\nI'm the header\n\u003C\u002Fheader>\n\u003C\u002Fdiv>`\n}\nnew Vue({\nel: '#app',\ncomponents: {\nbase_layout\n    }\n})\n\n```\n\nPut what you want to replace in the template in the tab, that's a placeholder\n```HTML\nActual content\n\n```\n\nThis will replace the content in the tag with the content in the slot\n\nIf none of the slots have names, then if there are multiple slots, they will all be replaced\n\n## Named Slots\n\nIf you have multiple places in your template that need to be replaced\n\nThen anonymous slots are not suitable, we give each slot an alias\n```JavaScript\nlet base_layout = {\ndata() {\nreturn {}\n    },\ntemplate: `\n\u003Cdiv>\n\u003Cheader>\nI'm the header\n\u003C\u002Fheader>\n\u003Cmain>\nI am the content\n\u003C\u002Fmain>\n\u003Cfooter>\nI am the footer\n\u003C\u002Ffooter>\n\u003C\u002Fdiv>`\n}\n\n```\n\nIn this way, when we make a replacement, we can specify which slot to replace\n\n```HTML\n\u003Ctemplate>\nhead\n\u003C\u002Ftemplate>\n\u003Ctemplate>\nbody\n\u003C\u002Ftemplate>\n\u003Ctemplate>\nTail\n\n\u003C\u002Ftemplate>\n\n```\n\nPay attention to the way the v-slot is written\n```HTML\nv-slot:header\n\n```\n\n'v-slot:' can be shortened to #\n \n```HTML\n        \n\u003Ctemplate>\n\u003Cdiv>\nHahahaha\n        \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Ctemplate>\nbody\n\u003C\u002Ftemplate>\n\u003Ctemplate>\nTail\n\n\u003C\u002Ftemplate>\n\n```\n\n> We can write any label when replaced, that is, you can also write components into the slot when replaced\n\n```HTML\n        \n\u003Ctemplate>\n\u003Cdiv>\nHahahaha\n        \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Ctemplate>\nbody\n\u003C\u002Ftemplate>\n\u003Ctemplate>\nTail\n\n\u003C\u002Ftemplate>\n\n\n\n```\n\n## Scope slots\n```JavaScript\nlet base_layout = {\ndata() {\n        return {\nuser: {\nname: 'Maple Maple',\nxin: 'Know'\n            }\n        }\n    },\ntemplate: `\n\u003Cdiv>\n\u003Cmain>\n{{ user.xin }}\n\u003C\u002Fmain>\n\u003C\u002Fdiv>`\n}\n\n```\n\nIn the subcomponent, I show the user's xin in the slot, what should I do if I want it to show the user's name?\n\nIf we write it like this directly when the parent component is called\n\n```HTML\n\n{{ user.name }}\n\n```\n\nThis is a wrong way to write it, because our user is defined from the component, and this user cannot be used in the parent component, so an error will be reported\n\nThen we should pass this user object to the parent component\n\nin the sub-component\n```HTML\n{{ user.xin }}\n\n```\n\nPass user to the parent component through dynamic properties\n\nin the parent component\n\n```HTML\n\u003Ctemplate>\n{{ slotProps.user.name }}\n\n\u003C\u002Ftemplate>\n\n```\n\nReceive the delivered user\n\nslotProps can be a name that you define yourself, and it stores something like this\n```HTML\n{ \"user\": { \"name\": \"Fengfeng\", \"xin\": \"Know\" } }\n\n```\n\n\n\nSo we pass the name in the user in slotProps to the subcomponent, and we can achieve dynamic data replacement\n\nIf you have and only one default slot in your component, you can do this when replacing it\n\n```HTML\n\n{{ slotProps }}\n\n```\n\nHowever, if a named slot appears, it can cause scope confusion\n\nWe should use it this way\n```JavaScript\nlet base_1 = {\ndata(){\n        return {\nuser: {\nname: 'Maple Feng Knows',\nage: 21\n            }\n        }\n    },\ntemplate: `\n\u003Cdiv>\n\u003Cheader>\nMy name is {{ user.name }} and my age is {{ user.age }}\n\u003C\u002Fheader>\n\u003C\u002Fdiv>`\n}\n\n\n\n```\n\n```HTML\n\u003Ctemplate>Zhang Zifeng\u003C\u002Ftemplate>\n\n\u003Ctemplate>{{ slotBase }}\u003C\u002Ftemplate>\n\n\n\n```\n\n## Dynamic components\nUsing v-bind: is in it, you can achieve the effect of dynamic components.\n\n\n\n\n\n\n\n\n\n\n\n## Custom Instructions\n\nThe previous use of v-if, v-show, and v-for are all built-in instructions provided by Vue\n\nOf course, we can also customize a command ourselves\n\n### Local custom instructions\n\n```JavaScript\ndirectives: {\nfocus: {\nDefinition of directive\nUsing this command will focus on the input box\ninserted: function (el) {\nel.focus()\n        }\n    }\n}\n```\n\nuse\n\n```HTML\n\u003Cinput type=\"text\">\n```\n\nThere are several hook functions in focus that need to be understood\n\n- 'bind': Call only once, the command is called when it is first bound to an element. A one-time initialization can be made here.\n- 'inserted': Called when the bound element is inserted into the parent node (only guarantees that the parent node exists, but not necessarily already inserted into the document).\n- 'update': Called when the component's VNode is updated, but may occur before its child VNode is updated. The value of the directive may or may not have changed. However, you can ignore unnecessary template updates by comparing the values before and after the update (see below for detailed hook function parameters).","前端",0,"https:\u002F\u002Fblog4-1316398321.cos.ap-nanjing.myqcloud.com\u002Fblog5\u002F20250712011452__【哲风壁纸】瞳-红色.png",[15],"Vue",false,{"id":18,"title":19,"title_en":20},8,"修复HTTP头信息泄露Nginx版本信息漏洞","Fixed vulnerability where HTTP header information leaked Nginx version information",{"id":22,"title":23,"title_en":24},10,"Django部署","Django deployment","2025-07-23T07:05:46+08:00"]