- <div id="eg1">
- <h1>methods------{{birth}},{{age1(birth)}}h1>
- <h1>computed-----{{birth}},{{age}}h1>
- <button @click="change">点击button>
- <p>{{shuxing}}p>
- div>
- <script>
- new Vue({
- el: "#eg1",
- data: {
- birth: "2001-04-16"
- },
- methods: {
- age1(str) {
- return new Date().getFullYear() - new Date(str).getFullYear()
- },
- change() {
- this.shuxing = 200
- }
- },
- computed: {
- //第一种写法:语法糖
- age() {
- return new Date().getFullYear() - new Date(this.birth).getFullYear()
- },
-
- //第二种写法 把shuxing当属性看
- shuxing: {
- //获取 取值
- get() {
- console.log("computed执行了")
- return new Date().getFullYear() - new Date(this.birth).getFullYear() + "岁"
- },
- //设置 存值
- set(val) {
- console.log(val)
- this.birth = `${2022-v}-02-03`
- }
- }
- },
- })
- script>
结果显示:
- 计算属性会把使用到的data中的属性缓存起来,防止页面发生大量重复计算,提升运行效率。仅当计算属性中使用到的data中那部分数据变了才会重新调用计算属性刷新页面,否则直接使用缓存中的数据。
- methods方法没有计算结果缓存起来,data任何数据发生改变,模板会重新取值渲染页面 ,方法都会被重新调用一遍
- 方法常常是作用的事件使用,计算属性常常是动态计算结果时使用
- 计算属性使用时当做属性使用
- 计算属性设计时当做函数设计(就像es6中的属性)
- 当计算属性的函数中使用到的data中的数据发生变化时,计算属性就会重新执行并刷新UI
1.如果是修改了data中监听的某个的属性值 计算属性就会运行
2.如果是修改了data中监听的某个属性值内部的数据,计算属性就不会重新运行
比如:计算属性使用的是data中的一个数组,某个交互把数组内部的某个下标的值改了,但是这个数 组没有改变,就不会触发计算属性
解决办法1:把修改后的数组重新赋值给data,让引用发生变化,来触发计算属性
解决办法2:赋值 JSON.parse(JSON.stringfy(data))
- <div id="eg1">
- <p>{{n}}p>
- <button @click="change1">修改nbutton>
- <button @click="change2">修改objbutton>
- <p>{{obj.age}}p>
- div>
- <script>
- new Vue({
- el: "#eg1",
- data: {
- n: 100,
- obj:{age:20}
- },
- methods: {
- change1() {
- this.n = 90
- },
- change2() {
- //修改了引用数据内部的属性值,页面会重新渲染,但是侦听器属性不会触发 因为引用没有发生变化
- this.obj.age = "21"
- //只有修改了引用数据的引用 才会触发侦听器属性
- this.obj={age:22}
- //若想只修改引用数据的属性值也触发侦听器,必须深度监听
- }
- },
- watch: {
- n() {
- console.log(1111)
- },
- // obj(){
- // console.log("obj改变了")
- // },
- //深度监听 引用数据内部的属性值
- obj:{
- deep:true,
- handler:()=>{
- console.log("obj改变了")
- }
- }
- }
- })
- script>
结果显示:
计算属性:会把计算的结果缓存起来,并监听计算过的数据源。如果监听的数据源发生改变就会重新计算(监听的属性没有发生变化 模板重新渲染 但直接取缓存中的计算结果)
方法:一般是提供给模板事件和其他方法(如钩子函数)使用,如果在模板中使用了方法,而且不是事件,只要模板中的渲染的任意数据源改变了,它都会重新调用
过滤器:用于数据渲染器的数据处理,除了用法与方法不一样 其他都一样。但是它没有被this劫持。
属性侦听器:只有侦听的属性发生变化时才会触发(deep:true 深度侦听,但消耗内存)
将以上函数分类的原因:为了业务更明显 功能更好调试
被this对象劫持的:方法、计算属性
- 指令:标签中v-开头的一种自定义的标签的属性 在vue运行后就具有封装好的功能 使用时非常简洁
除了默认设置的核心指令( v-model 和 v-show 等),Vue 也允许注册自定义指令。
在Vue里,代码复用的主要形式和抽象是组件。
有的情况下,仍然需要对纯 DOM 元素进行底层操作,这时候就会用到自定义指令 。
钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind
:只调用一次,指令与元素解绑时调用。钩子函数参数
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM。binding
:一个对象,包含以下 property:
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
- <div id="eg1">
- <p v-html="msg">p>
- <input type="text" v-model="count">
- <div v-red>字体变红div>
- <div v-color="'pink'">字体变粉div>
- <div v-color="mycolor">data中的变量div>
- <input type="text" v-focus value="获取光标">
- div>
- <script>
- new Vue({
- el: "#eg1",
- data: {
- msg: "
案例1
", - count: 200,
- mycolor: "blue"
- },
- directives: {
- red: {
- inserted(el) {
- //el:绑定这个指令的节点对象:DOM操作
- console.log(el)
- el.style.color = "red"
- }
- },
- color: {
- //inserted:指令插入节点以后 钩子函数
- inserted(el, option) {
- console.log(el, option.value)
- el.style.color = option.value
-
- }
- },
- focus: {
- inserted(el) {
- el.focus()
- }
- }
- }
- })
- script>
结果显示:
vue组件中8个:当前vm实例从创建到销毁的过程中会调用的函数:
- beforeCreate()
- created()
- beforeMount()
- mounted() //以上4个钩子都只执行一次
- beforeUpdate()
- updated() //以上2个第一次构建不会调用,以后每次data被更新了才会调用
- beforeDestroy()
- destroyed() 只执行一次
- 此函数由系统调用
- 函数在vm创建完成之前运行时,vm正在创建中:劫持data,methods 所以此时this对象中还不能访问到数据
能否网络请求数据 设置到数据源中?
- 可以做网络请求 因为函数在运行时XMLHttpRuquest是可以访问做AJAX请求
- 不能设置到数据源中 因为此时this还在创建
在此函数中可以做:
- 预加载:网页中同源加载的优化(同一个页面中的img script等 src属性请求资源) 将资源请求下来 存着 但不渲染
- 提前配置
- 只要不是用于页面渲染的都可以
- 在vm对象创建完毕后挂载到DOM树前触发钩子(调用函数)
- 即此函数可以操作this对象 但不能操作DOM
能否网络请求数据 设置到数据源中?
- 可以做网络请求 因为函数在运行时XMLHttpRuquest是可以访问做AJAX请求
- 可以设置到数据源中 因为此时this已经创建完毕
在此函数中可以做:
- 请求首屏数据
- 挂载/渲染前的操作
- vm对象创建完毕后挂载到DOM树前调用函数
- 可以做网络请求 可以设置到数据源中 可以操作this对象 无法操作DOM
- vm已经挂载到页面上 DOM渲染已经完成
- 请求首屏数据
- 网络请求时 页面已经出来了 请求后数据驱动页面 局部刷新页面
(数据源已经更新 )在页面重新渲染前 触发的钩子
数据更新时调用,发生在虚拟 DOM 打补丁之前。
这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器,该函数在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行
此函数中不能网络请求数据更新数据源 会导致死循环
- 页面已经重新渲染后 触发钩子
- 此函数中不能网络请求数据更新数据源 会导致死循环
- vm实例对象销毁之前 触发的函数 此时this还存在
- 可以做最后的操作 如 保存用户的行为配置文件
- vm对象销毁后触发的函数 无法操作this
- 调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监 听器会被移除,所有的子实例也会被销毁
- 清除当前组件中的计时器 把body的滚动条滚动到顶部
注册组件的注意事项:
- 注册组件时,组件名不能与系统标签同名
- 组件template模板中 只能有一个根元素
- 注册时用驼峰命名法,使用时用连字符 如
<==>
- <div id="eg1">
- <Box>Box>
- <Nav1>Nav1>
- <my-box>my-box>
- div>
- <script type="module">
- //第三种:import 导入
- import MyBox from "./components/MyBox.js"
- //第一种:写在全局 components中引用变量名
- let cpt1={
- template: `
-
我是全局声明的
- `
- }
- new Vue({
- el: "#eg1",
- data: {},
- methods: {},
- components: {
- //注册组件
- //第一种:写在全局
- Box:cpt1,
- //第二种:直接注册
- Nav1:{
- template:`
-
我是在components中直接注册的
- `,
- data:function(){
- return {msg:"msg"}
- },
- methods:{
- fn(){console.log("组件的全部方法")}
- }
- },
- //第三种:import 导入
- MyBox
- },
- })
- script>
结果显示: