欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue基础精讲 —— 详解Vue实例、Vue实例的属性和方法

程序员文章站 2024-03-23 15:28:52
...

Vue实例 —— 基本配置

在 build文件夹 下新建 webpack.config.practice.js 配置文件,内容参考:

const path = require('path')
const HTMLPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const merge = require('webpack-merge') // 合并对象
const baseConfig = require('./webpack.config.base') // 基础配置

const defaultPlugins= [
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: '"development"'
    }
  }),
  new HTMLPlugin()
]

const devServer = {
  port: 8080,
  host: '0.0.0.0',
  overlay: {
    errors: true,
  },
  hot: true
}

let config

config = merge(baseConfig, {
  entry: path.join(__dirname, '../practice/index.js'), // 入口文件
  devtool: '#cheap-module-eval-source-map',
  module:{
    rules:[
      {
        test: /\.styl/,
        use: [
          'vue-style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
            }
          },
          'stylus-loader'
        ]
      }
    ]
  },
  devServer,
  resolve:{
    alias:{
      'vue': path.join(__dirname, '../node_modules/vue/dist/vue.esm.js')
    }
  },
  plugins: defaultPlugins.concat([
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ])
})

module.exports = config

 注意:需要设置 alias 中 vue 指向,这里需要注意不同vue.js 的区别

'vue': path.join(__dirname, '../node_modules/vue/dist/vue.esm.js')

 在 node_modules/vue/dist/ 下有不同的vue.js,若不指定vue.js,项目默认使用的是.vue.runtime.esm.js(vue打包之后的代码),这份vue.js是不支持在Vue对象中使用template的。

Vue基础精讲 —— 详解Vue实例、Vue实例的属性和方法

若不设置alias指向,项目报错如图:

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

Vue基础精讲 —— 详解Vue实例、Vue实例的属性和方法

在package.json文件中新建一条启动命令

"practice": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.practice.js"

 

Vue实例 —— 创建,template创建Vue实例

通过template创建Vue实例,这种方式Vue会将template编译成一个render function,render function返回真正要显示在页面上的HTML代码,效率稍低。
代码示例:

import Vue from 'vue'

const div = document.createElement('div')
document.body.appendChild(div)

new Vue({
  el: div,
  template: '<div>this is content {{text}}</div>',
  data: {
    text: 'text'
  }
})

运行结果:

将template的内容挂载到div元素上,挂载过程是会把整个节点替换掉,因此在网页上看不到#root的元素

Vue基础精讲 —— 详解Vue实例、Vue实例的属性和方法

先定义document节点,再append到body中的方式,相对麻烦

可以注意到先加载了js,再加载真正的页面元素,比较奇怪

在真实的生产环境中,不建议这么操作,建议新建一个template.html文件,类似这样:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

 修改 webpack.config.practice.js 配置文件,生成HTML文件时会根据 template.html为模板生成

const defaultPlugins= [
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: '"development"'
    }
  }),
  new HTMLPlugin({
    template: path.join(__dirname, 'template.html')
  })
]

有了这个template模板文件之后, 修改el值

import Vue from 'vue'

new Vue({
  el: '#root',
  template: '<div>this is content {{text}}</div>',
  data: {
    text: 'text'
  }
})

在新建Vue实例的时候,如若不传el参数,还能通过这种方式挂载

import Vue from 'vue'

const app = new Vue({
  template: '<div>this is content {{text}}</div>',
  data: {
    text: 'text'
  }
})
app.$mount('#root')

Vue实例 —— 创建,render function创建Vue实例

详见,Vue核心分解 —— render function创建Vue组件(实例)

Vue实例 —— 属性

app.$data // 数据
app.$props // 接受参数
app.$el // 挂载点

app.$options
  app.$options.data.text = 'text1' // 不会修改值
  app.$data.text = 'text1' // 可以修改值
  // $options上特殊的属性render
  app.$options.render = (h) => {
    // 需要有值变化,重新进行渲染之后才会生效
    return h('div', {}, 'new render function')
  }

app.$root === app // Vue实例

app.$children // 子组件

app.$slots // 插槽
app.$scopedSlots // 插槽

app.$refs

app.$isServer // 服务端渲染会用到

Vue实例 —— 方法

// 监听
const unWatch = app.$watch('text', (nextText, oldText) => {
  console.log(`${nextText} : ${oldText}`)
})
// 页面之间相互跳转,采用app.$watch方法监听,需手动注销,不然会导致内存溢出
// 手动注销发方法,app.$watch会返回一个unWatch方法,调用该方法即可
unWatch()

// 监听 只监听一次
app.$once('test', () => {
  console.log('test once')
})

// 触发事件
app.$emit('test') 

// 强制组件渲染,不建议使用,若没控制好频度,会一直强制渲染,影响性能
app.$forceUpdate()

// 真正dom节点渲染完成
app.$nextTick() 

// vue是一个响应式框架,若对象中某个值没有在Vue实例创建时声明,则对这个对象赋值时,属于非响应式,不会引起组件渲染
// 在声明Vue实例时,设置data中obj属性为{}空对象,若要对obj中a属性赋值
// 不会引起页面响应
app.obj.a = 1 
// 会引起页面响应
app.obj = {a: 1}
// 会引起页面响应
app.$set(app.obj, 'a', 1) 
// 通过app.$set设置的属性,若要删除,需要通过app.$delete()方法

// vue渲染过程是异步的,每次改一个值,并没有同步渲染到HTML上,而是有一个异步队列
// 若多次改变一个值,vue是一次性渲染出来的,而不是每次都会渲染出来
setInterval(() => {
  app.text += 1
  app.text += 1
}, 1000)
// 在页面上查看text值,会发现它是+2递增,而非+1递增

与君共勉:再牛逼的梦想,也抵不住傻逼般的坚持!