Introduction to Vue, life cycle, template syntax, conditional rendering, list rendering, style and class binding

Table of contents

Introduction

Vue basic rendering-interpolation and data model

MVVM

life cycle

template syntax

Conditional rendering

v-if

Edit

v-show

List rendering

key

style binding

 class binding


Introduction

Vue is a progressive framework for building user interfaces . Unlike other large frameworks, Vue is designed to be applied layer by layer from the bottom up. Vue's core library only focuses on the view layer, which is not only easy to get started, but also easy to integrate with third-party libraries or existing projects. On the other hand, when combined with a modern tool chain and various supporting libraries, Vue is fully capable of providing drivers for complex single-page applications. Used to make a single page application - index.html, the vue plug-in routing used for page jumps to achieve jumps.

Vue basic rendering-interpolation and data model

//1-Vue基本渲染-插值
//代码
window.onload = function () {
    // 创建vue实例,vue实例要与模板(DOM)绑定
    let vm= new Vue({
        el: "#app",
        data: {// 数据模型
        msg:'hello world'
        },
        // 函数
        methods: {
            changeData(){
                if(this.msg==='hello world'){
                // 更改数据模型中的数据
                // 获取数据模型中的数据
                // 在vue实例内访问vue实例身上的属性和方法
                    this.msg='你好我是修改后的值'
                }else{
                    this.msg='hello world';
                }
            }
        },
    })
}
//html代码
<!-- 以前把msg作为元素文本的,获取dom节点,绑定事件,dom.innerText=msg-->
<div id="app">
<!-- 在模板内访问vue实例中数据模型中的数据 插值 -->
<!-- 基本渲染 插值 -->
{
   
   {msg}}
<p>{
   
   {msg}}</p>
<!-- 点击按钮 改变数据模型中的数据msg变量 -->
<button @click='changeData'>点我修改数据模型msg数据</button>
</div>
//数据模型更改,引发了vm驱动

MVVM

The MVVM pattern, as the name suggests, is the Model-View-ViewModel pattern.

 

Introduction to mvvm: m refers to the business logic operation on the model server, v refers to the view (page), and vm refers to the core hub between the ViewModel model and the view, such as vue.js

You can think of the DOM Listenersand in the above Data Bindingsfigure as two tools, which are the key to achieving two-way binding.

From the View side, the tools in ViewModel DOM Listenerswill help us monitor changes in DOM elements on the page, and if there are changes, change the data in the Model;

From the Model side, when we update the data in the Model, Data Bindingsthe tool will help us update the DOM elements in the page.

//2.数据模型
let vm=new Vue({
    el:'#app',
    data:{
        msg:'高校优质男',
        time:new Date()
    },
    methods:{
        sayName(){
            console.log(this.name)
        },
    }
})
// 每隔一秒重新查询一次时间
setInterval(()=>{
    vm.time=new Date()
},1000)
// 查看vue实例对象
console.log(vm)

life cycle

The entire process from vue instance creation to virtual dom generation to data binding, monitoring, data rendering and destruction

The first step in the life cycle is to create a vue instance and initialize it.
In the vue instance initialization phase,
beforeCreate
    calls beforeCreate during initialization, completing the initialization of the life cycle related properties of the vue instance and the initialization of events. At this time, the data and methods in the data model cannot be accessed.
After created
    is initialized, Vue's data injection and data monitoring operations are completed. The execution of this structure means that the Vue instance is created, and the data data model and methods methods can be accessed. In the vue instance mounting phase beforeMount, after created
,
Vue
    will Determine whether the instance contains the el attribute. If there is no vm.$mount(el), it will then determine whether it contains the template attribute. If it does, it will be parsed into a render function. If it does not parse the external html specified by el. Here only the parsing of the template is completed but the data is not bound to the template.
mounted
    creates vm.$el to replace el. What is actually completed is the data binding operation, during which the render function is executed, the template is parsed, and the data is dynamically bound. The
vue instance update phase
    beforeUpdate
    updates the virtual dom node
    updated
    is completed . The re-rendering of the page     is called before
the vue instance destruction phase
    beforeDestroy is destroyed. At this time, the vue instance     destroyed can be accessed.


    Completed the removal of listeners, subcomponents, event listeners, etc., and destroyed the Vue instance object.

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>
</head>

<body>
    <!-- 模版 视图层 -->
    <div id="app">
        <!-- 采用ref代替id ref表示dom的引用 可以通过ref属性找到dom元素 -->
        <div ref="box">{
   
   {msg}}</div>
    </div>
    <script>
        let vm = new Vue({
            // 使用el属性和模版进行绑定
            el: '#app',
            // 数据模型 存放vue变量
            data: {
                msg: 'hello Vue2'
            },
            // vue实例中提供了template模板 就把template作为模板编译,使用render函数渲染
            // template:`
            //     <h1>{
   
   {msg}}</h1>
            // `,
            methods: {
                // 异步请求 查询所有轮播图 axios
                async findAll() {
                    let res = await axios.get('http://121.199.0.35:8888/index/carousel/findAll');
                    console.log(res);
                }
            },
            /**
             * 生命周期
             * beforeCreate实例初始化之前 初始化默认事件和生命周期
             * created 实例初始化完成    可以访问数据模型data和methods中的方法 是异步请求可以最早
            */
            beforeCreate() {
                console.log('实例初始化之前 初始化默认事件和生命周期', this.msg);
            },
            created() {
                console.log('实例初始化完成 初始化完成响应式数据和methods方法', this.msg);
                // this.findAll();
            },
            /**
             * 实例挂载阶段 与模板绑定阶段
             * beforeMount 实例挂载之前 查看有没有el选项,有的话查看有没有template选项
             *  没有template选项,将el外部的html元素作为模板 此时访问不到dom元素
             * mounted 实例挂载完成 vm创建$el代替el完成模板编译 此时可以访问dom元素 渲染图表 可以发送异步请求
            */
            beforeMount() {
                console.log('实例挂载之前 此时访问不到dom节点', this.$refs.box, '获取ref引用对应的dom元素')
            },
            // 也可以手动提供render函数编译模板 
            // render(createElement) {
            //     return createElement('h2', {}, this.msg1)
            // },
            mounted() {
                console.log('实例挂载完成 此时可以访问dom节点', this.$refs['box'])
            },
            /**
             * 实例更新阶段  只要响应式数据发生更改 生命周期就会被触发
             * beforeUpdate 实例更新前 此时更改了数据,数据是最新,dom中数据还是原始数据,dom还未重新更新
             * updated 实例更新后 此时dom中数据就是最新数据 dom重新被编译到模板中
             * 
             * vue机制 nextTick  异步加载dom  更新dom 数据更改 dom用到该数据不会立马更新 dom更新存放在回调函数中
             * 会在下一次回调函数中完成更新 
            */
            beforeUpdate() {
                console.log('实例更新前', this.$refs.box.innerHTML, this.msg);
            },
            updated() {
                console.log('实例更新完成', this.$refs.box.innerHTML, this.msg);
            },
            /**
             * 实例销毁阶段生命周期 
             * beforeDestroy 实例销毁之前 依旧可以修改vue实例响应式数据
             * destroyed 实例销毁完成 销毁了监听器 子组件 和事件监听 无法修改vue实例响应式数据 不会触发更新阶段生命周期
            */
            beforeDestroy() {
                console.log('实例销毁之前', this.msg);
            },
            destroyed() {
                console.log('实例销毁完成', this.msg);
            }
        });
        setTimeout(() => {
            // 手动销毁实例
            vm.$destroy()
        }, 8000);
        // 如果没有el属性 可以使用$mount和模板进行绑定
        // vm.$mount('#app');
        // setTimeout(()=>{
        //     vm.msg = 'hello world'
        // },1000)
    </script>
</body>

</html>

template syntax

introduce:

Vue uses HTML-based template syntax, allowing developers to declaratively bind the DOM to the data of the underlying Vue instance. All Vue templates are legal HTML, so they can be parsed by browsers and HTML parsers that follow the specification. Under the hood, Vue compiles templates into virtual DOM rendering functions. Combined with the responsive system, Vue can intelligently calculate the minimum number of components that need to be re-rendered and minimize the number of DOM operations. If you are familiar with virtual DOM and prefer the raw power of JavaScript, you can also write rendering functions and render directly without templates, using optional JSX syntax (react uses jsx syntax).

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

</head>
<body>
    <!-- 模版 -->
    <div id="app">
        <!-- 1.Mustache语法 双花括号 文本插值 -->
        {
   
   {msg}}
        
        <!-- 2.使用v-once 进行一次性插值 后续该vue变量改变 执行一次性插值的dom元素不会改变 -->
        <div v-once>{
   
   {msg}}</div>
        
        <!-- 3.使用v-html 识别代码片段 -->
        <!-- {
   
   {content}}  无法将字符串中标签解析 -->
        <div v-html="content"></div>
        
        <!-- 4.1给标签绑定变量 使用v-bind进行绑定 无法使用{
   
   {}} -->
        <!-- <div v-bind:title="title">我是一个块级元素</div> -->
        <!-- 4.2绑定变量 简写为:   -->
        <div :title="title">我是一个块级元素</div>

        <!-- 5.1给标签绑定事件 使用v-on:事件类型 -->
        <!-- <button v-on:click="handler">点击我</button> -->
        <!-- 5.2给标签绑定事件 简写为@ -->
        <button @click="handler">点击我</button>

        <!-- 6.{
   
   {js表达式}} -->
        {
   
   {Boolean(str)}}
        {
   
   {str.split(",").reverse()}}
        {
   
   {str?'string':'null'}}
        <!-- {
   
   {if(str){console.log(str)}else{console.log('null')}}} --> 
    </div>
    <script>
        let vm = new Vue({
            // el:'#app',
            // 数据模型
            data:{
                msg:'hello vue2',
                str:'hello',
                content:'<p>文章标题</p><article>文章内容<a href="#">百度一下</a></article>',
                title:'我div标签的提示说明'
            },
            methods:{
                handler(){
                    console.log('我被点击了');
                }
            },
        });
        // vue实例与模版进行绑定
        vm.$mount('#app');
        setTimeout(()=>{
            vm.msg = 'hello world'
        },1000)
    </script>
</body>
</html>

Conditional rendering

v-if

v-if (can be used alone) , when the expression is true, the element using the v-if attribute is rendered, otherwise it is rendered using v-else

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

</head>
<body>
    <div id="app">
        <!-- 条件渲染 v-if v-else-if v-else 或者使用v-show -->
        <div v-if="type==='tel'">
            <form>
                <label for="tel">电话:</label>
                <input type="text" id="tel" placeholder="请输入电话号码">
            </form>
        </div>
        <div v-else-if="type==='email'">
            <form>
                <label for="email">邮箱:</label>
                <input type="text" id="email" placeholder="请输入邮箱">
            </form>  
        </div>
        <div v-else>错误</div>
        <button @click="toggle">切换</button>

        <div v-show>显示内容</div>
    </div>
    <script>
        new Vue({
            el:'#app',
            data:{
                type:'tel',
                isShow:false,
            },
            methods:{
                toggle(){
                    if(this.type==='tel'){
                        this.type='email'
                    }else{
                        this.type='tel'
                    }
                }
            },
        });
    </script>
</body>
</html>

As can be seen from the results:
v-if is "true" conditional rendering, as it ensures that event listeners and subcomponents within the conditional block are destroyed and recreated appropriately during the switch.
v-if is also lazy: if the condition is false on the initial render, it does nothing; the conditional block won't start rendering until the condition first becomes true.

v-if has higher switching overhead.

v-if corresponds to the addition or deletion of elements/tags

Add elements if conditions are met Delete elements if conditions are not met

v-show

v-show (switch the display attribute in css style), frequently switch css style, use v-show

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

</head>
<body>
    <div id="app">
        <!-- 条件渲染 v-if v-else-if v-else 或者使用v-show -->
        <div v-show="type==='tel'">
            <form>
                <label for="tel">电话:</label>
                <input type="text" id="tel" placeholder="请输入电话号码">
            </form>
        </div>
        <div v-show="type==='email'">
            <form>
                <label for="email">邮箱:</label>
                <input type="text" id="email" placeholder="请输入邮箱">
            </form>  
        </div>
        <button @click="toggle">切换</button>

        <div v-show>显示内容</div>
    </div>
    <script>
        new Vue({
            el:'#app',
            data:{
                type:'tel',
                isShow:false,
            },
            methods:{
                toggle(){
                    if(this.type==='tel'){
                        this.type='email'
                    }else{
                        this.type='tel'
                    }
                }
            },
        });
    </script>
</body>
</html>

 It can be seen from the results:

v-show The element will always be rendered regardless of the initial conditions and is simply toggled based on CSS.

 v-show has higher initial rendering overhead.

v-show corresponds to the display attribute in the CSS style of the element.
        If the condition is met, the element is displayed. display:block.
        If the condition is not met, the element is hidden. display:none.
        v-show is used to frequently switch css styles.

List rendering

Used to render list data. The v-for directive requires special syntax of the form item in items, where items is the source data array and item is an alias for the array element being iterated.

key

Vue will render elements as efficiently as possible, often reusing existing elements rather than rendering them from scratch. Doing this makes Vue very fast. But sometimes, we don't want Vue to reuse. At this time, Vue provides you with a way to express "these two elements are completely independent, do not reuse them." Just add a key with a unique value

<!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>Document</title>
    <!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> -->
    <script src="../vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <!-- <li v-for="(item,index) in animal">
                {
   
   {item}}---{
   
   {message}}---{
   
   {index}}
            </li> -->
            <!-- <li v-for="(item,index) of animal">
                {
   
   {item}}---{
   
   {message}}---{
   
   {index}}
            </li> -->
            <!-- <li v-for="(value,key,index) in obj">
                {
   
   {key}}---{
   
   {value}}---{
   
   {index}}
            </li> -->
            <li v-for="(value,key,index) of obj":key="index">
                {
   
   {key}}---{
   
   {value}}---{
   
   {index}}
            </li>
        </ul>
    </div>
    <script>
        new Vue({
            el:'#app',
            data:{
                message:'消息',
                animal:['猴子','大象','老虎'],
                obj:{
                    name:'terry',
                    age:18,
                    gender:'male'
                }
            },
            methods:{},
        })
    </script>
</body>
</html>

style binding

Manipulating an element's class list and inline styles is a common need for data binding, and since they are attributes, we can use v-bind to handle them: just calculate the string result through the expression. However, string concatenation is cumbersome and error-prone. Therefore, Vue has made special enhancements when using v-bind for classes and styles. In addition to strings, the expression result type can also be an object or an array.

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <style>
        
    </style>
</head>
<body>
    <div id="app">
        <!-- style绑定 动态绑定 -->
        <div :style="{color:current}">{
   
   {msg}}</div>
        <div :style="styleObj1">{
   
   {msg}}</div>
        <div :style="[styleObj1,styleObj2]">{
   
   {msg}}</div>
    </div>
    <script>
        new Vue({
            el:'#app',
            data:{
                msg:"hello Vue2",
                current:'red',
                styleObj1:{
                    fontSize:'24px',
                    backgroundColor:"pink",
                },
                styleObj2:{
                    width:'100px',
                    height:'100px',

                }
            },
            methods:{},
        })
    </script>
</body>
</html>

 class binding

Manipulating an element's class list and inline styles is a common need for data binding, and since they are attributes, we can use v-bind to handle them: just calculate the string result through the expression. However, string concatenation is cumbersome and error-prone. Therefore, Vue has made special enhancements when using v-bind for classes and styles. In addition to strings, the expression result type can also be an object or an array.

<!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>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <style>
        .four{
            border: 1px solid cyan;
        }
        .active{
            color: red;
            font-size: 24px;
        }
        .error{
            background: blue;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 动态绑定类名 -->
        <div class="four" :class="{active:isActive,error:hasError}">{
   
   {msg}}</div>
        <div class="four" :class="toggle">{
   
   {msg}}</div>
        <div class="four" :class="[isActive1,hasError1]">{
   
   {msg}}</div>


    </div>
    <script>
        new Vue({
            el:'#app',
            data:{
                isActive:true,
                hasError:false,
                isActive1:'active',
                hasError1:'error',
                toggle:{
                    active:false,
                    error:true,
                },
                msg:"hello Vue2",
      
            },
            methods:{},
        })
    </script>
</body>
</html>

 [Interview question: Why is data a function rather than an object in large projects]

A component is a reusable instance. When you reference a component, the data in the component is an ordinary object. All users who use this component refer to the same data, which will cause data pollution.

Data that is not wrapped with return will be globally visible in the project and will cause variable contamination;
after wrapping with return, the variables in the data will only take effect in the current component and will not affect other components.
When a component is defined, data must be declared as a function that returns an initial data object, since the component may be used to create multiple instances. If data were still a pure object, all instances would share a reference to the same data object! By providing a data function, we can call the data function every time a new instance is created, thereby returning a completely new copy of the original data object.

Guess you like

Origin blog.csdn.net/qq_53866767/article/details/131836588