VUE 学习笔记
项目创建
npm init vue@latest
之后更加提示进行创建项目
创建好之后进入创建的目录
cd vue-demo
npm install
npm run dev
到此 vue 项目就创建完成
模板语法
文本插值
<template>
<h1>{{ msg }}</h1>
<p>{{ p1?1:2 }}</p>
<p>{{ p2+1 }}</p>
<p>{{ p3.split("").reverse().join("") }}</p>
</template>
<script>
export default{
data(){
return{
msg:"Data",
p1:true,
p2:0,
p3:"12345"
}
}
}
</script>
<style>
</style>
这个类似微信小程序里面的数据绑定和渲染。而且还支持且仅支持单一表达式也就是一段能够被求值的 JavaScript 代码。
原始 HTML
<template>
<p>{{ rawHtml }}</p>
<p v-html="rawHtml"></p>
</template>
<script>
export default{
data(){
return{
msg:"Data",
p1:true,
p2:0,
p3:"12345",
rawHtml:"<a>html</a>"
}
}
}
</script>
<style>
</style>
想要在页面插入原始 html 需要给标签加入一个v-html
属性,然后将变量放入。
属性绑定
html 元素的属性无法使用模版语法进绑定,需要特定的语法进行绑定,v-bind: =""
进行绑定或者v-bind=""
<template>
<div v-bind:id="styles">样式</div>
<fiv v-bind="objectofBind">测试</fiv>
</template>
<script>
export default{
data(){
return{
styles:"active",
objectofBind:{
id:"123",
class:"111",
index:"1"
}
}
}
}
</script>
可以用对象进行绑定多个属性,也可以绑定单一属性。
条件渲染
v-if
v-else
v-else if
v-show
列表渲染
v-for="(itme,index) in items"
v-for="(itme,index) of items"
事件绑定
v-on:click=""
@click=""
表单输入绑定
v-model
指令帮我们简化了这一步骤:
<input v-model="text">
另外,v-model
还可以用于各种不同类型的输入,<textarea>
、<select>
元素。它会根据所使用的元素自动使用对应的 DOM 属性和事件组合:
- 文本类型的
<input>
和<textarea>
元素会绑定value
property 并侦听input
事件; <input type="checkbox">
和<input type="radio">
会绑定checked
property 并侦听change
事件;<select>
会绑定value
property 并侦听change
事件。
<script>
export default {
data() {
return {
checkedNames: []
}
}
}
</script>
<div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
计算属性
计算属性是通过一些计算逻辑来实时地维护当前属性的值。函数和计算属性都可以实现完全相同的结果,但是计算属性是基于所以来的存储属性的值的变化而重新计算,计算完成后,其结果会被缓存,下次访问计算属性时,只要其依赖的属性没有变化,其内的逻辑代码就不会重复执行。而函数则不同,每次访问其都会重新执行函数内的逻辑代码得到的结果。
<template>
<h1>计算属性实现与函数实现的对比</h1>
<p>{{ num }}</p>
<p>计算属性的值:{{ type }} |计算属性被调用的次数{{ computedNum }}</p>
<p>函数执行的结果:{{ funType() }} | 方法被调用的次数{{ methodNum }}</p>
<button @click="add">ADD</button>
<button @click="changeNum">改变Num下的text</button>
</template>
<script>
export default{
data(){
return{
num:{
count:0,
text:0
},
computedNum:0,
methodNum:1
}
},
computed:{
type(){
console.log("计算属性被调用")
this.computedNum++
if(this.num.count%2 == 0){
return "偶数"
}else{
return "奇数"
}
}
},
methods:{
funType(){
this.methodNum++
console.log("方法被调用")
if(this.num.count%2 == 0){
return "偶数"
}else{
return "奇数"
}
},
add(){
this.num.count++
},
changeNum(){
this.num.text++
}
},
}
</script>
就像上述例子,改变num对象下的text,不会调用计算属性,而会调用方法
属性监听器
在选项式 API 中,我们可以使用 watch
选项在每次响应式属性发生变化时触发一个函数。
<template>
<h1>监听器</h1>
<input v-model="message"/>
<p>输入的值:{{ text }}</p>
</template>
<script>
export default{
data(){
return{
message:"",
text:""
}
},
methods:{
},
watch:{
message(oldMsg,newMsg){
this.text = this.message
}
}
}
</script>
watch
选项也支持把键设置成用 .
分隔的路径:
<script>
export default {
watch: {
// 注意:只能是简单的路径,不支持表达式。
'some.nested.key'(newValue) {
// ...
}
}
}
</script>
组建基础
组建声明
传递props
Props 是一种特别的 attributes,你可以在组件上声明注册。要传递给博客文章组件一个标题,我们必须在组件的 props 列表上声明它。这里要用到 props
选项:
<!-- BlogPost.vue -->
<script>
export default {
props: ['title']
}
</script>
<template>
<h4>{{ title }}</h4>
</template>
当一个值被传递给 prop 时,它将成为该组件实例上的一个属性。该属性的值可以像其他组件属性一样,在模板和组件的 this
上下文中访问。
一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值。
当一个 prop 被注册后,可以像这样以自定义 attribute 的形式传递数据给它:
<BlogPost title="My journey with Vue" />
<BlogPost title="Blogging with Vue" />
<BlogPost title="Why Vue is so fun" />
通过插槽来分配内容
一些情况下我们会希望能和 HTML 元素一样向组件中传递内容:
<AlertBox>
Something bad happened.
</AlertBox>
我们期望能渲染成这样:
This is an Error for Demo Purposes
Something bad happened.
这可以通过 Vue 的自定义 <slot>
元素来实现:
vue
<template>
<div class="alert-box">
<strong>This is an Error for Demo Purposes</strong>
<slot />
</div>
</template>
<style scoped>
.alert-box {
/* ... */
}
</style>
如上所示,我们使用 <slot>
作为一个占位符,父组件传递进来的内容就会渲染在这里。
闭合标签
我们在上面的例子中已经使用过了闭合标签 (self-closing tag):
<MyComponent />
这是因为 Vue 的模板解析器支持任意标签使用 />
作为标签关闭的标志。
然而在 DOM 内模板中,我们必须显式地写出关闭标签:
<my-component></my-component>
这是由于 HTML 只允许一小部分特殊的元素省略其关闭标签,最常见的就是 <input>
和 <img>
。对于其他的元素来说,如果你省略了关闭标签,原生的 HTML 解析器会认为开启的标签永远没有结束,用下面这个代码片段举例来说:
<my-component /> <!-- 我们想要在这里关闭标签... -->
<span>hello</span>
将被解析为:
<my-component>
<span>hello</span>
</my-component> <!-- 但浏览器会在这里关闭标签 -->
元素位置限制
某些 HTML 元素对于放在其中的元素类型有限制,例如 <ul>
,<ol>
,<table>
和 <select>
,相应的,某些元素仅在放置于特定元素中时才会显示,例如 <li>
,<tr>
和 <option>
。
这将导致在使用带有此类限制元素的组件时出现问题。例如:
<table>
<blog-post-row></blog-post-row>
</table>
自定义的组件 <blog-post-row>
将作为无效的内容被忽略,因而在最终呈现的输出中造成错误。我们可以使用特殊的 is
attribute 作为一种解决方案:
<table>
<tr is="vue:blog-post-row"></tr>
</table>
路由
<script>
import Home from './Home.vue'
import About from './About.vue'
import NotFound from './NotFound.vue'
const routes = {
'/': Home,
'/about': About
}
export default {
data() {
return {
currentPath: window.location.hash
}
},
computed: {
currentView() {
return routes[this.currentPath.slice(1) || '/'] || NotFound
}
},
mounted() {
window.addEventListener('hashchange', () => {
this.currentPath = window.location.hash
})
}
}
</script>
<template>
<a href="#/">Home</a> |
<a href="#/about">About</a> |
<a href="#/non-existent-path">Broken Link</a>
<component :is="currentView" />
</template>
home.vue
<template>
<h1>Home</h1>
</template>
about.vue
<template>
<h1>About</h1>
</template>
404.vue
<template>
<h1>404</h1>
</template>