分享

vue[0x02] -- 基础特性

 nullPlus 2023-02-03 发布于浙江

拆解一个vue.js实例进行分析

前期工作

我们做这样一件事情:

第一步:创建一个html文件index.html

第二步:引入远程的vue的CDN文件

第三步:在body中书写楼下代码段

<div id="app">
   <input type="text" name="" v-model="message" id=""><br />
   <p>{{message}}</p>
</div>

紧接着我们就开启我们的探索吧!

探索发现

如何绑定一个Vue实例,或者说如何创建一个vue实例并挂载到对应节点?

方法一:el方式为实例提供挂载方式,比如说这里我要把它挂载在id为app的div元素上,那就需要这么些el: '#app'

这里还需要明确的一点是你可以这样写

let vm = new Vue({
   el: "#app",
   data: {
       message: "just do it!"
  }
})

你也可以这样写

new Vue({
   el: "#app",
   data: {
       message: "just do it!"
  }
})
方法二:mount挂载
let vm = new Vue({
   data: {
       message: "just do it!"
  }
})

vm.$mount('#app');

关于template在html中的应用,跟layui其实蛮像的,在这点上

我们还是改造楼上的例子,创建一个script脚本

<script id="tpl" type="x-template">
  <div class="tpl">
      <p>祝大家新春快乐!</p>
  </div>
</script>

然后对应的vue实例改成这样

let vm = new Vue({
   el: "#app",
   data: {
       message: "just do it!"
  },
   template: '#tpl'
})

你会发现这样一个现象,我本来时挂载到id为app的div上的,但是它并没有这么做。

关于数据data属性

最开始我们讲了,挂载实例的两种方式,不知你是否注意到我在el那里贴了两段接近一样的话,其中后者你不好在浏览器或者其他代码块去访问一些像data的属性,这里提一下吧。

关于data的写法

你可以这样写

data: {
   message: "just do it!"
}

你也可以这样写

data() {
   return {
       message: "just do it!"
  }
}

这里我们着重看第一种写法,它是一个对象吧。那么这里想要搞事情,我们自然而然地想去实例外部创建一个对象然后赋值给data里面地属性来进行观察对吧,那开始吧。

把它改造成如楼下这样,笔者分别选了对象、数组、数值、字符串

 let arr = [2, 0, 2, 0];
   let obj = {
       name: 'ataola',
       age: 23
  };
   let str = 'hello world';
   let num = 1997;
   let vm = new Vue({
       el: "#app",
       data: {
           message: "just do it!",
           arr,
           obj,
           str,
           num
      }
  })

可以看到笔者把数据搞到了data上。。。。。。

那我们接下来要做的事情可能同学们已经猜到了,改值呗,看看两者的变化。

这里提一下如果是你要获取data里面的元素,那么就需要vm.$data.message这样写,或者直接vm.message

由于楼上那张图已经很明了地介绍了vue实例中data的情况,那么接下来我们再看看原先我们声明的变量吧,记住它的模样,原先它长这样,后面就可能被我改的不知道啥鬼样了。。。。。。

这里希望读者注意下,就是除了message是页面用到的,其他页面都没啥卵用,注意你更新了页面会变化吗?在这里其实vue内部是做了优化的。基于MVVM模型,就是说页面相关的数据改变了我才更新视图。

可以看到vue中的data对传入的对象只是进行了浅拷贝,就是说你改变了外面的其实也会影响vue里面的data里面的对象。

这里留一个坑吧,可能后续也会整理到我的vue疑问专题,就是说找茬嘛,我就要它深拷贝,有没有办法?有兴趣的同学思考下告诉我!

还有一个要提及一下就是怎么将数据和视图进行绑定。

如果其是一个块状元素,例如p,那么你大可<p>{{message}}</p>这样搞,

如果说是一个表单元素,那么你可以用v-model,不过这个在早期vue版本并没有这个属性。

这里提及一下,你可以通过vue.$set('key', 'val')去增加一个变量,但是会报错

[Vue warn]: Cannot set reactive property on undefined, null, or primitive value: key

所以推荐你一开始就设计下,不要想到啥用啥,个人比较不喜欢和这种程序员共事,贼心累贼头大。

组件

组件是一个蛮沉重的话题,我们不断地去学习一些技术框架,最后都应该以组件地形式输出,所以意义重大,这个在后面地专题应该会进行深入探讨,这里就意思下。

我们做这样一件事,创建一个组件

<div id="taola">
   <taola-component title="3.1415926535" content="山顶一寺一壶酒,两人我杀我"></taola-component>
</div>
<script>
   let taolaComponent = Vue.component('taola-component', {
       props: ['title', 'content'],
       data() {
           return {
               author: 'ataola'
          }
      },
       template: '<div><h1>{{title}}</h1><p>{{content}}</p><p>{{auther}}</p></div>'
  });
   new Vue({
       el: '#taola'
  })
 
</script>

翻译到页面如楼下,这里我们注册了一个全局组件,然后知道下父子组件之间用props传值,所以你放到data里面的报错,渲染不上去。

报了个错

Property or method "auther" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https:///v2/guide/reactivity.html#Declaring-Reactive-Properties.

Vue中的方法methods

这部分内容深究下,关于this指向会在后面的专题介绍,这里就简单意思下做一个点击增加次数的案例

在html中加入

<button @click ="add" >被点击了{{count}}次</button>

在vue实例化中增加methods方法

methods: {
   add: function() {
       this.count++
  }
}

生命周期

这个话题依旧很沉重,你若问我有哪些以目前的记忆力都能记得住,但深究下去去分析应用场景这个我不一定能够很好地回答,所以这里暂时先定个脉络,后面专题去深究具体w问题具体分析。

那我们就来看下一些主要的生命周期钩子函数吧。

没有什么图比官网来的更贴切实在的了

init: function () {
   console.log('2.0中 init更名为beforeCreate,所以你看不到!')
},
beforeCreate: function () {
   console.log('beforeCreate: 在实例开始初始化时同步调用!');
},
beforeCompile: function () {
   console.log('2.0中已废弃,推荐楼下的created,所以你看不到!');
},
created: function () {
   console.log('created: 在实例创建之后调用!');
},
beforeMount: function () {
   console.log('beforeMount: 新增于2.0,先于mounted!');
},
compiled: function () {
   console.log('2.0中已经更名为mounted,所有你看不到!');
},
attached: function () {
   console.log('2.0中已经废弃,所有你看不到!')
},
detached: function () {
   console.log('2.0中已经废弃,所有你看不到!')
},
ready: function () {
   console.log('2.0中已经废弃,推荐mounted,所有你看不到!')
},
mounted: function () {
   console.log('mounted: 指令生效,DOM更新,但不保证$el已插入文档!')
},
beforeDestroy: function () {
   console.log('beforeDestroy: 在开始销毁实例时调用,此时实例仍然有效!')
},
destroyed: function () {
   console.log('destroyed: 在实例销毁后调用,实例和子实例被销毁,解绑了!')
},
beforeUpdate: function() {
   console.log('beforeUpdate: 2.0中新增!');
},
updated: function() {
   console.log('updated: 2.0中新增!');
},
activated: function() {
   console.log('activated: 2.0中新增,需配合kepp-live!');
}

反映到浏览器中如下:

过滤器

Vue.js 允许在表达式后添加可选的过滤器,以管道符“|”指示, 例如

{{ name | uppercase }} // VUE
是个vue内置过滤器
  • capitalize:字符串首字符转化成大写

  • uppercase :字符串转化成大写

  • lowercase :字符串转化成小写

  • currency 参数为{String}[ 货币符号] ,{Number} [ 小数位],将数字转化成货币符号,并且会自动添加数字分节号。

  • pluralize 参数为{String} single, [double, triple],字符串复数化。

  • json 参数为{Number}[indent] 空格缩进数,与JSON.stringify() 作用相同,将json对象数据输出成符合json 格式的字符串。

  • debounce 传入值必须是函数,参数可选,为{Number}[wait],即延时时长。作用是当调用函数n 毫秒后,才会执行该动作,若在这n 毫秒内又调用此动作则将重新计算执行时间。

  • limitBy 传入值必须是数组,参数为{Number}limit,{Number}[offset], limit 为显示个数,offset 为开始显示数组下标。

  • filterBy 传入值必须是数组,参数为{String | Function} targetStringOrFunction,即需要匹配的字符串或函数(通过函数返回值为 true 或 false 来判断匹配结果);“in”( 可选分隔符);{String}[…searchKeys],为检索的属性区域。

  • orderBy 传入值必须是数组,参数为{String|Array|Function}sortKeys,即指定排序策略。

PS: 2.0已经移除了这些内置过滤器

指令(Directives)

这些很死,记记背背的东西,抓重点形如v-xxx这种大致就是指令了或者@xx,这边就不展开了,还是后面开个专题吧!

值得一提的是修饰符,就是说可以这样写v-on:click.stop="doClick", stop相到于e. stopPropagation(), 望须知!

类似的有

.stop: 等同于调用event. stopPropagation()。
.prevent: 等同于调用event.preventDefault()。
.capture: 使用capture 模式添加事件监听器。
.self: 只当事件是从监听元素本身触发时才触发回调。

计算属性computed

举个例子吧,写过markdown的同志应该有感触,一些应用可以让你边写边实时渲染,它做的就是这么个事情,监听属性的变化。

写法上形如这种:

computed: {
   fun: {
       set: function(){

      },
       getL function() {

      }
  },
   func2: function() {

  }
}

这里我们在html中编写如下代码:

<input type="text" name="" v-model="message" id=""><br />
<p>{{message}}</p>
<input type="text" name="" v-model="message2" id=""><br />
<p>{{message2}}</p>
<p>{{m1m2}}</p>

在vue的computed属性中这么写:

data: {
   message: "just do it!",
   message2: "ataola is me !",
},
computed: {
   m1m2: function() {
       return this.message + " | " + this.message2;
  }
}

效果如图所属:

其实真正好玩的是,用计算属性的set和get去操作一些DOM、cookie、sessionStorage、localStorage之类的,这里就意思下,在后面专题我们再深究。

Class与Style绑定

开发中经常做的一件事就是动态地增加或者删除类,比如说tab组件的切换。

这里比如说你在一个标签中运用了v-bind:classs="v-bind:calss="{'active' : active , 'unactive' : !active}",

那么你只需要在data属性里设置active为true就行了。

渲染的结果就是 <div class="tab active"></div>

如果是多个类可以以数组的方式传递 v-bind:class="[classA, classB]"

如果你要绑定样式用v-bind:style,用法和楼上一样,注意绑定的是内联样式,还有个好处就是它会帮你加前缀。

模板渲染

模板渲染这块内容会涉及到一些遍历指令,你想嘛,大致就是拿个对象数组字段集合哈希表进行遍历输出显示嘛,早期前端做的是静态页面,死的数据,而模板的渲染这块要靠后端的嵌入php、jsp、asp代码完成,但现在更多的是后端给个接口,前端通过Ajax进行异步交互获取数据然后进行模板渲染,前后端更加专注做自己的事了吧,然后就是符合数据驱动视图。

Vue.extend(options)

创建基础Vue 构造器的“子类”,参数options 对象和直接声明Vue 实例参数对象基本一致

大致如下写法

let Child = Vue.extend({
   // coding
});

Vue.component('ataola-child', Child);
<ataola-child></ataola-child>

参考文献

《Vue.js前端开发快速入门与专业应用》

组件基础:https://cn./v2/guide/components.html

组件注册:https://cn./v2/guide/components-registration.html

参考文献:https://cn./v2/guide/instance.html#%E5%AE%9E%E4%BE%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%

选自《Vue涂鸦》系列文章

原文地址:https://github.com/ataola/vue-Graffiti/blob/master/note/vue-normal.md

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多