初识Vue

141 阅读3分钟

hello world

基础使用

// 创建Vue的实例
Vue.createApp({
// 在root中渲染的内容
    template: '<div>hello world</div>'
// 指定目标元素上使用vue    
}).mount('#root')

添加变量

vue中在data函数返回的对象中定义变量

 // 创建Vue的实例
Vue.createApp({
    data() {
        // content变量
        return {
            content: 1
        }
    },
    // 在root中渲染的内容,"{{}}" 叫插值表达式
    template: '<div>{{content}}</div>'
    // 指定目标元素上使用vue    
}).mount('#root')

counter计时器

使用vue之后由之前的面向DOM编程,转向面向数据编程,数据改变页面内容跟着发生变化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello world</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        // 创建Vue的实例
        Vue.createApp({
            data() {
                // content变量
                return {
                    content: 1
                }
            },
            // 自动执行的函数
            mounted(){
                setInterval(() => {
                    this.content += 1                   
                }, 1000);
            },
            // 在root中以template模板作为展示内容
            template: '<div>{{content}}</div>'
            // 指定目标元素上使用vue    
        }).mount('#root')
    </script>
</body>

</html>
    

字符串反转

v-on:click指令绑定事件

  • vue中使用v-on:click指令绑定事件
  • vue中在methods对象中定义方法

学习vue之前的处理逻辑

在页面中找到“hello world”对应的DOM元素,对其进行反转,然后再将DOM元素放到页面中更新页面

学习vue之后的处理逻辑

由面向DOM编程,变成面向数据编程,只要让页面的“hello world”反转,页面显示的内容就会自动更新,即数据反生变化,页面内容发生变化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello world</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        // 创建Vue的实例
        Vue.createApp({
            // 定义数据
            data() {
                return {
                    content: 'hello world'
                }
            },
            // 定义方法
            methods:{
                handleButtonClick() {
                    this.content = this.content.split('').reverse().join('')
                }
            },
            // 定义页面显示内容
            template: `
                <div>
                    {{content}}
                    <button v-on:click = "handleButtonClick">反转</button>
                </div>

            `
        }).mount('#root')
    </script>
</body>

</html>

内容显示隐藏

v-if指令

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>显示和隐藏</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        // 创建Vue的实例
        Vue.createApp({
            // 定义数据
            data() {
                return {
                    show: true,
                    content: 'hello world'
                }
            },
            // 定义方法
            methods: {
                handleButtonClick() {
                    this.show= !this.show
                }
            },
            // 定义页面显示内容
            template: `
                <div>
                    <span v-if="show">{{content}}</span>
                    <button v-on:click = "handleButtonClick">显示/隐藏</button>
                </div>

            `
        }).mount('#root')
    </script>
</body>

</html>

todoList

todoList新增固定内容

v-for 循环数组中数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>todoList</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        // 创建Vue的实例
        Vue.createApp({
            // 定义数据
            data() {
                return {
                    list: []
                }
            },
            // 定义方法
            methods: {
                handleAddItem() {
                    this.list.push('hello world')
                }
            },
            // 定义页面显示内容
            template: `
                <div>
                  <button v-on:click="handleAddItem">增加</button>
                  <ul>
                    <li v-for="(item,index) of list">{{item}}</li>
                  </ul>
                </div>

            `
        }).mount('#root')
    </script>
</body>

</html>

todoList新增自定义内容

v-model指令双向绑定数据

input输入框中的内容同data中的数据进行双向绑定

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>todoList</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        // 创建Vue的实例
        Vue.createApp({
            // 定义数据
            data() {
                return {
                    list:[],
                    inputValue:"",
                }
            },
            // 定义方法
            methods: {
                handleAddItem() {
                    this.list.push(this.inputValue)
                    // 清空输入框内容
                    this.inputValue = ""
                }
            },
            // 定义页面显示内容
            template: `
                <div>
                  <input v-model="inputValue"/>
                  <button v-on:click="handleAddItem">增加</button>
                  <ul>
                    <li v-for="(item,index) of list">{{item}}</li>
                  </ul>
                </div>
            `
        }).mount('#root')
    </script>
</body>

</html>

image.png

对todoList代码进行拆分

v-bind:指令将属性和数据进行绑定

如:button上的属性title同数据进行绑定怎么办?

 // 定义页面显示内容
template: `
    <div>
      <input v-model="inputValue"/>
      <button
       v-on:click="handleAddItem"
       title="inputValue"
      >
       增加
       </button>
      <ul>
        <li v-for="(item,index) of list">{{item}}</li>
      </ul>
    </div>
`

image.png

发现这样并不行,那么使用插值表达式可以吗?

 template: `
        <div>
          <input v-model="inputValue"/>
          <button
           v-on:click="handleAddItem"
           title="{{inputValue}}"
          >
           增加
           </button>
          <ul>
            <li v-for="(item,index) of list">{{item}}</li>
          </ul>
        </div>
   `

image.png

==> 我们发现也不可以,在vue中如果想要一个标签的属性同一个数据进行绑定,就需要使用v-bind进行绑定,如果这里的title属性同inputValue数据进行绑定

template: `
    <div>
      <input v-model="inputValue"/>
      <button
       v-on:click="handleAddItem"
       v-bind:title="inputValue"
      >
       增加
       </button>
      <ul>
        <li v-for="(item,index) of list">{{item}}</li>
      </ul>
    </div>
            `

image.png

总结:

vue中属性和数据进行绑定要用v-bind指令

标签内绑定内容使用插值表达式

组件的概念

组件就是页面中的一部分,在大型项目中不能把所有的代码全部写在一个页面中,那样页面没有办法维护,这时就需要将页面拆分成组件,在页面中最小的组件就是一个DOM标签

组件改写todoList

随着页面中的逻辑越来越复杂,vue示例中的内容也会变得越来越冗长,代码维护的成本也会越来越大,我们不妨将页面中的一部分即<li></li>标签中的内容拆分成组件进行维护

 // 创建Vue的实例
Vue.createApp({
    // 定义数据
    data() {
        return {
            list:[],
            inputValue:"",
        }
    },
    // 定义方法
    methods: {
        handleAddItem() {
            this.list.push(this.inputValue)
            // 清空输入框内容
            this.inputValue = ""
        }
    },
    // 定义页面显示内容
    template: `
        <div>
          <input v-model="inputValue"/>
          <button
           v-on:click="handleAddItem"
           v-bind:title="inputValue"
          >
           增加
           </button>
          <ul>
            <li v-for="(item,index) of list">{{item}}
                <div>
                    <span>index</span>
                    <span>--</span>
                    <span>{{item}}</span>
                </div>    
            </li>
          </ul>
        </div>
    `
}).mount('#root')

在vue实例上注册组件

注册组件

使用app.component(组件名称,{})注册组件,其中app是vue实例,{}中放组件的内容

 template: `
    <div>
      <input v-model="inputValue"/>
      <button
       v-on:click="handleAddItem"
       v-bind:title="inputValue"
      >
       增加
       </button>
      <ul>
        <todo-item />
      </ul>
    </div>
    `
}).mount('#root')

// 注册组件,{}中放组件的内容
app.component('todo-item',{
    template: `<div>hello world</div>`
})

我们发现页面中报错了:

image.png

原因是,我们在注册组件之前已经使用mount将实例挂载到了页面上,我们应该现在vue实例上注册组件,再将vue实例挂载到页面上

 // 创建Vue的实例
const app = Vue.createApp({
    // 定义数据
    data() {
        return {
            list:[],
            inputValue:"",
        }
    },
    // 定义方法
    methods: {
        handleAddItem() {
            this.list.push(this.inputValue)
            // 清空输入框内容
            this.inputValue = ""
        }
    },
    // 定义页面显示内容
    template: `
        <div>
          <input v-model="inputValue"/>
          <button
           v-on:click="handleAddItem"
           v-bind:title="inputValue"
          >
           增加
           </button>
          <ul>
            <todo-item v-for="(item,index) of list"/>
          </ul>
        </div>
    `
})

// 在vue实例上注册组件,{}中放组件的内容
app.component('todo-item',{
    template: `<div>hello world</div>`
})
// 将vue实例挂在到页面上
app.mount('#root')

父组件传递数据给子组件

组件的结构同vue实例差不多,它也有自己的数据和模板

现在的todoList存在的问题是每次展示的内容都是hello world现在需要展示的是vue实例中的list的每一项item

<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>组件改写todoList</title>
   <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
   <div id="root"></div>
   <script>
       // 创建Vue的实例
       const app = Vue.createApp({
           // 定义数据
           data() {
               return {
                   list:[],
                   inputValue:"",
               }
           },
           // 定义方法
           methods: {
               handleAddItem() {
                   this.list.push(this.inputValue)
                   // 清空输入框内容
                   this.inputValue = ""
               }
           },
           /*父组件通过v-bind绑定属性的方式传值给子组件*/
           template: `
               <div>
                 <input v-model="inputValue"/>
                 <button
                  v-on:click="handleAddItem"
                  v-bind:title="inputValue"
                 >
                  增加
                  </button>
                 <ul>
                   <todo-item
                     v-for="(item,index) of list"
                     v-bind:content="item" 
                     v-bind:index="index"
                   />
                 </ul>
               </div>
           `
       })

       // 子组件通过props接收父组件传递过来的数据
       app.component('todo-item',{
           props:['content','index'],
           template: `<li>{{content}} --- {{index}}</li>`
       })
       // 将vue实例挂在到页面上
       app.mount('#root')
   </script>
</body>

</html>

image.png

父组件传递数据给子组件的方式,在子组件上使用v-bind:xxx绑定属性,子组件中使用props:[xxx]接收父组件传递过来的数据