Vue:
-
MV*,1.0 是 MVVM 框架,2.0 不是了
-
Vue 的两个版本:完整版和运行时
- 完整版:vue.js/vue.min.js;非完整版:vue.runtime.js
- 完整版的体积大,功能强,支持直接写入 html;非完整版需要 render(h)才能写入 HTML
- 其中完整版多了一个编译器,但是非完整版更独立?
- webpack 可以做到我们看似是用带有编译器的写代码,其实是不带的,然后在打包时转化成能理解的??反正就是可以用体积更小的包更好的体验写代码
- 将编译器放在 build 里面,webpack+vue loader
- 引入方式
- cdn 引入
- webpack 引入,默认是非完整版,用完整版需要配置 alias
- @vue/cli 引入,默认是非完整版,完整版需要配置
- 到底怎么配置看文档
-
vue 单文件组件
- 写一个组件
- 引入进 main.js
- el:"xxx",render(h){return h(Demo)}
- 这是有 vue-loader 时可以写的
-
SEO 友好
- 搜索引擎优化
- curl 命令
- 把 description、title、keyword、h1、a 写好
- vue 中虽然 vue 会直接覆盖页面中的 dom 节点,但是搜索引擎依然可以 curl 到 div 中写的关键词
-
ssr
- 不要用客户端的 js 去渲染内容,而是用服务器端的 js 去渲染内容,指的去获取数据库数据等
- 指的就是 node.js
-
最佳实践:总是使用非完整版,然后配合 vue-loader 和 vue 文件
- 只支持 h 函数
- vue 文件不用写 h 函数
- vue-loader 把 vue 文件里的 HTML 转为 h 函数
-
真正的工程师要做的事是封装!
const vm = new Vue(options);
- new Vue({})这就是构造一个 vue 实例
- 但凡是个函数,他的proto就是 Function,vue 就是个构造函数
- vm 对象封装了对视图的所有操作,包括数据读写、事件绑定、DOM 更新,没有 ajax
- 因为 vue 是视图层的,不会去包含网络层的东西
- options 是 new Vue 的参数,一般称之为选项或构造选项,参数选项啊
- :属性名="",表示""里的是 js 代码,引号和里面的没关系,也可以传函数
options
-
数据:data 数据、props 属性、propsData、computed 被计算出来的、methods 方法、watch 观察
- 方法与函数:
- 方法:面向对象概念;函数:数学概念
- obj.say()是面向对象的写法,say()是函数式编程的写法
- data:可以为对象,也可以为函数,返回对象,优先使用函数(为什么?在 vue 组件里,data 要写为函数,因为如果这个组件被引用了两次,那如果是对象就是引用了同一个内存地址,一个改变所有的都改变,函数就不一样,函数内的变量是有自己的作用域的,调用时时重新创建变量)
- methods:作为事件处理函数或普通函数(代替 filter)
- @click="add"
- {{add()}}
- props:外部属性,外部传参,父传子
// main.js <Demo message="" /> // Demo.vue <template>{{message}}</template> <script> export default { props: ['message'] } </script> - 方法与函数:
-
DOM:el 容器、template 内容、render 渲染、renderError
- el:挂载点,与$mount 有替换关系
-
生命周期钩子:11 个钩子函数 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deactivated、destroyed...
- 使用 debugger 等手段实验
- created:出现在内存中,没有出现在页面中
- mounted:出现在页面中
- updated:更新触发
- destroyed:消亡,再次创建是重新创建全新的。怎么使用它呢?通过 v-if 可以控制一个组件的显隐
-
资源:components 组件、directives 指令、filters 过滤器
-
component 组件:可以组合的物件?
- 引入
- 可以直接创建、使用
- 还有一种见 App.vue
- 所以,直接 new Vue 就是实例,像上面几种方法创建的就是组件
- 组件用大写
Vue.component("demo", { template: ` <div>demo</div> `, }); -
directives 指令:自定义指令
- Vue.directive('x', directiveOptions)=>全局指令
- 局部指令,只能用在该实例中
new Vue({ ..., directives: { "x": directiveOptions } })- 指令主要作用:DOM 操作,减少重复的 DOM 操作
- VUE 实例/组件用于数据绑定、事件监听、DOM 更新
- 所有的 dom 操作都写在指令里面,经常使用的、复杂的 dom 操作封装指令
-
-
组合:extends 扩展、provide 提供、inject 注入、mixins 混合、parent
- mixins 就是复制。作用是减少 data、methods、钩子的重复
- 重复代码可以写在一个 js 文件里,然后导入后使用 mixins: [log],log 是 js 中 export default log,vue 导入的文件名
- 智能合并。如果有需要 vue 文件传参的地方,可以在 vue 文件的 data 中写,或者与 js 文件有一样的函数,也可以写,因为 mixins 可以智能合并
- 可以设置全局混入,在 main.js 里写就行,然后直接用,不用导入,但是这样所有的 vue 组件就都会被混入,会出现未定义等错误 Vue.mixin({})
- extends 继承。
- 跟 mixin 相似,同样需要新建 js 文件新建 myVue,继承 Vue 后写自己的代码
const myVue = Vue.extend({}),然后其他 vue 组件就可以 extends myVue - 跟 mixin 相似,同样需要导入 myVue,然后 extends:myVue
- 更高级的是,myVue 可以导入 mixin 文件,在里面 mixins,这样原先可能需要写很多遍的 mixins,可以在 myVue 中一次写完,然后其他组件可以继承一次这个 myVue 就可以
- 跟 mixin 相似,同样需要新建 js 文件新建 myVue,继承 Vue 后写自己的代码
- provide 和 inject
- 当子组件想使用父组件的变量和函数时,可以把这些变量和函数放在 provide 里,然后使用 inject 注入到想使用的子组件
- 注意:如果变量是字符串,那么传过去的就只是这个字符串的复制品,直接在子组件里更改这个字符串没有任何意义。这时可以在父组件里添加函数进行修改,然后传这个函数。当然,变量是对象的时候是可以直接进行修改的,但是这样你的变量就会被任何人任意修改,会失控
- 作用:适用于大范围的data和methods共用
if(x === 'a' || x === 'b' || x === 'c') {} 相当于 if(['a', 'b', 'c'].indexOf(x) >= 0) {} - mixins 就是复制。作用是减少 data、methods、钩子的重复
-
其他
数据响应式-data
- {n:(...)}表示并不存在一个 n 属性,但可以通过 get 和 set 对他进行读写
- 虚拟属性 get 和 set
- 新增 set 和 get,使用 defineProperty:
注意:不要在 get 和 set 里使用新增的 agevar _xxx = 0 Object.defineProperty(obj1, 'age', { get() { return _xxx } set(value){ _xxx = value } }) - 监听和代理
- 当 vm=new Vue({data: myData})
- 让 vm 成为 myData 的代理 proxy
- 会对 myData 的所有属性进行监控
- 监控是为了防止 data 被改变 vm 还不知道,vm 知道就可以调用 render
- data 的 bug:没有这个属性还要使用(比如在其他地方赋值)
- 如果 data 中没有声明变量 a,那么其他引用/操作 a 的语句都无法成立,因为 vue 无法监听一个一开始不存在的变量
- 但是可以通过以下方法操作:
- Vue.set(obj, 'a', {})
- this.$set()
- 作用:新增 key;自动创建代理和监听;触发 UI 更新,但不是马上更新
- 纠错:this.$set 作用于数组时,并不会自动添加监听和代理,原因未知
- 数组的变异方法 push、pop 等 7 个方法,会在调用的同时添加/删除监听和代理
进阶属性 数据更新时除了更新 UI 还能干啥
-
computed 计算属性:根据其他属性计算出的属性,是一个函数,但可以按变量读取
-
computed 是怎么做到缓存的?
-
watch 侦听:当数据变化时执行一个函数
-
watch 是异步的,会先做完这个函数的事再去触发 watch,所以可以让函数等一会,但不能使用 timeout({},0),vue 封装的 watch 的立马执行函数是 this.$nextTick,所以函数内也要使用这个
-
watch:第一次的值不监听,就是那个初始值
-
想做到监听第一次的值,可以在 handler 函数中写操作,然后设置 immediate=true
-
区别:
- computed:依赖于执行变化和缓存得到结果
- watch:更倾向于去执行一个东西,比如记录历史
- 英文翻译中文;用代码分别去描述
- computed 不需要用括号可以直接使用;根据依赖会自动缓存,依赖的值不发生改变就不会重新计算
- watch 有两个属性 immediate 和 deep;属性变化就去执行一个函数
-
watch:
- 简单类型变了就是变了,复杂类型,比如引用类型 obj={a:'a'},a 变了,但 obj 并没有变,obj 变了,里面的不变
- a 变化,怎么才能让 obj 也变化:加属性 deep: true
- 千万不要使用箭头函数
模板 template
- template 里面不是 HTML,是 XML
- XML 有闭合标签这一说,必须闭合,XML 可以这么写:自闭合
- 三种写模板的方式:
- main.js 中使用 template,写在 HTML 里
- main.js 中在写在选项里
- xxx.vue 写在 HTML 里然后其他文件引入
- 展示内容:
- {{ 表达式/运算/函数 }}
- undefined 或 null 不显示
- v-text=""没啥意义
- 如果包含标签,富文本=> v-html=""
- 想展示{{ n }}:v-pre 不会对模板进行编译
- 绑定属性
- src: v-bind:src="x"
- v-bind: 简写=> :
- :src :style
- 100 默认表示为 100px
- 绑定事件
- v-on:事件名="函数名"
- 缩写:@click
- if...else
- v-if:
- v-else-if:
- v-else:
- for(value, key) in obj/arr
- v-for="(u, index) in users" :key="index"
- v-for 必须要写 :key
- key 一般是不会重合的、唯一性的值
- :key="index"有 bug
- v-show
- 不是所有看的见的元素 display 为 block
- table 的 display 为 table
- li 的 display 为 list-item
- 特点:
- XML
- {{}}
- 指令:操作 DOM 和实现循环和条件判断
- vue 是声明式编程,写的是声明式对应的是命令式操作
- 指令:v-model;v-slot;v-cloak;v-once
指令
- v-开头
- v-pre 没有值 v-on:click.prevent 阻止默认事件
- .prevent 叫做修饰符
- .stop 阻止事件传播/冒泡
- .prevent 阻止默认动作
- .stop.prevent 同时表示两个意思
- v-on 的修饰符可以为 keycode 或他的别名(Alias),比如 enter 键的 keycode 为 13,可以写为:
- @click.13 = ""
- @click.enter = ""
- 别名修饰符有 enter、tab、delete 等,找官网
- v-bind: .sync
- 组件不能修改 props 外部数据
- this.$emit 可以触发事件并传参
- emit 的参数
- :money.sync="total"相当于:money="total" v-on:update:money="total=emit('update:money', money-100)"
- 这就是父和子组件互相传递啊
- v-model: .lazy .number .trim
v-model
- 双向绑定
- 内存改变时页面也会改变;页面改变内存也会改变(表单)
- input、多行文本、复选框、单选框、选择框、表单
- input,v-model="x"
- 多行文本textarea
- 复选框需要绑定不同的value,需要声明一个数组x
- 单选框,x="",最好把name写上,相同的name表示他们是一组的,radio
- select,options
- :value="1",这个1表示number,value="1",这个1是string,前者是动态绑定,加冒号:表示里面的是js语句,不然就是字符串
- form(@onSubmit.prevent="")+button(type="submit"),输入(v-model="user.username",v-model="user.password")后按回车可以自动提交,此时监听form的onSubmit事件输出变化的信息this.user,就可以拿到提交的信息
- 修饰符
- .lazy
- 表单在输入的时候,内存内的数据就变化了(input事件),想要让这个频率降低,使用v-model.lazy变成监听change事件
- input事件监听任何的改变,包括鼠标、键盘等输入设备
- change事件监听的是失去焦点
- .number
- 当变量初始化就是number类型,且输入的也只想要number类型就可以使用v-model.number,它会自动识别,比如输入21sss3,只会保存21,且021会自动省去0
- .trim
- 自动把前面和后面的空格去掉
- .lazy